- Home /
How do you check if Quaternion.Slerp has finished
This is my first question here. I'm a beginner programmer, just been thrown into it at work. Im actually just a 3D modeller, but anyway.
I've got a situation where I have set up a camera with a look at script that moves and changes depending on which object the user presses. Works fine but now i have been asked to make it so you can look around once from that camera point. This is what i have tried, script is applied to the camera.
rotation = Quaternion.LookRotation(lookAt.transform.position - transform.position);
if(lookAtOn==true){
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
}
if(transform.rotation==rotation){
lookAtOn=false; tVCamCentred=true;
} else{
tVCamCentred=false;
}
Then i just have pretty much on click on the screen to reset the camera, lookAtOn=true
This works perfect when it wants to. every so often it just gets stuck with lookAtOn=true and won't turn off, have to close the app and restart.
I just formatted your code. You can do this by highlighting all your code, then clicking the 10101 button at the top of the edit window =]
Answer by Bunny83 · Sep 27, 2012 at 10:23 PM
It will never finish because you use Slerp as a "divide-remaining-distance" smoothing function. Slerp is usually ment to linearly interpolate a rotation froma constant start rotation to a constant target rotation. The t-parameter has to be moved from 0 to 1. 0 means start rotation 1 means end rotation a value in between will return the respective linear interpolated rotation. Since your t value never reaches 1.0 you will never reach the end. The difference between your current / start rotation and the target rotation will get incredible small, but you will not reach the end.
You can check the Angle between your current rotation and your target rotation and if it's smaller than for example 1° you can treat it as finished.
Answer by svitlana · Feb 20, 2016 at 06:29 AM
float diff = player.transform.rotation.eulerAngles.y - targetRotation.eulerAngles.y; float dergee = 1; if (Mathf.Abs (diff) <= dergee) { Debug.Log("ready"); }
Answer by Toadill9114 · Aug 29, 2018 at 08:02 AM
It would be like this.
public void RotateTowards()
{
float strength = 1f;
float str;
Vector3 direction = (transform.position - playerAgentBase.transform.position).normalized;
direction.y = 0;
str = Mathf.Min(strength * Time.deltaTime, 1);
Quaternion lookRotation = Quaternion.LookRotation(direction);
playerAgentBase.gameObject.transform.rotation = Quaternion.Slerp(playerAgentBase.gameObject.transform.rotation, lookRotation, str);
float angle = Quaternion.Angle(playerAgentBase.gameObject.transform.rotation, transform.rotation);
if (angle >=179f)
{
rotate = false;
}
}
void Update()
{
if (rotate)
{
RotateTowards();
}
}
Answer by usernameHed · Nov 06, 2018 at 05:32 PM
For checking an angle diff, in degree, I have this function:
public static bool IsAngleCloseToOtherByAmount(float angleReference, float angleToTest, float differenceAngle)
{
if (angleReference < 0 || angleReference > 360 ||
angleToTest < 0 || angleToTest > 360)
{
Debug.LogError("angle non valide: " + angleReference + ", " + angleToTest);
}
float diff = 180 - Mathf.Abs(Mathf.Abs(angleReference - angleToTest) - 180);
//diff = Mathf.Abs(angleReference - angleToTest);
if (diff <= differenceAngle)
return (true);
return (false);
}
Then For checking the ending of an Quaternion.slerp, this function:
/// <summary>
/// Is a Quaternion.Slerp is over ?
/// </summary>
public static bool IsQuaternionSlerpOver(Quaternion objectInRotation, Quaternion targetRotation, float marginInDegree = 1)
{
if (!IsAngleCloseToOtherByAmount(objectInRotation.x, targetRotation.x, marginInDegree))
return (false);
if (!IsAngleCloseToOtherByAmount(objectInRotation.y, targetRotation.y, marginInDegree))
return (false);
if (!IsAngleCloseToOtherByAmount(objectInRotation.z, targetRotation.z, marginInDegree))
return (false);
return (true);
}
Answer by JahnStar · Jun 03, 2020 at 06:29 PM
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
if (Quaternion.LookRotation(lookAt.transform.position - transform.position) == transform.rotation)
{
// write your code here
}