C# & Unity : Pass reference by value?

99封情书 提交于 2019-12-14 02:40:16

问题


I'm new to C# and Unity, and here I am tweaking and creating my first minigame.

Here is the problem:
I've got a little cube, that moves. I've implemented a method that checks the next position before making a move. The method receives as parameters the current cube position, and the direction:

 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;
    }

Then, I call the method

public void movePlayer(int directionIndex)
{
    if (  okToMove(gameObject.transform, directionIndex) )
        transform.Translate(toDirection(directionIndex));

}

The problem is that the cube makes 2 moves at once. This is because of

transform.Translate(toDirection(directionIndex));

and

playerNextPosition.Translate(toDirection(directionIndex));

that is called from okToMove method. Unity or C# sees playerNextPosition as the real cube, and not somekind of temporary copy that only exists inside the method.

So why is my gameObject.transform being passed as a reference and not by value? How can I make it work?

Thanks in advance and sorry for my noobiness.


回答1:


You are passing reference to Transform and then moving it with translate in "okToMove", best way is to make a copy of Vector3, just change your "okToMove" like this.

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 is component attached to each gameObject and it holds values for position, rotation and scale, so your "playerCurrentPosition" is not copy of position but rather reference to Transform (not a copy).




回答2:


Create a new GameObject that is a copy of yours original, and use its transform to make your calculations. (This answer is originally from the Unity forums). The official documentation tells me you can use Object.Instantiate to create a clone of a GameObject.

In C#, objects have always their reference passed as value, so simply reassign won't do it. See this related question.




回答3:


Objects in C# are passed by reference. If you want to copy an object, implement the ICloneable interface which has the method Clone(). You will need to copy the object yourself and return it from this method.



来源:https://stackoverflow.com/questions/32172312/c-sharp-unity-pass-reference-by-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!