'My Game's Infinite Platform Generation does Not Work

I have followed a YouTube tutorial on how to make a doodle jump replica in 5 minutes.

The problem is, this tutorial is rushed and does not provide all the information needed and thus I have encountered one big problem. The infinite random platform generation keeps skewing off to either the left or right side of the screen after a certain point, and I have no clue as to why.

Here is the video tutorial: https://www.youtube.com/watch?v=IUzI95mmbwA I am just wondering if anyone on here could be kind enough to help me on this small problem as it is for my school project and I am not sure how to fix it.

GameManager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public GameObject platformPrefab;

    public int platformCount = 300;

    // Use this for initialization
    void Start ()
    {
        Vector3 spawnPosition = new Vector3();

        for (int i = 0; i < platformCount; i++)
        {
            spawnPosition.y += Random.Range(.5f, 2f);
            spawnPosition.x += Random.Range(-5f, 5f);
            Instantiate(platformPrefab, spawnPosition, Quaternion.identity);
        }
    }
}

Game Hierarchy

GameManager script is on game manager

Platforms being close together issue



Solution 1:[1]

So you generate your platforms using

void Start ()
{
    Vector3 spawnPosition = new Vector3();

    for (int i = 0; i < platformCount; i++)
    {
        spawnPosition.y += Random.Range(.5f, 2f);
        spawnPosition.x += Random.Range(-5f, 5f);
        Instantiate(platformPrefab, spawnPosition, Quaternion.identity);
    }
}

which basically means that the next platform always has an offset to the one before in a range +/- 5.

This means however, that the next value would always have to counterbalance the current offset in order to be fully balanced in total. Since you use a random and not an equal distribution thiis is not guaranteed!

In order to make sure platforms don't get "skewed" to one side infinitely I would simply make sure they still "fit into the screen" and clamp the position accordingly like e.g.

public class GameManager : MonoBehaviour
{
    public GameObject platformPrefab;
    public int platformCount = 300;

    [SerializeField] private Camera mainCamera;

    // Adjust via the Inspector in order to also take platform width into account!
    public float platformWidth;

    [Min(0)] public float xRange = 5f;

    float minX;
    float maxX;

    // Use this for initialization
    void Start ()
    {
        if(!mainCamera) mainCamera = Camera.main;

        // get the screen boarders in world space
        minX = mainCamera.ScreenToWorldPoint(new Vector3(0, 0, -mainCamera.transform.position.z)).x + platformWidth / 2f;
        maxX = mainCamera.ScreenToWorldPoint(new Vector3(Screen.width, 0, -mainCamera.transform.position.z)).x - platformWidth / 2f;

        Vector3 spawnPosition = Vector3.zero;

        for (int i = 0; i < platformCount; i++)
        {
            spawnPosition.y += Random.Range(.5f, 2f);
            spawnPosition.x += Random.Range(-xRange, xRange);

            // now simply clamp the x position so the platform 
            // doesn't go over the screen boarders
            spawnPosition.x = Mathf.Clamp(spawnPosition.x, minX, maxX);

            Instantiate(platformPrefab, spawnPosition, Quaternion.identity);
        }
    }
}

You could of course also instead of only clamping the position actively counter balance the range and shift it left or right accordingly like e.g.

Vector3 spawnPosition = Vector3.zero;

for (int i = 0; i < platformCount; i++)
{
    spawnPosition.y += Random.Range(.5f, 2f);

    var min = -5f;
    var max = 5f;

    var distanceToLeftBorder = spawnPosition.x - minX;
    var distanceToRightBorder = maxX - spawnPosition.x;

    if(distanceToLeftBorder < xRange)
    {
        min += xRange - distanceToLeftBorder;
        max += xRange - distanceToLeftBorder;
    }
    else if(distanceToRightBorder < xRange)
    {
        min -= xRange - distanceToRightBorder;
        max -= xRange - distanceToRightBorder;
    }

    spawnPosition.x += Random.Range(min, max);

    // now simply clamp the x position so the platform 
    // doesn't go over the screen boarders
    spawnPosition.x = Mathf.Clamp(spawnPosition.x, minX, maxX);

    Instantiate(platformPrefab, spawnPosition, Quaternion.identity);
}

To your final issue the platforms being too close I would take yet another different approach:

Instead of randomly place at offset +/- 5 rather separate the sign from the distance and do

var sign = Mathf.Sign(Random.value);
var distance = Random.Range(platformWidth + SPACING, maxDistance);
spawnPosition.x += distance * sign;

which would make sure that the next platform is at minimum the platform width plus an optional spacing (both positive!) and not any closer to the current platform.

I would then instead of clamping simply check if you would hit the border and switch the sign like

var sign = Mathf.Sign(Random.value);
var distance = Random.Range(platformWidth + SPACING, maxDistance);

if(spawnPosition.x + distance * sign < minX || spawnPosition.x + distance * sign > maxX)
{
    sign *= -1;
}

spawnPosition.x += distance * sign;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1