- Home /
Random instantiate at same frame with each instantiate having unique random direction
Hello! This question should be rather short (and sweet!). I have an enemy type in my game dropping a random set of coins Range(1,10). Problem is, they all go the same way for my "coin.rigidbody2D.AddRelativeForce(randomDirection);". I thought it would go through the for-loop differently each time. How do i go about making it so?
private int numberOfCoins;
void Start() {
numberOfCoins = Random.Range(1,10);
}
void LateUpdate() {
[...]
Vector2 randomDirection = new Vector2(Random.Range(-800f, 800f), Random.Range(-800f, 800f));
GameObject coin;
for (int i = 0; i < numberOfCoins; i++) {
coin = (Instantiate(coinPrefab, enemy.transform.position, enemy.transform.rotation)) as GameObject;
coin.rigidbody2D.AddRelativeForce(randomDirection);
}
Answer by Itaros · Oct 28, 2014 at 06:30 PM
Move
Vector2 randomDirection = new Vector2(Random.Range(-800f, 800f), Random.Range(-800f, 800f));
inside for loop
Additional I might recommend you to optimize your random routine:
Vector2 randomDirection = Random.insideUnitCircle * 800F;
It would be also better if you would leave the definition out of the loop.
Vector2 randomDirection;
GameObject coin;
for (int i = 0; i < numberOfCoins; i++)
{
randomDirection = Random.insideUnitCircle * 800F;
coin = (Instantiate(coinPrefab, enemy.transform.position, enemy.transform.rotation)) as GameObject;
coin.rigidbody2D.AddRelativeForce(randomDirection);
}
or
Vector2 randomDirection;
GameObject coin;
for (int i = 0; i < numberOfCoins; i++)
{
randomDirection = randomDirection = new Vector2(Random.Range(-800f, 800f), Random.Range(-800f, 800f));
coin = (Instantiate(coinPrefab, enemy.transform.position, enemy.transform.rotation)) as GameObject;
coin.rigidbody2D.AddRelativeForce(randomDirection);
}
@Nidre why leaving definition out of loop is better? It creates scope gap, isn't it?
http://stackoverflow.com/questions/407255/difference-between-declaring-variables-before-or-in-loop
Just to clarify what the problem is, in case you hadn't worked it out, is that you're generating a random vector, and then looping over things "numberOfCoin" times, and using that random vector for each one.
Consider the case where you have 3 coins. Your code first generates a random direction, for example, the vector (210, 14).
Now, you start a loop from 0 to 2.
You make a new coin and add a force equal to the vector generated earlier, (210,14)
You make a new coin, but since the direction vector hasn't changed, you add the same force again, (210,14)
You make a third coin, and again, the direction vector hasn't changed, so you add the same force a third time, (210,14).
Now all of your coins are spawned, moving in the same direction.
What you want to happen is to generate a new vector each time you go round the loop. Remember, when you write:
for(...)
{
//some code
}
The loop only goes over the code inside the loop itself, and doesn't touch anything else. Also remember that when you assign something to a value, say:
int x = 4+6;
It stores the result of this calculation, not the calculation itself, meaning that changing variables in the arithmetic do not propagate:
int a = 4; //a is 4
int b = a + 4;//b is 8
a = 1;//b is still 8
With all that said, the last thing to do is exactly what Itaros said: move the generation of the random vector into the start of the loop (and preferably with the optimisation, too). This will cause the program to generate a new variable on each run around the loop, and not just one beforehand.
Well, that is something new for me. I would expect declaring it each pass of loop would create a bigger overhead.
But after reading that topic you've mentioned it actually makes more sense to put them inside the loop.
Your answer
Follow this Question
Related Questions
instantiating vertically 2 Answers
Instantiate ignores position 2 Answers
How to randomly spawn three non repeating gameobjects from an array? 2 Answers