C#&;统一:通过值传递引用?
我对C#和Unity还不熟悉,在这里我调整并创建了我的第一个迷你游戏 问题是:C#&;统一:通过值传递引用?,c#,methods,unity3d,reference,copy,C#,Methods,Unity3d,Reference,Copy,我对C#和Unity还不熟悉,在这里我调整并创建了我的第一个迷你游戏 问题是: 我有一个小立方体,可以移动。我实现了一种方法,在移动前检查下一个位置。 该方法将当前立方体位置和方向作为参数接收: public bool okToMove(Transform playerCurrentPosition , int directionIndex) { Transform playerNextPosition = playerCurrentPosition; playerNextPos
我有一个小立方体,可以移动。我实现了一种方法,在移动前检查下一个位置。 该方法将当前立方体位置和方向作为参数接收:
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;
}
问题是立方体一次移动两次。这是因为
transform.Translate(toDirection(directionIndex));
及
这是从okToMove
方法调用的。Unity或C#将playerNextPosition
视为真实的多维数据集,而不是仅存在于方法内部的某种临时副本
那么为什么我的gameObject.transform
是作为引用而不是通过值传递的呢?我怎样才能让它工作
提前感谢并为我的无知表示歉意。创建一个新的
游戏对象
,它是您原始游戏的副本,并使用它的转换
进行计算。(这个答案最初来自于。您可以使用Object.Instantiate
创建游戏对象克隆的官方文档
在C#中,对象总是将其引用作为值传递,因此简单地重新分配不会这样做。查看此图。创建一个新的
游戏对象
,它是您原始游戏对象的副本,并使用其转换
进行计算。(这个答案最初来自于。您可以使用Object.Instantiate
创建游戏对象克隆的官方文档
在C#中,对象总是将其引用作为值传递,因此简单地重新分配不会这样做。见此。C#中的对象通过引用传递。如果要复制对象,请实现具有方法Clone()的IClonable接口。您需要自己复制对象并从该方法返回它。C#中的对象是通过引用传递的。如果要复制对象,请实现具有方法Clone()的IClonable接口。您将需要自己复制对象并从该方法返回它。您将引用传递给Transform,然后在“okToMove”中使用translate移动它,最好的方法是复制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;
}
public bool-okToMove(转换播放器当前位置,int-directionIndex){
Vector3 playerNextPosition=playerCurrentPosition.position;
playerNextPosition+=toDirection(方向索引);
如果(playerNextPosition.x>1||
playerNextPosition.x<-1||
playerNextPosition..y>1||
playerNextPosition.position.y<-1)
返回false;
其他的
返回true;
}
变换是附加到每个游戏对象的组件,它保存位置、旋转和缩放的值,所以“玩家当前位置”不是位置的副本,而是变换的引用(不是副本)。您将引用传递给变换,然后在“okToMove”中使用平移移动它,最好的方法是复制矢量3,就这样改变你的“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;
}
public bool-okToMove(转换播放器当前位置,int-directionIndex){
Vector3 playerNextPosition=playerCurrentPosition.position;
playerNextPosition+=toDirection(方向索引);
如果(playerNextPosition.x>1||
playerNextPosition.x<-1||
playerNextPosition..y>1||
playerNextPosition.position.y<-1)
返回false;
其他的
返回true;
}
变换是附加到每个游戏对象的组件,它保存位置、旋转和缩放的值,因此“playerCurrentPosition”不是位置的副本,而是对变换的引用(不是副本)。这不是真正优化的方法,您需要实例化游戏对象,然后稍后销毁(这在Unity中是非常昂贵的),我们只关心它的位置,所以只需要将位置复制到新的矢量3就足够了。@NevenIgnjic是一些情况(不是特别的这个)您可能需要整个转换。此外,我没有说它是性能最好的解决方案,并且在提供的链接中已经讨论了该解决方案的性能:“它没有碰撞器、网格渲染器或类似的东西,因此它实际上是一个非常轻量且不可见的对象。”。这使它变得更容易,因为它是轻量级的,但这完全取决于此方法运行的频率,将其位置复制到Vector3是最便宜的解决方案,但在某些情况下,确实需要整个转换(以避免进行Unity已经为我们做过的所有物理和数学)这并不是真正优化的方法,你需要实例化游戏对象,然后再销毁(在Unity中,这是非常昂贵的),我们只关心它的位置,所以只需要将位置复制到新的向量3就足够了。@NevenIgnjic是一些情况(不是特别的这个)您可能需要整个转换。此外,我没有说它是性能最好的解决方案,并且在提供的链接中已经讨论了该解决方案的性能:“它没有碰撞器、网格渲染器或类似的东西,因此它实际上是一个非常轻量且不可见的对象。”。这使它变得更容易,因为它是轻量级的,但这完全取决于此方法运行的频率,将其位置复制到Vector3是最便宜的解决方案,但在某些情况下,确实需要整个转换(以避免进行Unity已经为我们做过的所有物理和数学)引用是按值传递的,而不是按引用传递的。此处的更多信息引用是按值传递的,而不是按引用传递的。此处的更多信息这肯定是更好的方法。我在类似这样的情况下创建一个成员变量,以便在每次调用中使用相同的对象,而不是创建一个新对象,在本例中为Vector3。几率为y你不会注意到对性能的影响,但我认为当你制作游戏时,你真的想让每一行代码都有价值。如果你每一帧都复制并销毁“幽灵”对象,相信我,你会在手机上感受到巨大的影响,fps从3降到3
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;
}