- Home /
How do I make something rotate until a condition is met
I want to make a game object rotate until its Z axis it's pointing towards a specific point. I have a variable named angle which is the angle between the object's Z axis and the position of the point which it needs to point to. I have the following code right now:
while (angle > 0)
{
transform.Rotate (Vector3.right * rotationSpeed * Time.deltaTime);
transform.Rotate (Vector3.up * rotationSpeed * Time.deltaTime);
}
but it always ends up in an infinite loop and crashing because it just rotates by the amount I'm telling it to. So is there any way to tell the object to keep rotating until the angle is 0?
Where do you set the value of angle, because it is not being increased or decreased in the loop. Could that be the cause of the issue?
I think I found that the problem is that the way the object rotates makes it impossible for the angle to ever close, so yeah, you're right about that. I still have no idea how to solve my problem, my intuition would be to define two angles: one equal to the angle between the z vector of the game object I'm trying to rotate and the transform.position.x of the target, and another angle but with the y component of the target, I don't know if I'm being clear enough... Anyway then I'd have to set up two while loops, one for each angle, that way each one will have to equal zero at some point and exit the loop, but I have no idea how to do it yet.
Could you work out the movement before the loop, eg
float xRot = targetAngleX - currentAngleX;
float yRot = targetAngleY - currentAngleY;
and then work out the speed for each axis. After that you could then go into a loop and add the necessary speed to each one?
That sounds about right. However, and I hope this isn't much trouble, could you elaborate a little more, please? I'm new to unity and C# I'm not entirerely sure about some of the concepts. I'm guessing xRot and yRot would store a value for an angle wich I would then turn into a rotation by using
transform.Rotate(Vector3.up * xRot);
transform.Rotate(Vector3.right * yRot);
but, I'm not sure about how to retrieve the values of targetAngle and currentAngle. What I did in my original code to get the angle was this:
float angle = Vector3.Angle(transform.forward, CameraOp.moveToDest)
In that context transform.forward was the angle of the thing I was trying to rotate and CameraOp.moveToDest a position value retrieved from a raycast hit. what I'm trying to do is to make the object point at CameraOp.moveToDest without using LookAt
Answer by Superrodan · Feb 05, 2015 at 09:45 PM
If the point you want to point towards is a rotation vector you can use RotateTowards, I believe.
Quaternion myQuat = Quaternion.Euler(transform.localEulerAngles);
Quaternion targetQuat = Quaternion.Euler(YOURTARGETVECTOR);
while(myQuat!=targetQuat)
{
transform.localRotation = Quaternion.RotateTowards(myQuat, targetQuat, 10.0f);
myQuat = Quaternion.Euler(transform.localEulerAngles)
}
This is for local rotation. For world rotation remove the local so it's just EulerAngles I believe.
This is all untested and more of a guess based on how I would try to approach the problem.
thanks four your answer! but sadly no... the point is just a static Vector3. It's the transform.position of another game object, I haven't got into Quaternions yet
Try this in the above code, and it still might work:
Quaternion targetQuat = Quaternion.LookRotation(YOURTARGETVECTOR);
Actually looking at the above comment thread going on it seems I might be close but not entirely there with my usage of LookRotation. I think this is closer:
Quaternion myQuat = Quaternion.Euler(transform.EulerAngles);
Vector3 targetToLookAt = target.position - transform.position;
Quaternion targetQuat = Quaternion.LookRotation(targetToLookAt);
while(myQuat!=targetQuat)
{
transform.rotation = Quaternion.RotateTowards(myQuat, targetQuat, 10.0f);
myQuat = Quaternion.Euler(transform.EulerAngles)
}
As they said above, putting this in a while loop is probably not the best way to do this. Having it in your Update script is better, but I wrote my answer based on the method you put in your initial question.