Reputation: 11399
I'm trying to change the eulerAngle X of a camera rotation while keeping y and z at 0.
However, the following IEnumerator results in strange eulerAngles like 10, -74.653, 0.
I don't understand how the y value can change within the following function:
private IEnumerator LerpCameraNormalRot()
{
float duration = 0.5f;
for (float t = 0f; t < duration; t += Time.deltaTime)
{
float f = Mathf.Lerp(camera.transform.eulerAngles.x, 10, t / duration);
Vector3 vNew = new Vector3(f, 0, 0);
camera.transform.eulerAngles = vNew;
yield return 0;
}
}
Isn't this strange? I never change the Y and Z values!
I only want to change the X rotation (eulerAngle.x) from its current value to 10.
Thank you for the help!
Upvotes: 3
Views: 1333
Reputation: 90669
Unity uses two representation of rotation, position, eulerAngles, etc
The values not including local
in their name are in world space.
If your object has than any parents that are rotated/scaled/translated you won't see the values you set in Unity since the Transform
inspector displays the local coordinates.
If you want to set the local
coordinates to the exact values instead use localPosition
, localRotation
or localEulerAngles
instead.
For me it looks like you want to rotate the Camera around its local x
axis by 10° in 0.5 secons.
So I think you could instead do it like
private IEnumerator LerpCameraNormalRot()
{
float duration = 0.5f;
float initialRotationX = camera.transform.localEulerAngles.x;
float targetRotationX = 10;
for (float t = 0f; t < duration; t += Time.deltaTime)
{
float currentX = Mathf.Lerp(initialRotationX, targetRotationX, t / duration);
camera.transform.localEulerAngles = new Vector3(currentX , 0, 0);
// Which would be the same as using
// camera.transform.localRotation = Quaternion.Euler(new Vector3(currentX, 0, 0));
yield return null;
}
// to be sure you have no overshooting you could set the target rotation fix here as well
camera.transform.localEulerAngles = new Vector3(targetRotation, 0 ,0);
// or
// camera.transform.localRotation = Quaternion.Euler(new Vector3(targetRotation, 0, 0));
}
Upvotes: 2
Reputation: 20259
You are setting the eulerAngles
but that will result in different localEulerAngles
which are indicated by the red box in your image. If the object has any ancestors that are rotated, they will probably not match!
To fix your immediate problem, you could use localEulerAngles
instead of eulerAngles
:
float f = Mathf.Lerp(camera.transform.localEulerAngles.x, 10, t / duration);
Vector3 vNew = new Vector3(f, 0, 0);
camera.transform.localEulerAngles= vNew;
The problem with this is that it does not account for the ability to go from 359 degrees around to 0 degrees. Better yet would be to use Quaternion.Euler
and Quaternion.Slerp
to use Quaternions rather than Euler angles:
private IEnumerator LerpCameraNormalRot()
{
float duration = 0.5f;
Quaternion startRotation = camera.transform.localRotation;
Quaternion goalRotation = Quaternion.Euler(10f, 0f, 0f);
for (float t = 0f; t < duration; t += Time.deltaTime)
{
camera.transform.localRotation = Quaternion.Slerp(startRotation, goalRotation, t/duration);
yield return 0;
}
camera.transform.localRotation = goalRotation;
}
Upvotes: 2