Search code examples
c#unity-game-enginematrixquaternions

Unity: Rotate gizmo with an offset of 45


I am drawing two wireframe spheres that I would like to follow the player around. When the player moves the two gizmos follow, however, when I rotate only one of the gizmos rotates.

The broken gizmo code looks like this, it should have an offset of 45:

void OnDrawGizmosSelected() {
  Gizmos.color = new Color(1, 0, 0);

  Gizmos.matrix = Matrix4x4.TRS(transform.position, Quaternion.Euler(transform.rotation.x, transform.rotation.y + 45, transform.rotation.z), Vector3.one);
  Gizmos.DrawWireSphere(Vector3.zero, 5f);
}

For reference here is the whole block with both gizmos:

void OnDrawGizmosSelected() {
  Gizmos.color = new Color(1, 0, 0);
  // This one works
  Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
  Gizmos.DrawWireSphere(Vector3.zero, 5f);

  // This one does not work
  Gizmos.matrix = Matrix4x4.TRS(transform.position, Quaternion.Euler(transform.rotation.x, transform.rotation.y + 45, transform.rotation.z), Vector3.one);
  Gizmos.DrawWireSphere(Vector3.zero, 5f);
}

Default with no rotation (How I want it to stay when rotating)

Default Rotation

Rotation around the Y Axis

Rotation on Y Axis


Solution

  • Quaternion has 4 components, x,y,z and w.

    Just putting x,y and z into Quaternion.Euler will not give you the expected results.

    Instead, use transform.rotation.eulerAngles

    void OnDrawGizmosSelected()
    {
        Gizmos.color = new Color(1, 0, 0);
        // This one works
        Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
        Gizmos.DrawWireSphere(Vector3.zero, 5f);
    
        // This one works now :)
        Gizmos.matrix = Matrix4x4.TRS(transform.position, Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + 45, transform.rotation.eulerAngles.z), Vector3.one);
        Gizmos.DrawWireSphere(Vector3.zero, 5f);
    }
    

    EDIT:

    Okay, that fixes the Y value, but X and Z are still broken. They move but not in the proper direction.

    Then try

        // This works even better
        Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one) * Matrix4x4.Rotate(Quaternion.Euler(0, 45, 0));