"While" problem

I have a problem using the “while” statement.

currentRotation = transform.rotation;
		destRotation = allign.transform.rotation;
		while(currentRotation != destRotation){
			transform.rotation = Quaternion.Lerp (currentRotation, destRotation, Time.deltaTime * thrustSpeed);
		}

With this code Unity quits responding and i have to force quit it. Is there something wrong with my code or is this a bug? :cry:

Is it inside any type of Update() function ?

if so, you just need to do this…

destRotation = allign.transform.rotation; 
if(transform.rotation != destRotation)
     transform.rotation = Quaternion.Lerp (transform.rotation, destRotation, Time.deltaTime * thrustSpeed);

Though comparing rotations this way is never good because of precision issues.

Otherwise you need to stick a yield in there…

      currentRotation = transform.rotation; 
      destRotation = allign.transform.rotation; 
      while(currentRotation != destRotation) { 
         transform.rotation = Quaternion.Lerp (currentRotation, destRotation, Time.deltaTime * thrustSpeed);
         yield;
      }

so it runs every frame.

Thank you very much! Yes indeed it’s located inside a FixedUpdate() function. I will try the above mentioned :slight_smile:

Also i don’t know if it’s possible but i have a GUI button which activates the align and i wanted this rotation to be made by one click instead of multiple clicking. That is why i wanted the while statement.

So then you need have a boolean var called something like shouldOrient and set it to false at start.

then when user clicks button, it sets shouldOrient to equal true;

then your fixedupdate code could be something like this…

destRotation = allign.transform.rotation; 
if (shouldOrient) {
     if (transform.rotation != destRotation)
          transform.rotation = Quaternion.Lerp (transform.rotation, destRotation, Time.deltaTime * thrustSpeed);
     else
          shouldOrient = false;
}

Also, is allign.transform.rotation changing? if not, its not worth the overhead to set it every framestep, just set it at the start, or set the var destRotation inside the GUI button click.

It’s more like a warp drive system so the align it’s an object child to the space ship that looks at the object you are about to warp(couldn’t find any better solution). So if you are in different places of the solar system you get different align angles.

sure, but its not changing every frame is it? What you are aligning too? Because if it is not, then its a waste to keep updating the destRotation var every framestep…

Sorry, been optimising my iPhone games all day… so I don’t like wasting any cycles :slight_smile:

:smile: yeah you are right i should look into it more cause the planets aren’t moving and while you are in warp you can’t initiate another warp. Thnx for your help! :slight_smile:

Hi,

As a unity newby but a longtime programmer I would suggest you made the classical mistake to compare floating point number for being equal.

All of the transform properties are floating point numbers which are always difficult to compare (so my guess is that the loop is never finished at all).

Personally I would try to cast the 3 rotation properties to integers and then compare them.

Another solution to debug is to add a counter that you put in the while condition before the comparisment, like:

int cnt=0;
while (cnt<20  currentRotation!=destRotation) {
  cnt++;
  ..
}

And then see what rotation you end up with. Again my guess is the currentRotation is never exactly equal to destRotation because it’s made of floating points.

Another problem might be the location of the code, if changing the transform calls the update yet again you will have an unwanted ‘infinite’ recursion.

While you’re definitely right about comparing float values, I don’t see how this code would help avoid the infinite loop myself. And wouldn’t you want an || in this case rather than ?

I think Seon’s example using if statements is the best solution, though. Since Update and FixedUpdate are already loops, the code will already execute for every frame the condition is met.

The original issue the OP had was the freezing of Unity Editor and not being able to pause or stop the code.

That was because running a while loop (or any for that matter) without a yield inside it will cause Unity to try to run teh entire loop until condition is met within the frame… not on a per frame basis. The yield tells Unity to only iterate each frame (or framestep).

I did mention in my post above that comparing the rotations was not a good idea due to precision issues.

There is the Mathf.Approximately command that is supposed to help with float comparison, but its alwys been hit or miss with me.

I generally compare Mathf.Round(ed) values or do some manipulation to them first before comparison.

It’s ok at the moment i use an if statement and it works. I hope that by comparing these rotations won’t affect the game on iPhone, but until optimization i have a game to build :stuck_out_tongue:

Hi,

Your right, i only suggested it to have a loop that at least would exit and allow you to see what goes wrong with the comparisment. The logic should be (I’m always messing the and up as I used to program in Pascal like languages).

The code was supposed to exit after 20 iterations even if the rotation isn’t matched.

there are alternative ways for that comparision that don’t care about float precision at all.

How about projecting your direction onto the normalized dest direction.

when the projection is >= 0.95*the length of your destination vector (0.98 or how close you want it to be) consider it equal

Doh, I’m not sure how I was reading it there, my mistake. An || wouldn’t have exited the loop at all! :sweat_smile: