- Home /
Spawn sprites X distance away from one another
Hello,
What I'm trying to do is randomly spawn sprites on the screen in a way that each one is a desired distance away from every single other one on the screen. For testing purposes I'm calling SpawnTeleport()
every 0.5f seconds.
Here is my 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 < 1000; 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
{
float teleportPosX = Random.Range (0.1f, 0.9f);
float teleportPosY = Random.Range (0.1f, 0.9f);
teleportPos = Camera.main.ViewportToWorldPoint (new Vector2(teleportPosX, teleportPosY));
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;
}
}
The problem is that instead of the desired outcome, what happens is that a first sprite is spawned, then the second one is spawn a desired distance away (which is teleportDistance
) and then all the others that follow are spawned the correct distance away from the first one but not from each other. I did debugging and it seems to check against each newly spawned sprites position as it should but I still don't get the correct result... At this point I just don't know what's wrong.
Thank you in advance!
Perhaps your return on line 36 should be "break"? It looks like this will stop generating new telporters, once a good location for one is found, rather than allowing k to reach 1000. (or, I miunderstand what the $$anonymous$$:0->1000 loop is for.)
@Glurth the $$anonymous$$ loop is number of attempts to find a suitable position for the new teleport, the one that will be a correct distance away from the already spawned ones. I don't see how putting in "break" will fix the issue at hand...
Oh, I thought that was how many to create or something like that...because from you code, it looks like the "i=0;" resetting your for loop counter, after checking distance, is what will keep it looping to find a new position. That $$anonymous$$ loop doesn't seem to have anything to do with that. Still, my previous suggestion wont help.
EDIT: found a few possible issues: You are not resetting counter=0 just before your for(i) loop. you might want: for (int i = 0, counter=0; i < TeleportsList.Count; i++)
Also, you have the potential for an infinite loops (resetting i=0 inside the loop). suggest you change that to a break, which WILL allow it to use your $$anonymous$$ loop for number of attempts.
Lastly, you are passing a vector2 to the ViewportToWorldPoint, but this function takes AND returns a Vector3, not a vector2. (http://docs.unity3d.com/ScriptReference/Camera.ViewportToWorldPoint.html)
Thanks to you my code works now but I unfortunately don't understand why... thus I'll be grateful if you could answer several questions.
I can't just put counter = 0
in a for loop like this
for (int i = 0; counter=0; i < TeleportsList.Count; i++)
The compiler doesn't allow this does it? I could put counter = 0
just above my for i
loop but what's the point? I nullify counter in the else
statement so that the for i
loop starts with a counter = 0
, what's the point of nullfiying it otherwise? (I left counter = 0
in the else statement for now and the code works).
I made the $$anonymous$$ variable for the attempts but it seems somewhere down the line, while trying to fix the code, I ended up with an infinite loop by making i zero and thus making $$anonymous$$ obsolete, thanks for pointing that out, I changed i = 0
with break, and now my code works as it should, I just don't understand what changed in logic? Without break;
it randoms the new position in the else statement and starts the for loop anew with that, with break;
it goes outside of for i
loop, randoms there and enters the loop again... what's the difference?
Lastly, I know about ViewportToWorldPoint needing and returning Vector3 but I needed Vector2 and the program doesn't seem to $$anonymous$$d for some reason, so I left it be.
Ah, I just noticed:
After you set i=0; the for loop still does it's i++; ... so your loop starts again with i=1, not 0; If you set i=-1; ins$$anonymous$$d of 0 that might work.. but again.. infinite loops scariness FYI: (I edited the FOR syntax comment above to clarify this with "..code..")
(but if you break, it sets i=0; at the start)
Sanity restored?
Your answer
Follow this Question
Related Questions
How is the Bounds.SqrDistance calculated behind the scene? What algorithm/formula does it use? 2 Answers
How can I find the Distance between Two Objects on the X Axis? 3 Answers
ARCore tracking maximum distance 2 Answers
Limit the distance between a GameObject and a Character Controller 0 Answers
Set distance away from an object 0 Answers