Search code examples
c#unity-game-enginequaternions

In Unity3D setting the Quaternion of a GameObject directly, without constructing a new object every time


I have a sensor that provides quaternions which I would like to apply to a GameObject.

My currently working code is the following:
transform.rotation = new Quaternion(x, y, z, w);
This works correctly, it modifies the rotation of the GameObject it's attached to, in the way it supposed to rotate it.

However the problem is that constructing a new object every frame seems very wasteful, so I would like to modify the existing one. I've tried the following code:
transform.rotation.Set(x, y, z, w);
This code simply doesn't modify the rotation of the GameObject at all.

Can I modify the Quaternion of the GameObject without constructing a new object every time?


Solution

  • As you can see in the documentation Quaternion is a struct, not a reference type.

    This means:

    • transform.rotation returns a copy of the current rotation of your object. Thus you cannot modify it by calling transform.rotation.Set(x, y, z, w);. You have to use an assignment call.
    • You will not improve performance by caching the rotation in a member field, since the assignement will copy it anyway and your local Quaternion is allocated on the stack.

    If you are afraid of performance (which you shouldn't be just because of the Quaternion construction), I would suggest you cache transform in a member, since Unity's transform member calls this.gameObject.GetComponent<Transform>() every time you use it, which is a rather expensive operation. Though for true optimization we need to know your exact code.

    Example:

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