Help with Vector3.Lerp/Slerp for eulerAngles?

I’m trying to have an object Lerp/Slerp from one Vector3 point to another but for some reason the Lerping is not exactly going to the second Vectors position. If this isnt the best way to do something like this? Then what would be?

I tried doing a Quaternion with transform.rotation but that doesnt seem to do what I am looking for.

The above method of Vectors rotates in the way I like, I’m just not seeing the results I am looking for.

Thank you.

//JS
function LerpTimed(firstVector : Vector3, secondVector : Vector3, time : float, totalTime : float)
{
return Vector3.Lerp(firstVector, secondVector, time / totalTime);
}

//C#
public Vector3 LerpTimed(Vector3 firstVector, Vector3 secondVector, float time, float totalTime)
{
return Vector3.Lerp(firstVector, secondVector, time / totalTime);
}

These lerp between two vectors based on an amount of time, so if time is in seconds, and you have a totalTime from the first vector to the second, that’s what it’ll go to.

I’m not sure if this is what you wanted, your problem wasn’t very clear. Hope this helps.

~
Another walk in the park.

Thanks, sorry thats not it. I’ve been doing that but the values I’m expecting are not the values that are being shown.

Could you explain what exactly you are trying to achieve. Do you want to move from A to B? Do you want to go from one rotation to another? Do you want both?

I want both, but I already have the translation working properly. I am trying to get one rotation to another. So if I’m currently at Rotation : 270, 0, 0 then I would like to get to Rotation : 225, 0, 0 … But When I try Lerping to that Rotation, it ends up with like Rotation : 315, 180, 180

Doesn’t even make any sense

Euler angles in are only a conversion from the actual Quaternion rotation objects internally have in Unity.
You will never be able to control the euler angles of an objects rotation yourself, not unless you store the euler rotation yourself.
Long story short, if you want to interpolate between two transform rotations, use Quaternion.Slerp.
Take a look at the Quaternion video.
http://unity3d.com/learn/tutorials/modules/intermediate/scripting/quaternions

pseudo code:

Vector3 curRot = transform.rotation.eulerAngles;
curRot = Vector3.Lerp(curRot, targetRot, time);
transform.rotation = Quaternion.Euler(curRot);

does this help?

~
Another walk in the park.

Show your code!

I’ll check the Quaternion video out but I have already tried using Quaternions and couldn’t get it working. I was thinking of posting my code but got to figure out which code to include.

Thanks for the replies

That sounds like you should refactor your code first :slight_smile:

EDIT: You’re lerping on one dimension, so a normal Vector lerp should work just fine. I think you will need to show the lerp code before we can help you! There may be no need to mess with Quaternions yet.

====

ORIGINAL POST: When working with angles/rotations, it is best to convert everything to Quaternions.

void Start()
{
  Quaternion originalRotation = transform.rotation
  Quaternion targetRotation = Quaternion.Euler(yourTargetEulerAngles);
}

void Update()
{
  float t = percentComplete;
  transform.rotation = Quaternion.Lerp(originalRotation, targetRotation, t);
}

There is also RotateTowards.transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, speedInDegrees * Time.deltaTime);Rotating around x then rotating around y gives different results than rotating around y then rotating around x. This is a source of gimbal lock and the reason why euler angles can be deceptive to work with.

2 Likes

Hmm actually that code might work. I’ll give it a try next. That seems like it may do the trick!

@GarthSmith … Unfortunately that code worked just as my code originally worked… So that’s not good. But thanks anyways

So I figured something out.

A rotation of (225, 0, 0) is the same thing as a rotation of (315, 180, 180). So you are lerping to the correct rotation.

I’m guessing that means your rotation is around the wrong axis. I would like to ask for two things.

  • How is the rotation different from what you expect? How does it act now? What should it act like?
  • Can you provide the code you are using to rotate?

Well yes, that first statement is correct. It is working, but I am trying to check the current rotation with the rotation that I want to Lerp until if they are equal and then let the game now when that happens.
But because (225,0,0) rotates to (315,180,180) the current rotation will never equal (225,0,0) and then never send the signal.

There’s no point to post my code because its just the few lines that keep getting passed around on this thread. But what I said above in this reply should allow a better understanding.

Thank you

How about checking if the angle between them is almost 0?

if (Quaternion.Angle(originalRotation, targetRotation) < 0.01f) Debug.Log("Close enough!");

bool rotationAchieved = Vector3.Dot(curRot.eulerAngles.normalized, lerpRot.eulerAngles.normalized) == 1.0f;
Dot product of two vectors will be 1.0f if they’re the same, or -1.0f if they’re completely opposite direction of each other, 0.0f if they are perpendicular(90 degrees of eachother).

Emma, I don’t think that comparing the Euler angles that way is reliable, because the same rotation might convert to quite different Euler angles. Using Quaternion.Angle as Thermal suggested seems like a safer bet to me.

(But I’d be happy to be wrong on this one, and learn something new!)

@JoeStrout @TwixEmma The euler angles actually come out the same. The y and z components are off by about 0.00001. The problem is coming from expecting two floats to perfectly equal each other.

@d34thst4lker You should never compare 2 floats directly. Instead, you need to compare if two floats are close enough together. The reason for this is because floats use a base 2 numbering system, and so most numbers cannot be represented exactly in a float. Example: A float can never have the value 0.1 exactly. You can try some numbers at this site and see almost none of them are exact in a float.
http://www.h-schmidt.net/FloatConverter/IEEE754.html

This means you should do something similar to @ThermalFusion . Figure out what error is acceptable and check against that error.

Yea sounds good! Will try that soon
Thanks!