变量赋值和Unity
Variable assignment and Unity
我需要一些帮助来理解 C# 语言的变量赋值。
在使用 Monodevelop for Unity 编写脚本时,我将游戏对象的 RigidBody 和 Collider 组件(以及其他组件)分配给局部变量。当我通过调用它们的方法或更改它们的属性来更改这些变量时,这些更改会反映在原始组件中。为了使我的观点更清楚,我将在下面留下这个伪代码:
void someMethod(Rigidbody rb)
{
Rigidbody localRigidBody;
localRigidBody = rb; //assigned external rb component to local rigidBody
localRigidBody.velocity = 10.0f; //changes are reflected in the original rb object!
}
让我感到困惑的是 "contains" rb Rigibody 组件的游戏对象的变化。虽然我知道这是有效的,但我记得它不应该起作用,因为 localRigidBody 是一个局部变量,改变 localRigidBody 的速度不应该改变 rb 的速度值。然而它改变了,并且它起作用了,因为当我 运行 我的程序时,带有 rb 组件的对象改变了它的速度。你能解释一下为什么吗?
如果我的问题没有得到澄清,请告诉我,我会尽力表达自己。
谢谢。
Unity 通过引用传递 Rigidbody
。如果您想要 Rigidbody
的 copy
或 clone
完全独立于传递给您的方法的原始对象 (rb
),您可以使用 Instantiate
:
void someMethod(Rigidbody rb)
{
Rigidbody localRigidBody = Instantiate<Rigidbody>(rb);
localRigidBody.velocity = 10.0f;
}
否则,正如@RB 所述,您的 localRigidBody
只是原始 rb 变量的 "alias",因为它们都指向同一个对象(内存位置)。
查看此 SO question/answer 以了解经过 "reference" 的内容是:Passing Objects By Reference or Value in C#
更新:
What if I create a simple script where I declare a variable "int a = 10;" and then "int b = a" followed by "b=8". Will "a" change its value? Or is "b" an alias also?
原始数据类型的处理方式略有不同 ;-) 我建议对原始数据类型和引用类型进行一些研究,Microsoft 有一些关于此的很棒的文章...您的示例:
代码:
int a = 10;
Console.WriteLine (a);
int b = a;
Console.WriteLine (b);
b = 8;
Console.WriteLine (a);
Console.WriteLine (b);
输出:
10
10
10
8
Press any key to continue...
您刚刚无意中发现了大多数编程语言的基础 "feature"。
有两种传递变量的方法:
按引用传递
在 C# 中,对象通过引用传递。这意味着每当您将一个已经存在的对象(例如您的 Rigidbody rb
)分配给一个变量(您的 localRigidBody
)时,您是在 而不是 创建一个新对象。相反,您的 localRigidBody
只是对 rb
的引用。如果您想创建 rb
的独立副本,您需要 "clone" 它。
按值传递
int
或 double
等类型按值传递。您将始终获得传递的参数的全新独立副本。
我建议您先阅读 msdn article
我需要一些帮助来理解 C# 语言的变量赋值。
在使用 Monodevelop for Unity 编写脚本时,我将游戏对象的 RigidBody 和 Collider 组件(以及其他组件)分配给局部变量。当我通过调用它们的方法或更改它们的属性来更改这些变量时,这些更改会反映在原始组件中。为了使我的观点更清楚,我将在下面留下这个伪代码:
void someMethod(Rigidbody rb)
{
Rigidbody localRigidBody;
localRigidBody = rb; //assigned external rb component to local rigidBody
localRigidBody.velocity = 10.0f; //changes are reflected in the original rb object!
}
让我感到困惑的是 "contains" rb Rigibody 组件的游戏对象的变化。虽然我知道这是有效的,但我记得它不应该起作用,因为 localRigidBody 是一个局部变量,改变 localRigidBody 的速度不应该改变 rb 的速度值。然而它改变了,并且它起作用了,因为当我 运行 我的程序时,带有 rb 组件的对象改变了它的速度。你能解释一下为什么吗?
如果我的问题没有得到澄清,请告诉我,我会尽力表达自己。
谢谢。
Unity 通过引用传递 Rigidbody
。如果您想要 Rigidbody
的 copy
或 clone
完全独立于传递给您的方法的原始对象 (rb
),您可以使用 Instantiate
:
void someMethod(Rigidbody rb)
{
Rigidbody localRigidBody = Instantiate<Rigidbody>(rb);
localRigidBody.velocity = 10.0f;
}
否则,正如@RB 所述,您的 localRigidBody
只是原始 rb 变量的 "alias",因为它们都指向同一个对象(内存位置)。
查看此 SO question/answer 以了解经过 "reference" 的内容是:Passing Objects By Reference or Value in C#
更新:
What if I create a simple script where I declare a variable "int a = 10;" and then "int b = a" followed by "b=8". Will "a" change its value? Or is "b" an alias also?
原始数据类型的处理方式略有不同 ;-) 我建议对原始数据类型和引用类型进行一些研究,Microsoft 有一些关于此的很棒的文章...您的示例:
代码:
int a = 10;
Console.WriteLine (a);
int b = a;
Console.WriteLine (b);
b = 8;
Console.WriteLine (a);
Console.WriteLine (b);
输出:
10
10
10
8
Press any key to continue...
您刚刚无意中发现了大多数编程语言的基础 "feature"。
有两种传递变量的方法:
按引用传递
在 C# 中,对象通过引用传递。这意味着每当您将一个已经存在的对象(例如您的 Rigidbody rb
)分配给一个变量(您的 localRigidBody
)时,您是在 而不是 创建一个新对象。相反,您的 localRigidBody
只是对 rb
的引用。如果您想创建 rb
的独立副本,您需要 "clone" 它。
按值传递
int
或 double
等类型按值传递。您将始终获得传递的参数的全新独立副本。
我建议您先阅读 msdn article