如何通过脚本在 Unity 中重新定位和调整游戏对象的大小?
Posted
技术标签:
【中文标题】如何通过脚本在 Unity 中重新定位和调整游戏对象的大小?【英文标题】:How do I reposition and resize gameObjects in Unity via scripting? 【发布时间】:2021-09-27 10:36:38 【问题描述】:所以我试图在 Unity 中构建一个类似于 Snakes and Ladders 游戏的游戏,但是当多个玩家令牌落在同一个方格上时,我发现很难处理。
我的场景中有以下游戏对象:
单击 Player1 按钮后,其中一个玩家标记(圆柱形游戏对象)前进到第一个方格(骰子被硬编码为每次掷 1 以进行测试),如下所示:
现在,当单击 Player2 按钮时,另一个玩家令牌应该会前进到第一个方格,但是它会与第一个玩家令牌重叠,看起来现在场景中只有一个玩家令牌,如下所示:
我正在尝试找到一种方法来调整两个标记的大小和位置,以便它们之间有足够的空间并且它们仍然保持在同一个正方形上。
此外,一旦玩家令牌离开方格并前进到另一个方格,我需要根据每个方格上是否存在其他玩家令牌(当然,如果超过 2 名玩家)来调整两个方格上的玩家令牌的大小,或者不是
我在单击按钮时调用的方法中尝试了以下方法:
public void MovePlayerToken(GameObject currentPlayer)
var startingSquare = currentPlayer.GetComponent<PlayerToken>().StartingSquare;
var landingSquare = GetLandingSquare(startingSquare);
var existingPlayerTokensOnLandingSquare = GetExistingPlayerTokens(playerTokens, landingSquare);
//var existingPlayerTokensOnStartingSquare = GetExistingPlayerTokens(playerTokens, startingSquare);
if (existingPlayerTokensOnLandingSquare.Count > 0)
TransformPlayerTokens(existingPlayerTokensOnLandingSquare, landingSquare, SquareType.LandingSquare);
if (currentPlayer.transform.localScale == new Vector3(1, 1, 1))
currentPlayer.transform.localScale = new Vector3(currentPlayer.transform.localScale.x / 2,
currentPlayer.transform.localScale.y / 2,
currentPlayer.transform.localScale.z / 2);
switch (existingPlayerTokensOnLandingSquare.Count)
case 1:
existingPlayerTokensOnLandingSquare[0].transform.position = new Vector3(landingSquare.transform.localPosition.x + 0.25f, landingSquare.transform.localPosition.y, landingSquare.transform.localPosition.z + 0.25f);
currentPlayer.transform.position = new Vector3(landingSquare.transform.localPosition.x + -0.25f, landingSquare.transform.localPosition.y, landingSquare.transform.localPosition.z + -0.25f);
break;
case 2:
existingPlayerTokensOnLandingSquare[0].transform.position = new Vector3(landingSquare.transform.localPosition.x + 0.25f, landingSquare.transform.localPosition.y, landingSquare.transform.localPosition.z + 0.25f);
existingPlayerTokensOnLandingSquare[1].transform.position = new Vector3(landingSquare.transform.localPosition.x + -0.25f, landingSquare.transform.localPosition.y, landingSquare.transform.localPosition.z + -0.25f);
currentPlayer.transform.position = landingSquare.transform.position;
break;
else
currentPlayer.transform.position = landingSquare.transform.position;
currentPlayer.GetComponent<PlayerToken>().StartingSquare = landingSquare;
private Square GetLandingSquare(Square startingSquare)
Square landingSquare = startingSquare;
for (int i = 0; i < _stateManager.DiceTotal; i++)
if (landingSquare.NextSquares.Length > 1)
landingSquare = landingSquare.NextSquares[Random.Range(0, landingSquare.NextSquares.Length)];
else
landingSquare = landingSquare.NextSquares[0];
return landingSquare;
private List<PlayerToken> GetExistingPlayerTokens(PlayerToken[] playerTokens, Square square)
List<PlayerToken> existingPlayerTokens = new List<PlayerToken>();
foreach (var playerToken in playerTokens)
if (playerToken.transform.position == square.transform.position ||
playerToken.transform.position == new Vector3(square.transform.localPosition.x + 0.25f, square.transform.localPosition.y, square.transform.localPosition.z + 0.25f) ||
playerToken.transform.position == new Vector3(square.transform.localPosition.x + -0.25f, square.transform.localPosition.y, square.transform.localPosition.z + -0.25f))
existingPlayerTokens.Add(playerToken);
return existingPlayerTokens;
private void TransformPlayerTokens(List<PlayerToken> existingPlayerTokens, Square landingSquare, SquareType squareType)
foreach (var playerToken in existingPlayerTokens)
if(playerToken.transform.localScale == new Vector3(1, 1, 1))
playerToken.transform.localScale = new Vector3(
playerToken.transform.localScale.x / 2,
playerToken.transform.localScale.y / 2,
playerToken.transform.localScale.z / 2
);
这种方法的问题在于,玩家代币越多,需要的硬编码就越多……我真的不喜欢这种方法,我相信有更好的方法可以使用物理引擎或一些东西(顺便说一句,我是一个完整的新手,以前从未使用过 Unity - 这是我的第一个项目,所以请期待我对物理引擎知之甚少)
谢谢。
【问题讨论】:
不确定这是否适用于物理(尤其是所需的收缩部分)。但可以肯定的是,您可以创建一种算法,将它们放在正方形内的网格上。 1x1 网格上的 1 名球员,2x2 网格上的 2-4 名球员,3x3 上的 5-9 名球员,依此类推。这种方式没有硬编码,单个算法可以解决所有数量的玩家。 @PmDuda 谢谢.. 我会统一研究网格! 【参考方案1】:您可以使用 GameObject.transform.position =(此处为新位置)重新定位。
【讨论】:
如果你真的阅读了这个问题,你会意识到 OP 已经知道这一点,而这不是问题所在。【参考方案2】:对于调整大小,您可以这样做
var players = existingPlayerTokensOnLandingSquare.Count + 1;
currentPlayer.transform.localScale = new Vector3(currentPlayer.transform.localScale.x / players,
currentPlayer.transform.localScale.y / players,
currentPlayer.transform.localScale.z / players);
不知道重新定位,或者现在无法考虑。希望其他人可以回答这个问题。
【讨论】:
定位可以用物理学来完成。在它们上面放置对撞机和刚体,然后在正方形区域周围建造墙壁,或者如果它们离开该区域,则使用脚本将它们移回,无论我猜哪个可行。太大了,我在这里回答,希望你能弄清楚。 或者你可以把它们放在一个网格中,就像我刚刚注意到的其他评论一样。 我确实给了我的方格刚体,并且当玩家令牌前进到方格时,我在掷骰子时能够在 onTriggerEnter 方法中获取当前玩家令牌对象,但不知道如何以识别特定方格上是否存在其他玩家棋子。以上是关于如何通过脚本在 Unity 中重新定位和调整游戏对象的大小?的主要内容,如果未能解决你的问题,请参考以下文章