- Home /
Endless runner obstacles spawning problem
Hi!
I am working on a 2D endless runner style game and I am having a few obstacles spawning here and there. It works quite good with the system I have now but it is not really what I want. Since my camera speeds up over time I want the objects to spawn with a close distance to eachother but this system I've made only spawns them in every few seconds which means they distance can get quite big.
I did try to make a system so when the camera gets closer then for example, 20 meters, it would spawn a object. Seemed like a foolproof plan until I tried to implement it. I can not figure out how I would do such a thing.
But here's my code. This is the system I currently use. (Stripped down)
[System.Serializable]
public class SpawnableObject
{
public GameObject prefab;
public Vector2 minPos;
public Vector2 maxPos;
public Vector3 minRotation, maxRotation;
public bool randomBetween;
public float spawnDelay, spawnTimeMin, spawnTimeMax;
}
public SpawnableObject[] spawnableObjects;
void Start()
{
foreach (SpawnableObject obj in spawnableObjects)
{
StartCoroutine(SpawnUniversalObjects(obj.prefab, obj.minPos, obj.maxPos, obj.spawnDelay, obj.spawnTimeMin, obj.spawnTimeMax, obj.randomBetween, obj.minRotation, obj.maxRotation));
}
}
IEnumerator SpawnUniversalObjects(GameObject prefab, Vector2 minPos, Vector2 maxPos, float spawnDelay, float minSpawnTime, float maxSpawnTime, bool randomBetween, Vector3 minRotation, Vector3 maxRotation)
{
yield return new WaitForSeconds(spawnDelay);
while (true)
{
GameObject newObject = Instantiate(prefab) as GameObject;
if(randomBetween)
{
newObject.transform.position = new Vector3(mainCamera.transform.position.x + Random.Range(minPos.x, maxPos.x), Random.Range(minPos.y, maxPos.y), 0);
newObject.transform.eulerAngles = new Vector3(Random.Range(minRotation.x, maxRotation.x), Random.Range(minRotation.y, maxRotation.y), Random.Range(minRotation.z, maxRotation.z));
}
else
{
int posIndex = Random.Range(0, 2);
float yPos;
Vector3 newRot;
if(posIndex == 0)
{
yPos = minPos.y;
newRot = minRotation;
}
else
{
yPos = maxPos.y;
newRot = maxRotation;
}
newObject.transform.position = new Vector3(mainCamera.transform.position.x + Random.Range(minPos.x, maxPos.x), yPos, 0);
newObject.transform.eulerAngles = newRot;
}
yield return new WaitForSeconds(Random.Range(minSpawnTime, maxSpawnTime) - (mo.speed /3));
}
}
Any help to implement something like that I talked about before it greatly appreciated!
Thanks in advance!
Answer by Wolfdog · Jun 06, 2015 at 06:08 PM
This is my logic:
public GameObject[] spawnableObjects;
public float spacing = 2; // spawns every 2 units/metres
private float oldX = 0; // previous camera position
private float newX = 0; // current camera position
private float distanceTravelled = 0;
public Transform camera; // getting camera reference
void Update () {
newX = camera.transform.position.x;
distanceTravelled += newX - oldX; // if you are goint to the right
// if you're going to the left, do this instead:
// distanceTravelled += oldX - newX;
oldX = newX; // this is very important
if (distanceTravelled >= spacing) {
distanceTravelled = 0;
spawnNewObject ();
}
}
void spawnNewObject () {
// code to spawn. Use the newX + some X offset while declaring your new object's position.
}
Basically, I spawn a new obstacle every X units moved. This will work no matter how fast the camera moves.
I tried your code and did a quick test. It keeps spawning objects at a very fast speed. It spawns around 100 objects in 1 second. I have copied the code right of just to do a quick test so it appears there is something wrong with your code.
Here's my code for reference:
newX = mainCamera.transform.position.x;
distanceTravelled += newX - oldX;
if(distanceTravelled >= spacing)
{
distanceTravelled = 0;
Instantiate(spawnObjetcs[Random.Range(0, spawnObjetcs.Length)], new Vector3(newX + 10, 0, 0), Quaternion.identity);
}
But still, it could just be me missing something obvious.
Sorry man, I forgot something very small. I udpated the code with the correct statements. It should work now. Let me know if it doesn't.
@Wolfdog I finally got around to try and fix it. It works great when I copy the code right off but I need to set a few variables for my game to work as it should. So I tried doing that in the update function using a foreach loop and then check for all those things you have provided. But that just ended up spawning them all at a rapid rate. So I tried to do a coroutine with a while loop that would check the things from before but that ended up "crashing" Unity.
So I am not sure how I would do this now. I need to access specific variables from the object. If you want to see a example of this, use the code I posted in the original post.
Your answer
![](https://koobas.hobune.stream/wayback/20220613200712im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
removing instantiated game objects after time 0 Answers
Instantiate objects in a specific order 2 Answers
Generate a continuos platform for endless runner 3 Answers
instanstiate Spawns more then one objec 0 Answers
How to use the same object more than once at the same time when using an "object pooling" pattern? 3 Answers