Hello, i am attempting to make a simple script that rotates an object by 45 degrees when the R key is pressed. I already achieved this with transform.rotate, but that does it instantly. I want it to be a bit more gradual, so i came up with the following:
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
//transform.Rotate(new Vector3(0, 0, 45));
oldrotation = transform.rotation;
nextrotation = new Quaternion(transform.rotation.x, transform.rotation.y, transform.rotation.z + 45, transform.rotation.w);
StartCoroutine("RotateCube");
}
}
void RotateCube()
{
Debug.Log(gameObject.name + " is rotating");
Quaternion.RotateTowards(oldrotation, nextrotation, speed * Time.deltaTime);
}
}
it works, i think, because checking the log in the editor shows the message, however, the rotation is not happening. How come?
So, because you are using RotateTowards (and a coroutine) I assume you are trying to get it to smoothly rotate over time, right?
Currently your coroutine only rotates for one frame. That means it will rotate only a tiny amount. You’re almost there! You need to put your current rotation code inside a loop to make it continuously rotate over time. But let’s not jump ahead. Let’s first do the rotation instantly just to make sure we did all of our calculations right:
Try this out first just to make sure the end result is correct:
now my question is how to i rotate it by 45 degrees each time, because as is, it appears that “Quaternion.Euler” always ends up with the same result, even though i put transform.rotation.z + 45
in addition to my question about the 45 degrees each time, i may as well add this, how do i get rid of the slowing down near the end of the lerp of the rotation? once it gets close to the end rotation it slows down quite a lot. I know its because i’m using the current transform position in the lerp, thats just to make sure it works at all. I could have sworn that, at least with lerps of vector3 positions, to fix the slowing down you use both and end point and a start point in the lerp function, however using Quaternion rot = Quaternion.Lerp(oldrotation, nextrotation, speed * Time.deltaTime);
does not rotate the object properly, it appears to hold ALMOST still, though jittering a bit.
The other option is to use Lerp properly. speed * Time.deltaTime is not really the right thing to put into the third parameter of Lerp. What you need is a value that smoothly goes from 0 to 1 over a set period of time. The third parameter is basically a percentage of the rotation from A to B. So if you pass in speed * Time.deltaTime, that’s going to pretty much be the same value every frame, subject to the fluctuation of the device’s framerate. If you insist on using Lerp and you want a linear interpolation you need to do something like this:
IEnumerator RotateCube()
{
Debug.Log(gameObject.name + " is rotating");
var t = 0;
var lerpDuration = 2f; // duration in seconds
while(t < 1)
{
t += Time.deltaTime / lerpDuration;
Quaternion rot = Quaternion.Lerp(oldrotation, nextrotation, t);
transform.rotation = rot;
yield return null;
}
}
Notice that instead of a “speed”, we’re using a “duration”. Lerp is easier to work with using a duration of the animation instead of a speed.
Thank you, i changed it to rotatetowards and that indeed worked. Now i just need to figure out how to get it to rotate 45 degrees from whatever position its at when R is pressed. As is, it only works the first time, Because i think Quaternion.Euler gets the same thing every time even though its transform.position.z + 45
When you multiply quaternions, it’s like applying the two rotations in sequence. So what this says is basically “Give the me the rotation that is my current rotation followed by another 45 degree rotation around the Z axis”.
directionObject = Input.GetAxis("Horizontal");
this.transform.localRotation = Quaternion.Euler(0,maxRotate * directionObject,0);```
This will rotate up to 45-degrees each direction (left-right) and return back to center (0) when no input is applied.