Randomly 2D instantiate/spawn objects without overlapping. HELP

Hello Everybody,
This is my very first post. I’m just new in Unity and C# programming.
I’m working on a 2D game on which I have different Sprites (one sprite for each letter A to Z) and I want them to be placed when the game starts in a random position avoiding overlapping so as to look for them with my player in order.
Any help will be welcome.
Thanks in advance.

Random positions on a grid? In a line? Within some 2D box but without any grid to it?

There are lots of ways to solve this, but some of them (grid or line) are much easier than others (arbitrary non-overlapping positions). So, please describe what other constraints you have (or are willing to accept).

Random positions “anywhere”, I don’t have any grid. I mean I just have a background and a player to walk around and try to “collect” the letters in A to Z order.

Well, nuts. :slight_smile: That’s the hardest case.

OK then, there’s nothing for it but to keep track of where you’ve spawned already, and for each new object, check all the existing ones to see if it’s going to overlap. Keep trying random locations until you find one that works.

Come to think of it, Adam Buckner had a similar problem in his UnityEvent tutorial. I simplified his Spawner code a bit for my version of the tutorial, and here it is:

using UnityEngine;
using UnityEngine.Events;
using System.Collections;

public class Spawner : MonoBehaviour {
   
    public int spawnCount = 10;

    [Range (1,100)]
    public float spawnRadius = 25;
    public float minionOffset = 1;
    public GameObject minion;
   
    public void Spawn () {
        for (int i = 0; i < spawnCount; i++) {
            Vector3 spawnPosition = GetSpawnPosition();
           
            Quaternion spawnRotation = new Quaternion();
            spawnRotation.eulerAngles = new Vector3(0f, Random.Range (0f, 360f), 0f);
            if (spawnPosition != Vector3.zero) {
                // Create and reparent the new minion
                GameObject noob = Instantiate(minion, spawnPosition, spawnRotation) as GameObject;
                noob.transform.SetParent(transform, true);
            }
        }
    }
   
    Vector3 GetSpawnPosition() {
        Vector3 spawnPosition = new Vector3 ();
        float startTime = Time.realtimeSinceStartup;
        bool test = false;
        while (test == false) {
            Vector2 spawnPositionRaw = Random.insideUnitCircle * spawnRadius;
            spawnPosition = new Vector3 (spawnPositionRaw.x, minionOffset, spawnPositionRaw.y);
            test = !Physics.CheckSphere(spawnPosition, 0.75f);
            if (Time.realtimeSinceStartup - startTime > 0.5f) {
                Debug.Log ("Time out placing Minion!");
                return Vector3.zero;
            }
        }
        return spawnPosition;
    }
   
}

You can see that we’re actually using the physics engine to keep and check the list for us, simply using Physics.CheckSphere. In 2D, you might use Physics2D.OverlapCircle instead.

1 Like

Thanks I’ll try it on my game. I just hace to adapt it because I hace to spawn a different object (letter) each time.