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.
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!