UnityRef is currently in early development. Some features may be incomplete and/or not functioning.

UNITYREF

Your Pit Stop For Solving ANYTHING in Unity

architecture

[GameObjectTransforms] Stop Child Object Rotation Drift

Solution

transformquaterniongameobjecthierarchy

Unity 2021.x - Unity 6.3.x

Published Thu, Mar 12

Issue

 When attempting to rotate a child GameObject attached to a parent, using gameObject.transform.rotation incorrectly targets the script host instead of the intended weapon or tool. This occurs when your script references its own Transform context, often compounded by variable shadowing where a local identifier obscures the serialized member variable intended for the child.

To rotate a specific child GameObject, its Transform must be explicitly referenced using localRotation to maintain parent-relative orientation.

Explanation

Target the specific child localRotation component for rotation, not the GameObject to which your script is attached.

  1. Declare a [SerializeField] variable for the child GameObject.
  2. Assign the target child object in the Inspector.
  3. Apply the rotation to the localRotation property of your child gameobject to ensure the transformation is relative to the parent.
  4. Ensure that no local variables within your methods share the same name as your serialized field to prevent shadowing the localRotation reference.

Additional Tips

  • Using localRotation prevents the child from inheriting unintended world-space orientation offsets.
  • If the child object needs to return to a neutral state, store the initial localRotation in a Quaternion variable during Awake or Start.

Copy


using UnityEngine;

public class EquipmentManager : MonoBehaviour
{
    public bool isSwordActive;
    public float delayStart = 3f;
    public float delayStop = 5f;

    [Header("References")]
    [SerializeField] private GameObject sword;

    void Update()
    {
        if (Input.GetMouseButtonDown(1) && !isSwordActive)
        {
            Invoke("RotateSwordOn", delayStart);
            Invoke("RotateSwordOff", delayStop);
        }
    }

    void RotateSwordOn()
    {
        Debug.Log("Rotating Child Object");
        isSwordActive = true;
        
        // Accessing the specific child reference avoids rotating the parent script host
        sword.transform.localRotation = Quaternion.Euler(0, 90, 0);
    }

    void RotateSwordOff()
    {
        isSwordActive = false;
        sword.transform.localRotation = Quaternion.identity;
    }
}

Related Posts Haven't quite found a solution to your problem? We think these posts might help you.

Content inspired by a Unity discussion post.