- Home /
Why does this code hang the system??
Hi guys,
What I'm tryin to do with the code below is: 1. generate a position within the screen and instantiate a sprite (teleportPrefab) 2. add it to the list 3. then, next time the code is called, check the new generated position against the already existing sprite, if it's satisfactory distance away (in this case it's just 1), then instantiate another sprite and add that to the list too 4. keep generating positions for a new sprite and checking against every other, already instantiated sprite's position, if satisfactory, instantiate
for testing purposes, SpawnTeleport()
gets called every half a second just to see if the algorithm works as desired. For K
I initially had 1000 and for teleportDistance
I had 5 but since Unity would just hang after spawning several teleports I lowered those numbers and it still occurs (sometimes right after instantiating one sprite).
The code doesn't have any perpetual loops and has exits for every case so I don't understand why does it hang the system.
Here's the code:
public void SpawnTeleport()
{
GameObject Teleport;
Vector2 teleportPos;
int counter = 0;
float teleportPosX = Random.Range (0.1f, 0.9f);
float teleportPosY = Random.Range (0.1f, 0.9f);
teleportPos = Camera.main.ViewportToWorldPoint (new Vector2(teleportPosX, teleportPosY));
if(TeleportsList.Count > 0)
{
for (int k = 0; k < 10; k++)
{
teleportPosX = Random.Range (0.1f, 0.9f);
teleportPosY = Random.Range (0.1f, 0.9f);
teleportPos = Camera.main.ViewportToWorldPoint (new Vector2(teleportPosX, teleportPosY));
for (int i = 0; i < TeleportsList.Count; i++)
{
if(Vector2.Distance(teleportPos, TeleportsList[i].transform.position) >= teleportDistance)
{
counter++;
}
else
{
counter = 0;
i = 0;
}
if(counter == TeleportsList.Count)
{
Teleport = Instantiate (TeleportPrefab, teleportPos, Quaternion.identity) as GameObject;
TeleportsList.Add (Teleport);
return;
}
}
}
print ("fail");
return;
}
else
{
Teleport = Instantiate (TeleportPrefab, teleportPos, Quaternion.identity) as GameObject;
TeleportsList.Add (Teleport);
return;
}
}
Any help is appreciated!
Answer by VioKyma · Jan 22, 2015 at 11:33 PM
The issue lies in this code:
for (int i = 0; i < TeleportsList.Count; i++)
{
if(Vector2.Distance(teleportPos, TeleportsList[i].transform.position) >= teleportDistance)
{
counter++;
}
else
{
counter = 0;
i = 0;
}
...
}
Where you are setting the counter = 0;, you are also setting i = 0;, which will reset the progress of the loop. As the state of TeleportsList does not change, you will never exit the loop, as it will continually reach this point and then go back to the start of TeleportsList.
I'm doing that to make sure the newly generated position checks against all the other existing ones. This code won't work like that eventually, i don't need to generate many teleports, maybe 5-6 max.
I get what you're saying I just don't see why finding an appropriate space on screen is so hard when there's so much space left?... Any suggestions on how to go about achieving what I need otherwise?
I believe what he's saying is that you get your random range before you enter the for loop. So it will never try different spots because it's stuck in the loop. It finds a random spot and the moment that random spot is unavailable you are stuck in an endless loop.
ah yes, you (and @Vio$$anonymous$$yma) are right, that is a problem there. But if I generate a new position in the else statement (where counter
and i
are nullified) then I'm back to my old problem - the algorithm generates teleports desired distance away only from the very first one and the rest are spawned wherever in relation to each other... any ideas why that is? Guess I broke it even more with this endless loop by trying to fix that issue
Here's my idea. I'm not going to write the code but I think the theory checks out. Create a list of Vector2 in code: http://unity3d.com/learn/tutorials/modules/intermediate/scripting/lists-and-dictionaries
Each list needs to remember the x and y position of the teleport. Whenever you place a new teleport, add it's Vector2 to the list. Each time you check whether a new one is too close to the old one cycle through the entire list and check for all of them. If you are too close to any of them reset the random variables and try again.
One note to keep in $$anonymous$$d is that in theory you can still hang your device for a while if it keeps generating numbers too close to your current teleports.
There is probably a more efficient way than generating random numbers until they are not too close to other random numbers for this but I don't know what it is. You'll need a better programmer than I.
Answer by hav_ngs_ru · Jan 22, 2015 at 11:24 PM
where do you call SpawnTeleport first? Let me guess.... hmmm... in Update? :)) I'm joking of cause, but you can never tell what might happen :))
@hav_ngs_ru as a matter of fact, it is from Update(), If a certain bool becomes true, then there's a timer in update which decreases and when it reaches zero it calls SpawnTeleport() and resets itself to call it again 0.5f seconds later. That bool becomes false after certain point, never to become true again
Your answer
Follow this Question
Related Questions
OnCollisionEnter2D() Instantiate Causing an Infinite Loop 0 Answers
Loop crashing unity (pathfinding) 2 Answers
Instantiate objects in a specific order 2 Answers
Unity hangs packing sprites for Android compressed best quality 2 Answers
How can I make sure my app actually closes when I manually shut it down through iOS? 1 Answer