Reputation: 878
I have my main camera in the scene:
And I have this code that smoothly rotates the camera:
private IEnumerator SmoothlyRotateCamera()
{
float duration = 0.3f;
Quaternion from = transform.rotation;
Quaternion to = from * Vector3.up * 180f;
float elapsed = 0.0f;
while (elapsed < duration)
{
transform.rotation = Quaternion.Slerp(from, to, elapsed / duration);
elapsed += Time.deltaTime;
yield return null;
}
transform.rotation = to;
isRotating = false;
yield return null;
}
Currently, my camera's rotation is [30, -60, 0]
and I want it to rotate around Y axis by 180 degrees.
In theory, to achieve that I need to rotate it for Vector3.up * 180f
, everything sound fine, except the fact, when I rotate it that way, it also rotates all other axes as well.
If I rotate it by new Vector3(180f, 0f, 0f)
- only X axis will be affected.
If I rotate it by new Vector3(0f, 0f, 180f)
- only Z axis will be affected.
And if I rotate it by new Vector3(0f, 180f, 0f)
- all of the axis will rotate as well.
I've checked the rotation by setting my X rotation to 0, so now my camera's rotation is [0, -60, 0]
and if I rotate it the way it intended to be, by Vector3.up * 180f
, then everything works fine! BUT, I need my camera's X to stay in the place. E.g., rotation in the Editor itself only by Y gives me the result that I want.
What should I do? How do I rotate it by 180 degrees by Y axis only?
P.S. I know about transform.Rotate
but in my case I need to rotate it using the way that I have described here.
Thanks!
Upvotes: 0
Views: 10520
Reputation: 90872
Rather use transform.Rotate
private IEnumerator SmoothlyRotateCamera()
{
var duration = 0.3f;
// in angles per second
var rotationSpeed = 180f / duration;
float rotated = 0;
do
{
var angle = Mathf.Min(180.0f - rotated, rotationSpeed * Time.deltaTime);
var rotation = Vector3.up * angle;
rotated += angle;
// depends which Y axis you want to rotate around here
// pass Space.World to rotate around the global Y axis instead of the local one
// if left out it rotates around its transform.up vector instead
transform.Rotate(rotation, Space.World);
yield return null;
} while (rotated < 180f);
isRotating = false;
// your last yield return is redundant
}
I added the Mathf.Min
to make sure there is no overshooting. As you can see it lands exactly on 180° and is smooth in time (you don't need necessarily Lerp
for that only use Time.deltaTime
).
In order to show the effect I only changed the duration to 3
instead of 0.3
(which is to fast to notice it).
Rotating around global Y using transform.Rotate(rotation, Space.World);
Rotating around local Y using transform.Rotate(rotation);
Upvotes: 2
Reputation: 2408
You can try with Euler Angles.
transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y + 180, transform.eulerAngles.);
Your code will become:
private IEnumerator SmoothlyRotateCamera()
{
float duration = 0.3f;
Vector3 from = transform.eulerAngles;
Vector3 to = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y +180, transform.eulerAngles.z);
float elapsed = 0.0f;
while (elapsed < duration)
{
transform.eulerAngles = Vector3.Slerp(from, to, elapsed / duration);
elapsed += Time.deltaTime;
yield return null;
}
transform.eulerAngles = to;
isRotating = false;
yield return null;
}
Upvotes: 1