Rotation does not continue out of [-90, 90] degrees

I am following a Unity tutorial and I thought of doing an extra step to test my understanding. The tutorial link: https://learn.unity.com/tutorial/lesson-1-4-use-user-input-to-control-the-vehicle?uv=2022.3&pathwayId=5f7e17e1edbc2a5ec21a20af&missionId=5f71fe63edbc2a00200e9de0&projectId=5caccdfbedbc2a3cef0efe63

I was planning to make 2 scripts for the front wheels to:

  1. Rotate forward/backward
  2. Rotate left/right

based on the player input. The issue is that when I add the 2 scripts together as a components on the wheel game object, the forward rotation does not go beyond [-90, 90] degrees on the x-axis. They both work fine when I disable one and leave the other component.

What is the issue exactly?

The script for rotating forward/backward:

using UnityEngine;

public class ForwardWheelRotation : MonoBehaviour
{
    public float forwardRotationSpeed = 500f; // Speed of the wheel rotation
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        // Get the vertical input
        float verticalInput = Input.GetAxis("Vertical");

        // Rotate the wheel based on the vertical input (forward and backward)
        transform.Rotate(Vector3.right, verticalInput * forwardRotationSpeed * Time.deltaTime);

    }
}

The script for rotating left/right:

using UnityEngine;

public class LRWheelRotation : MonoBehaviour
{
    private float maxRotationAngle = 45f; // Maximum rotation angle in degrees 
    private Transform parentTransform;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void LateUpdate()
    {
        // Get the horizontal input
        float horizontalInput = Input.GetAxis("Horizontal");
        parentTransform = transform.parent;

        // Rotate the wheel based on the horizontal input (left and right)
        // currentRotationAngle = Mathf.Clamp(horizontalInput, -1, 1);
        transform.localRotation = Quaternion.Euler(
            transform.localRotation.eulerAngles.x, 
            horizontalInput*maxRotationAngle, // Because input is [-1, 1] * maxRotationAngle = [-max, max]
            0 // No rotation on the z-axis
                    );        

    }
}


I tried to include a video of the issue but it seems that new users can’t upload attachments.

It’s difficult to debug something like this if you have two or more scripts modifying the same object (wheel). Moreover, rotating an object and then rotating it again is prone to give you surprising results since a sequence of rotations doesn’t necessarily lead to the same result as a single combined rotation.

I bet this is what you ran into here, and the fact that you take the euler angles to modify the rotation. Euler angles have certain limitations and odd behaviour so it’s best to use them only for input or ouput, but never both especially when it’s getting euler, then creating a new Quaternion from euler angles.

You can create two quaternions and add them up quite easily: q1 * q2 = combined rotation
Multiplying quaternions actually means “add” in the common sense.

Combine the two scripts into one that updates the combined wheel rotation in one go. You can then more easily step through the code to see what the values are and how they change.

Thanks for the advice. I gave it a try, but it wasn’t a success for me (Maybe I am not knowledgeable enough about it) I searched online and saw some people create empty parents to simplify these things, and it did work for me.

I attached the LRWheelRotation script to the new empty parent and ForwardWheelRotation to the wheel and everything worked fine.

Interestingly, when I swap the scripts (LRWheelRotation to wheel and ForwardWheelRotation to the new empty parent), the left/right rotation was done with respect to the parent’s local rotation.

using UnityEngine;

public class LRWheelRotation : MonoBehaviour
{
    private float maxRotationAngle = 45f; // Maximum rotation angle in degrees 
    public float forwardRotationSpeed = 500f; // Speed of the wheel rotation
    public float myValue = 0f; // Value to be set in the editor

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void LateUpdate()
    {
        // Get the horizontal input
        float horizontalInput = Input.GetAxis("Horizontal");
        
        // Rotate the wheel based on the horizontal input (left and right)
        float targetYRotation = horizontalInput * maxRotationAngle;
        float currentYRotation = Mathf.LerpAngle(transform.localRotation.eulerAngles.y, targetYRotation, Time.deltaTime * 5f);
        
        // Apply the rotations
        transform.localRotation = Quaternion.Euler(0, currentYRotation, 0);

    }
}

using UnityEngine;

public class ForwardWheelRotation : MonoBehaviour
{
    public float forwardRotationSpeed = 500f; // Speed of the wheel rotation
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        // Get the vertical input
        float verticalInput = Input.GetAxis("Vertical");

        // Rotate the wheel based on the vertical input (forward and backward)
        transform.Rotate(Vector3.right, verticalInput * forwardRotationSpeed * Time.deltaTime);

    }
}