在Unity3D中直接设置一个GameObject的Quaternion,不用每次都构造一个新对象
In Unity3D setting the Quaternion of a GameObject directly, without constructing a new object every time
我有一个提供四元数的传感器,我想将其应用于游戏对象。
我目前的工作代码如下:
transform.rotation = new Quaternion(x, y, z, w);
这工作正常,它修改了它附加到的游戏对象的旋转,按照它应该旋转的方式。
但是问题是每一帧都构建一个新对象,看起来很浪费,所以我想修改现有的。我试过以下代码:
transform.rotation.Set(x, y, z, w);
此代码根本不修改游戏对象的旋转。
我可以修改GameObject的四元数而不用每次都构造一个新对象吗?
Do not attempt to edit/modify rotation.
我怀疑这是因为 rotation
纯粹是为了方便起见,实际的变换矩阵仅在函数或 property-set 调用期间更新。因此直接修改 rotation
不会触发矩阵更新。
您可以尝试修改旋转然后调用 rotate(0,0,0)
,但不能保证这会起作用,因为 rotation
可能不是 'ground-truth',它甚至可能不会被存储。它可以根据矩阵的要求生成。
正如您在 documentation 中看到的那样 Quaternion
是结构,而不是引用类型。
这意味着:
transform.rotation
returns 对象当前旋转的副本。因此您不能通过调用 transform.rotation.Set(x, y, z, w);
来修改它。您必须使用分配调用。
- 您不会通过在成员字段中缓存旋转来提高性能,因为赋值无论如何都会复制它,并且您的本地四元数分配在 stack。
如果您害怕性能(这不应该只是因为四元数构造),我建议您将 transform
缓存在一个成员中,因为 Unity 的 transform
成员调用 this.gameObject.GetComponent<Transform>()
每次都使用它,这是一个相当昂贵的操作。
尽管为了真正的优化,我们需要知道您的确切代码。
示例:
public class MyClass
{
// to be used instead of Unity's transform member
private Transform myTransform;
private void Awake()
{
// make expensive call only once during Awake
myTransform = transform;
}
我有一个提供四元数的传感器,我想将其应用于游戏对象。
我目前的工作代码如下:
transform.rotation = new Quaternion(x, y, z, w);
这工作正常,它修改了它附加到的游戏对象的旋转,按照它应该旋转的方式。
但是问题是每一帧都构建一个新对象,看起来很浪费,所以我想修改现有的。我试过以下代码:
transform.rotation.Set(x, y, z, w);
此代码根本不修改游戏对象的旋转。
我可以修改GameObject的四元数而不用每次都构造一个新对象吗?
Do not attempt to edit/modify rotation.
我怀疑这是因为 rotation
纯粹是为了方便起见,实际的变换矩阵仅在函数或 property-set 调用期间更新。因此直接修改 rotation
不会触发矩阵更新。
您可以尝试修改旋转然后调用 rotate(0,0,0)
,但不能保证这会起作用,因为 rotation
可能不是 'ground-truth',它甚至可能不会被存储。它可以根据矩阵的要求生成。
正如您在 documentation 中看到的那样 Quaternion
是结构,而不是引用类型。
这意味着:
transform.rotation
returns 对象当前旋转的副本。因此您不能通过调用transform.rotation.Set(x, y, z, w);
来修改它。您必须使用分配调用。- 您不会通过在成员字段中缓存旋转来提高性能,因为赋值无论如何都会复制它,并且您的本地四元数分配在 stack。
如果您害怕性能(这不应该只是因为四元数构造),我建议您将 transform
缓存在一个成员中,因为 Unity 的 transform
成员调用 this.gameObject.GetComponent<Transform>()
每次都使用它,这是一个相当昂贵的操作。
尽管为了真正的优化,我们需要知道您的确切代码。
示例:
public class MyClass
{
// to be used instead of Unity's transform member
private Transform myTransform;
private void Awake()
{
// make expensive call only once during Awake
myTransform = transform;
}