[2D] Random Spawn inside Camera View and check for Collissions with Other Objects

Hello,

I’m looking for some help on my ‘upgrade’ spawning.
Requirements:

  • Random Location
  • Inside Camera View
  • Not Colliding with other objects when spawning
  • Extra: Later tweaking it that when the camera is moving up it doesn’t spawn to far down etc.

What I have now:

            Vector3 spawnPos = Camera.main.ScreenToWorldPoint(new Vector3(UnityEngine.Random.Range(0, Screen.width), UnityEngine.Random.Range(0, Screen.height), Camera.main.farClipPlane / 2));
            float radius = 5f;

            while (Physics.CheckSphere(spawnPos, radius))
                spawnPos = Camera.main.ScreenToWorldPoint(new Vector3(UnityEngine.Random.Range(0, Screen.width), UnityEngine.Random.Range(0, Screen.height), Camera.main.farClipPlane / 2));

                clone_upgrade = Instantiate(_upgrade, spawnPos, Quaternion.identity) as Transform;
                soundEffect("SpawnPickup");

Here’s what my demo level looks like ingame:


These are the colliders: (Didn’t clean them up yet, just for testing)

I tried making the radius bigger but I’m not getting a good effect. The objects still spawn inside the gray areas.

Any help would be greatly appreciated.

Just noticed, I’m not using the Physics2D… So I changed my code:

            Vector3 spawnPos = Camera.main.ScreenToWorldPoint(new Vector3(UnityEngine.Random.Range(0, Screen.width), UnityEngine.Random.Range(0, Screen.height), Camera.main.farClipPlane / 2));
            float radius = 5f;

            while (Physics2D.OverlapCircle(spawnPos, radius))
                spawnPos = Camera.main.ScreenToWorldPoint(new Vector3(UnityEngine.Random.Range(0, Screen.width), UnityEngine.Random.Range(0, Screen.height), Camera.main.farClipPlane / 2));

                clone_upgrade = Instantiate(_upgrade, spawnPos, Quaternion.identity) as Transform;
                soundEffect("SpawnPickup");
                Transform _upgradeSpawnParticleClone = Instantiate(upgradeSpawnPrefab, spawnPos, Quaternion.identity) as Transform;
                Destroy(_upgradeSpawnParticleClone.gameObject, 2f);

The results are allot better, but still from time to time some of my pickups spawn outside the area I wish. As you can see at the bottom.

Kind regards,
Xercium

Did you found any soloution to ur question? I know this is old but I’m trying to archive the same.

Untested code but this should be a decent approach. This class will start a loop that keeps trying locations randomly in the viewport until it finds one, or until it passes a failure threshold to prevent infinite looping.

using UnityEngine;

public class Spawner : MonoBehaviour
{
    public GameObject prefabToSpawn;
    public float spawnPositionZ;
    public float spawnCheckRadius = 5f;
    public int spawnAttemptsBeforeFailure = 500;

    private Camera _camera;

    private void Awake()
    {
        _camera = Camera.main;
    }

    public void Spawn()
    {
        if(TryGetSpawnPosition(out Vector3 spawnPosition))
        {
            GameObject newObject = Instantiate(prefabToSpawn, spawnPosition, Quaternion.identity);
            // ...etc
        }
    }

    private bool TryGetSpawnPosition(out Vector3 spawnPosition)
    {
        int spawnAttempts = 0;
        do
        {
            spawnPosition = _camera.ViewportToWorldPoint(GetRandomViewportPosition());

            spawnAttempts++;
            if (spawnAttempts > spawnAttemptsBeforeFailure)
            {
                Debug.Log("Couldn't find a spawn position after 500 attempts.");
                return false;
            }
        }
        while (Physics2D.OverlapCircle(spawnPosition, spawnCheckRadius) != null);

        return true;
    }

    private Vector3 GetRandomViewportPosition()
    {
        return new Vector3(Random.value, Random.value, spawnPositionZ);
    }
}
1 Like