1

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?

David Tailor
  • 13
  • 1
  • 3
  • Setting a Quaternion manually is folly at best. To my knowledge, Unity's Quaternions are structs and so don't have the migrating-memory overheads that clases do (struct being a value-type meaning when you assign a 'new' one, it just copies the values over instead) – Immersive Nov 05 '20 at 02:05
  • In terms of penalty for creating 'new' Quaternions, the amount of work you'd have to do to recreate the math for generating a Quaternion, IMHO, defeats the puprose. – Immersive Nov 05 '20 at 02:06
  • 1
    Thanks for your comment, sorry for late reply! I'm not calculating the Quaternions, that's what the sensor gave me. I actually had problems converting to Euler, and that's why I switched to Quaternions, because then I just pass values, cannot screw them up. :) The answer I accepted works fine for that purpose. – David Tailor Nov 27 '20 at 00:51

2 Answers2

2

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;
    }
Thomas
  • 1,225
  • 7
  • 16
1

From API: Transform.rotation

Do not attempt to edit/modify rotation.

I suspect this is because the rotation is used purely as a convenience, and the actual transformation matrix is only updated during a function or property-set call. Modifying the rotation directly thus doesn't trigger the matrix update.

You could try modifying the rotation and then calling rotate(0,0,0), but no guarantees this will work as rotation may not be the 'ground-truth', it may not even be stored. It may be generated on request from the matrix.

Immersive
  • 1,684
  • 1
  • 11
  • 9