Quaternion.Lerp is setting object's rotation to 0, 0, -180

Hello!

So I’ve used Quaternion.Lerp before, but now I’m running into this strange issue. I’m using code directly from the docs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CatapultController : MonoBehaviour {
    public Quaternion StartRotation;
    public Quaternion EndRotation;
    public float RotateSpeed;
   
    // Update is called once per frame
    void Update ()
    {
        transform.rotation = Quaternion.Lerp(StartRotation, EndRotation, Time.time * RotateSpeed);
    }
}

However when I hit play the object’s rotation instantly switches to 0, 0, -180 and doesn’t move at all. Is there anything I forgot to do? This is so strange because I’ve used it before in much more complicated scripts.

Thank you!

Lerp’s 3rd parameter is supposed to be a value from 0->1, Unity clamps this value as well (so values > 1 will just be 1). You have to actually call the LerpUnclamped to get an unclamped lerp:

Anyways… Time.time is a value that after 1 second of gameplay is > 1, (faster so depending on what RotateSpeed is), so you’re basically setting the value to the ‘EndRotation’ almost immediately.

Strange that the docs show code that doesn’t work. Anyways, I fixed it to this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CatapultController : MonoBehaviour {
    //By the way I have all variables public so I can see them in the Inspector, later I'll hide some by making them private.
    public Transform CatapultArm;
    public Quaternion StartRotation;
    public Quaternion EndRotation;
    public float CurrentTime;
    public float TotalTime;
    public float RotateSpeed;
    public float QuaternionThirdParameter;
    // Use this for initialization
    void Start ()
    {
        SetupRotation();
    }
  
    // Update is called once per frame
    void FixedUpdate ()
    {
        CurrentTime += Time.fixedDeltaTime;
        QuaternionThirdParameter = CurrentTime / TotalTime;
        CatapultArm.rotation = Quaternion.Lerp(EndRotation, StartRotation, QuaternionThirdParameter);
    }

    void SetupRotation()
    {
        float AmountToTurn = StartRotation.z - EndRotation.z;
        TotalTime = AmountToTurn / RotateSpeed;
        Debug.Log("Turning this many degrees: " + AmountToTurn + " starting with " + (CurrentTime / TotalTime));
    }
}

Yet the result is exactly the same, and the third parameter takes many seconds to reach 1.

After some thinking, I found this to be the easiest solution:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CatapultController : MonoBehaviour {
    public Transform CatapultArm;
    public float StartZRotation;
    public float EndZRotation;
    public float RotateSpeed;
    public bool Flinging;
    public bool Retracting;
    // Use this for initialization
    void Start ()
    {
        SetupRotation();
    }
  
    // Update is called once per frame
    void Update ()
    {
        if (Flinging)
        {
            if (CatapultArm.eulerAngles.z > EndZRotation)
                CatapultArm.eulerAngles = new Vector3(CatapultArm.eulerAngles.x, CatapultArm.eulerAngles.y, CatapultArm.eulerAngles.z - (RotateSpeed * Time.deltaTime));
            else
            {
                Flinging = false;
                Debug.Log("Finished flinging");
            }
        }

        if (Retracting)
        {
            if (CatapultArm.eulerAngles.z < StartZRotation)
                CatapultArm.eulerAngles = new Vector3(CatapultArm.eulerAngles.x, CatapultArm.eulerAngles.y, CatapultArm.eulerAngles.z + (RotateSpeed * Time.deltaTime));
            else
            {
                Retracting = false;
                Debug.Log("Finished flinging");
            }
        }
    }

    void SetupRotation()
    {
        StartZRotation = CatapultArm.localEulerAngles.z;
    }
}

Not sure if it’s better or worse than Quaternion.Lerp, but at least it works and I can manage directions!