C# 和 Unity:按值传递引用?
C# & Unity : Pass reference by value?
我是 C# 和 Unity 的新手,在这里我正在调整和创建我的第一个迷你游戏。
问题是:
我有一个小立方体,它会移动。我已经实现了一种在移动之前检查下一个位置的方法。
该方法接收当前立方体位置和方向作为参数:
public bool okToMove(Transform playerCurrentPosition , int directionIndex)
{
Transform playerNextPosition = playerCurrentPosition;
playerNextPosition.Translate(toDirection(directionIndex));
if (playerNextPosition.position.x > 1 ||
playerNextPosition.position.x < -1 ||
playerNextPosition.position.y > 1 ||
playerNextPosition.position.y < -1)
return false;
else
return true;
}
然后,我调用方法
public void movePlayer(int directionIndex)
{
if ( okToMove(gameObject.transform, directionIndex) )
transform.Translate(toDirection(directionIndex));
}
问题是立方体一次移动了 2 步。这是因为
transform.Translate(toDirection(directionIndex));
和
playerNextPosition.Translate(toDirection(directionIndex));
从 okToMove
方法调用。 Unity 或 C# 将 playerNextPosition
视为真正的多维数据集,而不是仅存在于方法内部的某种临时副本。
那么,为什么我的 gameObject.transform
是作为参考而不是按值传递的?我怎样才能让它发挥作用?
提前致谢,抱歉我的笨拙。
创建一个新的 GameObject
,它是您原件的副本,并使用其 transform
进行计算。 (此答案最初来自 Unity forums). The official documentation tells me 您可以使用 Object.Instantiate
创建游戏对象的克隆。
在 C# 中,对象总是将它们的引用作为值传递,所以简单地重新分配是行不通的。看到这个 related question.
C# 中的对象通过引用传递。如果要复制对象,请实现具有方法 Clone() 的 ICloneable 接口。您将需要自己复制该对象,并通过此方法 return 它。
您正在传递对 Transform 的引用,然后在 "okToMove" 中使用翻译移动它,最好的方法是制作 Vector3 的副本,只需像这样更改您的 "okToMove"。
public bool okToMove(Transform playerCurrentPosition , int directionIndex){
Vector3 playerNextPosition = playerCurrentPosition.position;
playerNextPosition += toDirection(directionIndex);
if (playerNextPosition.x > 1 ||
playerNextPosition.x < -1 ||
playerNextPosition..y > 1 ||
playerNextPosition.position.y < -1)
return false;
else
return true;
}
Transform 是附加到每个游戏对象的组件,它包含位置、旋转和缩放的值,因此您的 "playerCurrentPosition" 不是位置的副本,而是对 Transform 的引用(不是副本)。
我是 C# 和 Unity 的新手,在这里我正在调整和创建我的第一个迷你游戏。
问题是:
我有一个小立方体,它会移动。我已经实现了一种在移动之前检查下一个位置的方法。
该方法接收当前立方体位置和方向作为参数:
public bool okToMove(Transform playerCurrentPosition , int directionIndex)
{
Transform playerNextPosition = playerCurrentPosition;
playerNextPosition.Translate(toDirection(directionIndex));
if (playerNextPosition.position.x > 1 ||
playerNextPosition.position.x < -1 ||
playerNextPosition.position.y > 1 ||
playerNextPosition.position.y < -1)
return false;
else
return true;
}
然后,我调用方法
public void movePlayer(int directionIndex)
{
if ( okToMove(gameObject.transform, directionIndex) )
transform.Translate(toDirection(directionIndex));
}
问题是立方体一次移动了 2 步。这是因为
transform.Translate(toDirection(directionIndex));
和
playerNextPosition.Translate(toDirection(directionIndex));
从 okToMove
方法调用。 Unity 或 C# 将 playerNextPosition
视为真正的多维数据集,而不是仅存在于方法内部的某种临时副本。
那么,为什么我的 gameObject.transform
是作为参考而不是按值传递的?我怎样才能让它发挥作用?
提前致谢,抱歉我的笨拙。
创建一个新的 GameObject
,它是您原件的副本,并使用其 transform
进行计算。 (此答案最初来自 Unity forums). The official documentation tells me 您可以使用 Object.Instantiate
创建游戏对象的克隆。
在 C# 中,对象总是将它们的引用作为值传递,所以简单地重新分配是行不通的。看到这个 related question.
C# 中的对象通过引用传递。如果要复制对象,请实现具有方法 Clone() 的 ICloneable 接口。您将需要自己复制该对象,并通过此方法 return 它。
您正在传递对 Transform 的引用,然后在 "okToMove" 中使用翻译移动它,最好的方法是制作 Vector3 的副本,只需像这样更改您的 "okToMove"。
public bool okToMove(Transform playerCurrentPosition , int directionIndex){
Vector3 playerNextPosition = playerCurrentPosition.position;
playerNextPosition += toDirection(directionIndex);
if (playerNextPosition.x > 1 ||
playerNextPosition.x < -1 ||
playerNextPosition..y > 1 ||
playerNextPosition.position.y < -1)
return false;
else
return true;
}
Transform 是附加到每个游戏对象的组件,它包含位置、旋转和缩放的值,因此您的 "playerCurrentPosition" 不是位置的副本,而是对 Transform 的引用(不是副本)。