- Home /
Quaternion, eulerAngles, localEulerAngles Driving me mad
Hi,
I have a reload animation that i want to Slerp slightly, I've tried using Quaternion because I thought it alway taken the shortest route?
I have 2 Quaternion, 1 (3,964, -176.115, 0, 0) and (0,-176.115, 0, 0) but when using Slerp it goes the long way around.
I've tried eulerAngles and localEulerAngles and seem to get the same results.
Here is a snippet of my code.
Any help would be greatly appreciated ..
var _reloadRotation : Quaternion;
private var _transformsRotation : Quaternion;
private var j : float;
function reloadLerpPosition ()
{
_transformsRotation = transform.rotation;
j = 0;
while(j < 1)
{
j += Time.deltaTime/0.6;
j = Mathf.Clamp(j, 0, 1);
transform.rotation = Quaternion.Slerp(_transformsRotation, _reloadRotation, j);
yield;
}
}
Slerp works fine, what most worries me is where you say you have two quaternion '(3,964, -176.115, 0, 0) and (0,-176.115, 0, 0)', the components of a quaternion should be clamped between -1 and 1 I believe. are you setting the x,y,z components of the quaternion yourself somewhere? it is quite likely that (1, -1, 0, 0) lerping to (0, -1, 0, 0) will go quite a distance.
@Scribe Hi, the (3,964, -176.115, 0, 0) is the position of the animated arms and weapon, that never changes because it's child of another Transform, and (0,-176.115, 0, 0) is the target rotation I'm trying to achieve ..
So you are happy that you are rotating towards an EULERIAN angle of (0, 180, 0), which is the equivalent to a QUATERNION of (0,-176.115, 0, 0). On top of this, the objects are at the 5 dimensional position (3,964, -176.115, 0, 0)?
Here's a good little post
Answer by Outliver · Apr 29, 2016 at 08:32 AM
That's because rotation is presented in Quaternions which cannot be converted into euler angles with 100% precision. The problem occurs when you cross the 0 point on the x axis (afair). Try using Rotate() or RotateAround(). It's generally a good advice to avoid manipulating Quaternions directly. If that doesn't work: where, how and by what is your method being called?
@Outliver Thanks for the input,
First it's being called in what I call the AnimationCtrlWeapon script, when the player runs out of ammo a reload function is called, then in that I first call the reloadLerpPosition function and when thats finished it calls the reload animation.
I've also tried ..
var reloadRotation : Vector3;
private var localRotationX : float;
private var localRotationY : float;
private var localRotationZ : float;
function reloadLerpPosition ()
{
localRotationX = transform.localEulerAngles.x;
localRotationY = transform.localEulerAngles.y;
localRotationZ = transform.localEulerAngles.z;
j = 0;
while(j < 1)
{
j += Time.deltaTime/0.6;
j = $$anonymous$$athf.Clamp(j, 0, 1);
transform.localEulerAngles.x = $$anonymous$$athf.Lerp(localRotationX, reloadRotation.x, j);
transform.localEulerAngles.y = $$anonymous$$athf.Lerp(localRotationY, reloadRotation.y, j);
transform.localEulerAngles.z = $$anonymous$$athf.Lerp(localRotationZ, reloadRotation.z, j);
yield;
}
}
And I still can't get it right :(
First of all, I'm still not quite sure what you're trying to achieve exactly. Do you really want to lerp in every direction? Why "while (j < 1)" if you $$anonymous$$athf.Clamp() anyway? That's an infinite loop. And why is your reloadRotation a Vector3, not a Quaternion?
Again: do not set quaternions or euler angles manually. Have you tried something like this already? transform.Rotate( reloadRotation * j ); (untested pseudo code)
If that doesn't work, maybe you'll need to make sure, the rotation is never more than 180° away. Like so:
reloadRotation.x = reloadRotation.x > 180 ? reloadRotation.x - 360 : reloadRotation.x;
...and so on (again, just pseudo-code).
I thought this would be simple, just to Slerp from (3,964, -176.115, 0, 0) to (0,-176.115, 0, 0)
Or Lerp from (3,964, -176.115, 0) to (0,-176.115, 0) in the shortest distance ..