- Home /
Loop crashing unity (pathfinding)
Trying to have an object follow a set of Vector3 coordinates one at a time as a form of very specific pathfinding. I have a list of Vector3s and I'm trying to iterate through it but I'm causing an infinite loop or something that locks up unity. Any ideas? Thanks in advance.
void Update () {
if(goToDestination == true){
if(destination.ToUpper() == "CARGO STORAGE"){
while(transform.position != CARGOSTORAGE){
foreach(Vector3 dest in MULE1_TO_CARGO){
while(transform.position != dest){
transform.position = Vector3.Lerp (transform.position, dest, Time.deltaTime * moveSpeed);
}
}
}
}
}
}
The way you've written it, the behaviour is trying to move through all of the points in your route in a single update. I think you should aim for something more like this:
Outside of Update, when the agent is to begin following a route, set a state variable to mark the first target point on the route it should aim for.
Inside of Update:
1) Check whether to follow route. (you have a method for this already) 2) Calculate the max distance you can move in one update (Time.deltaTime * maxSpeed) and compare it against the distance remaining to the current target point. 3) If the distance remaining is within the max distance, then just move straight to that point, otherwise move closer by the max distance. 4) If you reached the target point, then either select the next one in your array, if one exists, or stop following this route. 5) Leave Update and allow the above steps to be repeated next time Update is called.
Answer by SarperS · Oct 25, 2012 at 05:46 AM
All the loops are processed in a single frame, the reason the code you've posted causes an infinite loop means that the conditions are never met(transform.position == CARGOSTORAGE is that condition here). If they did what you would see is a long single frame that processes all the dest in MULE1_TO_CARGO and the next frame which shows the result.
What you have to do is to convert it into a coroutine and move to the next frame after each loop so you will see the results and the change in your objects position each frame.
Could you elaborate a little more? I converted it to a coroutine, and am calling that routine from Update based on the same condition (if (goToDestination == true)), but I'm not 100% sure how to "move to the next frame". With a yield? Where would it go?
Just put a "return yield null;" after "transform.position = Vector3.Lerp..." line
Answer by Kryptos · Oct 25, 2012 at 08:01 AM
Two major mistakes here:
Never ever compare two vectors for equality. This is not possible to reach exactly a target position.
Everything inside
Update
is executed within one frame. But what really you want is to move a step towards your target destination.
Following what @phodges and @sarper suggested, you need to rethink your method (or routine) as a single step, not the complete movement. Using simplified code, this will look like:
void Update()
{
// get the distance to the target (we use a square distance as it is faster to calculate)
float sqrDistance = (this.transform.position - targetPosition).sqrMagnitude;
if (sqrDistance < (minStep*minStep))
{
// Move the object to the target position, as we are very close
this.transform.position = targetPosition;
}
else
{
// Move a step
this.transform.position = Vector3.Lerp(this.transform.position, targetPosition, Time.deltaTime * moveSpeed);
}
Alright, this is definitely a step in the right direction. It gets me to where I need to go, but it all happens at once. Start > LAG > Done. All in half a second or so. I'm not sure what type of value $$anonymous$$Step is intended to be in your example. Here's the code I'm using now: http://pastebin.com/Tje4NS1p
Your answer
Follow this Question
Related Questions
Unity crashes when doing A* pathfinding loop 1 Answer
Unity crashes when using while 2 Answers
Unity freezes when OnTriggerEnter occurs 3 Answers
Why does this code hang the system?? 2 Answers