Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

C# GameObjects Spawn Into Each Other Issue

Discussion in 'Scripting' started by kenaochreous, Aug 2, 2016.

  1. kenaochreous

    kenaochreous

    Joined:
    Sep 7, 2012
    Posts:
    395
    I have this script that randomly generates prefabs within a 2D box collider. However I've noticed that sometimes the prefabs spawn into each other. Is there anyway I could prevent this from occurring? I'm not really sure where to start since all of the gameobjects spawn at the same time.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GeneratePrefabsWithinCollider : MonoBehaviour {
    5.     public BoxCollider2D playerCollider;
    6.     public GameObject[] placeableObjects;
    7.     public GameObject currentObject;
    8.     public int numberOfObjects;
    9.     public float max;
    10.  
    11.     public void Start () {
    12.         for(int i = 0; i < numberOfObjects;i++)
    13.         {
    14.             for(int j = 0; j < placeableObjects.Length;j++)
    15.             {
    16.             currentObject = Instantiate(placeableObjects[j],GeneratedPosition(),Quaternion.Euler(0, 0, Random.Range(0f, 360f))) as GameObject;
    17.             currentObject.transform.parent = transform;
    18.             }
    19.         }
    20.     }
    21.    
    22.     Vector3 GeneratedPosition()
    23.     {
    24.         float x,y;
    25.         x = UnityEngine.Random.Range(transform.position.x, transform.position.x + max) - GetComponent<Collider2D>().bounds.extents.x;
    26.         y = UnityEngine.Random.Range(transform.position.y, transform.position.y + max) - GetComponent<Collider2D>().bounds.extents.y;
    27.         return new Vector3(x,y,1);
    28.     }
    29.    
    30.     void OnTriggerEnter2D(Collider2D other) {
    31.         if(other == playerCollider){
    32.             for(int i = 0; i < transform.childCount; i++){
    33.                 if(transform.GetChild(i).gameObject.activeSelf == false){
    34.                     transform.GetChild(i).gameObject.SetActive(true);
    35.                 }
    36.             }
    37.         }
    38.     }
    39.     void OnTriggerExit2D(Collider2D other) {
    40.         if(other == playerCollider){
    41.             for(int i = 0; i < transform.childCount; i++){
    42.                 if(transform.GetChild(i).gameObject.activeSelf == true){
    43.                     transform.GetChild(i).gameObject.SetActive(false);
    44.                 }
    45.             }
    46.         }
    47.     }
    48. }
     
  2. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    Make a two-dimensaional array of booleans to represent a grid. Set to true when an object's spawn location falls within the calculated borders of a grid square. Add a little jitter in random directions if the objects you spawn are smaller than the grid squares.
     
  3. kenaochreous

    kenaochreous

    Joined:
    Sep 7, 2012
    Posts:
    395
    When you say calculated grid square are you referring to the 2D box collider that the prefabs instantiate inside of? Also if I need to calculate borders for grid squares wouldn't I want an array of vector2s or 2Dcolliders rather than bools? I'm afraid I don't quite understand.
     
  4. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    No, what I mean is to think of your screen as a grid of squares where each object is placed somewhere in one of those logical squares. This grid (array of bools) is there to manage available positions on the screen, to avoid the overlap. Maybe you can do it other ways too, but I think just setting a boolean in an array is better, because then you aren't allocating anything extra.

    If you have a maximum of 25 objects you need a 5x5 two-dimensional array, 100 objects = 10x10 and so on, or you can make it a simple one-dimensional array and just multiply x and y for easier Random.Range() use.

    Now you just pick a random x and y position (scaled down to grid size from screen size) and set grid[x,y] to true if it's false, pick another position if true. Once an available square is found, calculate the minimum and maximum screen position from the x and y of the available grid slot, accounting for object size. That's your random range for positioning the object. Now every object should have its place without overlap.

    It's probably harder to explain (especially on a sick day!) than it is to code ;)
     
  5. kenaochreous

    kenaochreous

    Joined:
    Sep 7, 2012
    Posts:
    395
    Sorry that I wasn't able to answer back immediately. I've set the maximum amount of gameobjects that can be instantiated to 64 which would require an 8x8 grid correct? Also what exactly am I checking for one of the bools in the 2 dimensional grid to equal true? Is there a way I can compare the transform.position of currentObject to something else? I'm trying to sketch this out in my mind and understand what I'm trying to do code wise I mean.