Search Unity

Question Objects not Instantiating properly

Discussion in 'Scripting' started by cb12438, Feb 3, 2023.

  1. cb12438

    cb12438

    Joined:
    Jul 1, 2021
    Posts:
    7
    Everything i try to get these objects to spawn on the grass just does not want to work i rewrote this script maybe 10-20 times now what is going wrong for the objects to now spawn on the mesh but to spawn everywhere else in the water or under the mesh or above the mesh etc, etc

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ObjectGeneration : MonoBehaviour
    6. {
    7.     public GameObject[] gameObjectsToSpawnArray;
    8.     public int[] spawnRarityArray;
    9.     public int objectCount;
    10.     public LayerMask whatIsGround;
    11.     public float spacing;
    12.     public float spawnRange;
    13.     public int objectsPerFrame;
    14.     public BoxCollider generateZone;
    15.  
    16.     private Vector3 _spawnPos;
    17.     private int _currentObjectCount;
    18.  
    19.     private void Start()
    20.     {
    21.         _currentObjectCount = 0;
    22.     }
    23.  
    24.     private void Update()
    25.     {
    26.         if (_currentObjectCount >= objectCount) return;
    27.  
    28.         for (int i = 0; i < objectsPerFrame; i++)
    29.         {
    30.             if (_currentObjectCount >= objectCount) return;
    31.  
    32.             // Calculate a random position within the generateZone
    33.             _spawnPos.x = Random.Range(generateZone.bounds.min.x, generateZone.bounds.max.x);
    34.             _spawnPos.y = generateZone.bounds.max.y; // Start from the top of the generateZone
    35.             _spawnPos.z = Random.Range(generateZone.bounds.min.z, generateZone.bounds.max.z);
    36.  
    37.             // Check if the position is valid (not overlapping with existing objects)
    38.             Collider[] colliders = Physics.OverlapSphere(_spawnPos, spacing, whatIsGround);
    39.             if (colliders.Length > 0)
    40.             {
    41.                 continue;
    42.             }
    43.  
    44.             // Cast a ray down to find the ground, ignoring the generateZone collider
    45.             RaycastHit hit;
    46.             if (Physics.Raycast(_spawnPos, Vector3.down, out hit, Mathf.Infinity, whatIsGround, QueryTriggerInteraction.Ignore))
    47.             {
    48.                 // Make sure the hit object has the desired tag
    49.                 if (hit.collider.gameObject.tag == "MeshLayer")
    50.                 {
    51.                     _spawnPos = hit.point;
    52.                 }
    53.                 else
    54.                 {
    55.                     continue; // Skip if the hit object doesn't have the desired tag
    56.                 }
    57.             }
    58.             else
    59.             {
    60.                 continue; // Skip if the raycast didn't hit anything
    61.             }
    62.  
    63.             // Choose a game object to spawn based on rarity
    64.             int randomIndex = ChooseObjectByRarity();
    65.             if (randomIndex == -1)
    66.             {
    67.                 return; // Handle the case where ChooseObjectByRarity returned -1
    68.             }
    69.  
    70.             GameObject go = gameObjectsToSpawnArray[randomIndex];
    71.  
    72.             // Spawn the object
    73.             Instantiate(go, _spawnPos, Quaternion.identity);
    74.             _currentObjectCount++;
    75.         }
    76.     }
    77.  
    78.     private int ChooseObjectByRarity()
    79.     {
    80.         int randomNumber = Random.Range(0, 100);
    81.         int raritySum = 0;
    82.  
    83.         for (int i = 0; i < gameObjectsToSpawnArray.Length; i++)
    84.         {
    85.             raritySum += spawnRarityArray[i];
    86.  
    87.             if (randomNumber <= raritySum)
    88.             {
    89.                 return i;
    90.             }
    91.         }
    92.  
    93.         return -1;
    94.     }
    95. }    
     
    Last edited: Feb 3, 2023
  2. FlashMuller

    FlashMuller

    Joined:
    Sep 25, 2013
    Posts:
    451
    You are using the bounds of your collider to check if the collision is legit, but the bounds are basically a cube thats surrounding your actual collider. It is a bounding box (google for explanatory images).
    You could instead create a random position based on the bounds (as is), then do a top down raycast against your actual collider and if it does hit, the x and z position are legit and y could be retrieved from the RaycastHit.
     
    PraetorBlue likes this.