- Home /
Check distance between many objects
Hi,
i am trying to check the distance between many enemies ( their spawn position ) as they spawn at random positions.It works, but is obviously extremely very heavy on performance and sometimes Unity even freezes, so i wanted to ask if there is any better solution ( iam sure there is ).
Here is the code:
if(i > 0)
{
for( var a : int = i; a > 0; a--)
{
while(Vector3.Distance(enemiesPosition[i], enemiesPosition[a - 1]) < spawnDistance)
{
SetRandomPosition();
print("adjusting distance");
}
}
}
I am looping index of an array. EnemiesPosition is Vector3, its position of current enemy and its comparing distance of the previous enemy. If it is in given range, it sets new position. If not it loops again with another enemy which was spawn earlier. I am having like 15 enemies and its totaly crushing Unity, so i guess that the looping for all enemies is the issue, but i dont know how to else check for all other enemies spawning positions so they dont spawn on same spot.
Thanks for any reply.
Luke
I'm not real sure what i
is, but I think I have the general idea of what you're trying to do. One thing that jumps out at me is that the while loop could become an infinity loop fairly easily, and from your code we can't tell if SetRandomPosition()
is guaranteed to get a valid position.
He does say his script works, but it's not easy on the CPU. ;)
And the while loop could indeed become infinite...
I maintain that the potential for infinite looping means he should use a list-of-spawns solution as in my answer. $$anonymous$$aking it less hard on the CPU doesn't change the fact that this is a flawed method.
@Simon V, he also says that Unity sometimes freezes, which could likely be an infinite loop.
Answer by almo · Jul 11, 2011 at 03:05 PM
Well, it can get stuck if this happens:
1) Place 14 enemies.
2) Place 15th.
3) It touches #13, try moving it.
4) It touches #10, try moving it.
5) It touches #5, try moving it.
So you need to do something else.
Like make spawn points, keep them in a list, and then remove them from the list as they are used.
Answer by Simon V · Jul 11, 2011 at 03:08 PM
There are two ways to optimize this.
First is to call update only once every x seconds
The other is to use yield.
I know these are both possible, but I haven't used them , so I don't know how they work exactly.
If you can't figure it out this way, I'll try to search how they work.
Also use Almo's answer ;)
Answer by aldonaletto · Jul 11, 2011 at 03:30 PM
You can span your loop over several frames using yield, which would reduce the load. You could do the following:
private var busy = false; // declare this flag outside any function
...
if(i > 0 && !busy){ // only checkEnemies when last job ended
checkEnemies(i);
i--; // only goes to the next enemy when this one was verified
}
...
function checkEnemies(i: int)
{
busy = true; // I'm busy here
for( var a : int = i; a > 0; a--)
{
while(Vector3.Distance(enemiesPosition[i], enemiesPosition[a - 1]) < spawnDistance)
{
SetRandomPosition();
print("adjusting distance");
}
yield; // continue in next frame
}
busy = false; // I'm done
}
The checkEnemies function sweeps the enemies as before, but after checking each enemy it suspends execution with yield, and only resume in the next frame. It sets the variable busy at start to signal it's working - the caller code must not call this function again until it has finished - and clears it at the end. You must also pass to the next enemy only when checkEnemies has ended - that's why I placed the i decrement after checkEnemies (I'm supposing you're sweeping the enemies with variable i from the number of enemies to 0; if not, adapt this code to your logic).
It may be better to move the yield instruction to inside the while in order to further reduce the CPU load.
Your answer
Follow this Question
Related Questions
Enemy AI help with height check 1 Answer
How to click from specyfic distance? 2 Answers
Getting vectors on an object every so many units 0 Answers
Problem With Vector3.Distance 1 Answer