Endless runner obstacles spawning problem


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)

    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;

                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));
                int posIndex = Random.Range(0, 2);
                float yPos;
                Vector3 newRot;

                if(posIndex == 0)
                    yPos = minPos.y;
                    newRot = minRotation;
                    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!

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.