- Home /
How can I instantiate two prefabs at different times and positions ?
Hi everyone,
I am a newbie in unity and was trying to instantiate two prefabs on 3 different positions and different times too. I want these prefabs two instantiate with a minimum of 1.5 seconds and max of 3 seconds. They should not interefere with each other. I can instantiate one prefab randomly chosing the position and time between 1.5 and 3 seconds and it works well for me. The problem is when I instantiate the second prefab because it intereferes with the first object. Both of these prefabs have a method where they can pick up randomly the position 0, 1, or 2 and the time from min to max.
public Transform[] posTranform;
public RigidBody[] prefab;
private RigidBody prefabInstance1;
private RigidBody prefabInstance2;
private float timer1;
private float timer2;
int randTransform1;
int randTransform2;
private float minTime = 1.5f;
private float maxTime = 3.0f;
void SetRandomPosition1()
{
randTransform1 = Random.Range (0, 3);
}
void SetRandomPosition2()
{
randTransform1 = Random.Range (0, 3);
}
void SetRandomTime1()
{
spawnTime1 = Random.Range (minTime, maxTime);
}
void SetRandomTime2()
{
spawnTime2 = Random.Range (minTime, maxTime);
}
The above methods are called inside of these two conditions set on Update()
void Update ()
{
timer1+=Time.deltaTime;
timer2+=Time.deltaTime;
if (timer1 >= spawnTime1) {
timer1 =0;
prefabInstance1 = Instantiate(prefab[0], posTransform[randomTransform1].position, posTransform[randomTransform1].rotation) as RigidBody;
SetRandomTimer1(); SetRandomPosition1();
}
if (timer2 >= spawnTime2) {
timer2 = 0;
prefabInstance2 = Instantiate(prefab[1], posTransform[randomTransform2].position, posTransform[randomTransform2].rotation) as RigidBody;
SetRandomTimer2(); SetRandomPosition2();
}
}
If someone knows how to make the prefabs not interefere with each other it could be great. ;)
Thank you, Gerald.
What do you mean by interference? How do they interfere one another?
When the game starts the first prefab is spawned and it waits 1.5 seconds to 3.0 seconds to get spawned again in a different instance(position from Transform[] array) or same position doesn't matter (depends on the random number that Random.Range(0, 3) generates. 0 is the first position, 1 is the second and 2 is the third one). What matters is the time of it being spawned one after another which is more than 1.5 seconds. So the first prefab getting spawned works well and doesnt get closer than 1.5 seconds. If it gets closer than that time, then the prefab "interferes", but having only one prefab spawned its not a problem. The problem occurs when the second prefab is spawned after the first prefab or before it ( depends on the $$anonymous$$imum time generated from Random.Range(1.5f, 3.0f). If these prebafs get spawned at different positions they do not interfere with each other, but if the Random.Range(0, 3) selects the same position for both of prefabs to be spawned, then depending on the time difference they get spawned which might be less than 1.5 seconds they became too closer which isn't in my favor. I know I should set a condition comparing their random generated position on Update() and I already tried to do so but had no success because of the code execution time. Sometimes the positions of prefabs are changed if they are the same and it works like a charm but sometimes the position is changed and because of Update() method i guess it changes two times one after another then it spawns the second prefab which ends up at the same position as the first one and unfortunately they are closer to each other depending on the time difference which is less than 1.5 seconds. If you don't understand it tell me again so I can explain it better to you.Sorry for my english too. :) :D
Do you need exactly 3 prefabs? If so, you could generate 3 spawn times and 3 positions in Start()
or Awake()
ins$$anonymous$$d of update.
What I need is: 2 prefabs, 3 positions, a $$anonymous$$ of 1.5 seconds and a max of 3.0 seconds. Random.Range method generates the number of the position from 0-3 and the time from 1.5 to 3.0 seconds. After the two positions and the two time values are generated and chosen from Random.Range method( you can see above in my post at SetRandomPosition() and SetRandomTime() methods) the first prefab gets spawned, then the seconds one is spawned, or the second prefab may get spawned first ( depends on the $$anonymous$$imum time chosen for both of them differently) and then the first prefab get spawned second. Also, I should mention that there are two different timers called on Update() method where they increment every 1 seconds per framepersecond. Then, I compare the timer with the time chosen from Random.Range if (timer >= timechosentospawn).
The reason I use Update() method is because I need to generate random numbers every frame per second. The Start() and Awake() methods are only called once in the beginning of the game If i'm not mistaken.
Answer by GrKl · Dec 21, 2016 at 07:30 AM
Ok, I kindof see what you mean from your last comments, kind off... :)
You really should not be using Update. Really... You do not need new random numbers at every frame as you are saying, you just need them just before instantiating your prefabs.
Do you know about Enumerators? if not, read on those, they will help you doing what you want with much better performance than Update. I was doing same than you before, and that messes up the code and complicates thing. Use Enumerators :) .
Here is an untested solution, but that should work for you, if I'm correct, this should replace all your original code and do what you want. And be cleaner...
public Transform[] posTranform;
public RigidBody[] prefab;
private int randTransform1;
private int randTransform2;
private float minTime = 1.5f;
private float maxTime = 3.0f;
void Start()
{
StartCoroutine(Spawn1(Random.Range(minTime,maxTime)));
StartCoroutine(Spawn2(Random.Range(minTime,maxTime)));
}
private IEnumerator Spawn1(float waitTime)
{
//this will force the function to pause for 'waitTime' time
yield return new WaitForSeconds(waitTime);
while (randTransform1 == randTransform2)
{
//this will force randTransform1 to be different than randTransform2 and thus not interfere with the other
randTransform1 = Random.Range(0,3);
}
Instantiate(prefab[0], posTransform[randTransform1].position, posTransform[randTransform1].rotation) as RigidBody;
StartCoroutine(Spawn1(Random.Range(minTime,maxTime)));
}
private IEnumerator Spawn2(float waitTime)
{
yield return new WaitForSeconds(waitTime);
while (randTransform1 == randTransform2)
{
randTransform2 = Random.Range(0,3);
}
Instantiate(prefab[1], posTransform[randTransform2].position, posTransform[randTransform2].rotation) as RigidBody;
StartCoroutine(Spawn2(Random.Range(minTime,maxTime)));
}
Thanks for helping with the code. The problem now is that the first prefab gets spawned at the first position only with random time and the second prefab gets spawned at the second position only with random time too. None of them gets spawned at the third position or at different positions.
Thats odd, mark both randTransform as public and while game is running, check the values in the inspector. They should have 50% chance to be changed every 1.5 to 3seconds
I just did that and no. They aren't changing at all. The randTransform1 stays always 1 and randTransform2 stays always 0. I guess the problem is with the while condition, but don't know why.
Your answer
Follow this Question
Related Questions
Instantiating from a list of gameobjects randomly, with different positions for each gameobject... 0 Answers
How to Instantiate a GameObject from a ScriptableObject piece of script? 0 Answers
How prefab the instance works? 1 Answer
instantiating a projectile continually over time 2 Answers
Adding prefabs to a list or an array from a folder and instantiating them. 2 Answers