Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug Spawning Script Not Working

Discussion in 'Scripting' started by VeryGoodDeveloperISwear, Aug 26, 2023.

  1. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    46
    I have a collectable that I am trying to spawn on terrain. I have 2 Vector3s which are the bounds of the spawning (they make the collectable always within the terrain), and then when I pick a random x and z coordinate within those boundaries (with a y coordinate that is above all terrain). Then, I shoot a raycast directly down and set the collectable's y coordinate to y of the point that was hit.

    However, it seems like the raycast never hits anything because the Debug.Log isn't printing out into the console. I don't know why it doesn't hit though, since the collectables always spawn within the terrain (the terrain has a terrain collider, it doesn't have a physics material if that is important)

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class CollectableSpawner : MonoBehaviour
    4. {
    5.     public int spawnedCollectables;
    6.  
    7.     [SerializeField] private Vector3 corner;
    8.     [SerializeField] private Vector3 oppositeCorner;
    9.  
    10.     [SerializeField] private LayerMask prohibitedSpawnAreaLayer;
    11.     [SerializeField] private GameObject collectable;
    12.  
    13.     private int collectables;
    14.  
    15.     private void Awake() => collectables = Random.Range(PlayerCollectableManager.MinCollectables, PlayerCollectableManager.MaxCollectables + 1);
    16.  
    17.     private void Start()
    18.     {
    19.         while (spawnedCollectables != collectables)
    20.         {
    21.             Vector3 _spawnPosition = new Vector3(Random.Range(corner.x, oppositeCorner.x), 100, Random.Range(corner.z, oppositeCorner.z));
    22.  
    23.             Transform _collectableTransform = Instantiate(collectable).GetComponent<Transform>();
    24.             _collectableTransform.position = _spawnPosition;
    25.  
    26.             if (Physics.OverlapBox(_collectableTransform.position, _collectableTransform.localScale / 2,
    27.                 Quaternion.identity, prohibitedSpawnAreaLayer).Length > 0)
    28.             {
    29.                 Destroy(_collectableTransform.gameObject);
    30.                 continue;
    31.             }
    32.  
    33.             //following code should bring collectable down
    34.             Ray _downRay = new Ray(_collectableTransform.position, new Vector3(_collectableTransform.position.x,
    35.                 Mathf.NegativeInfinity, _collectableTransform.position.z));
    36.  
    37.             //placing spawnedCollectables += 1; inside the if makes an infinite loop
    38.             if (Physics.Raycast(_downRay, out RaycastHit _hitInfo))
    39.             {
    40.                 Debug.Log($"Raycast point y: {_hitInfo.point.y}");
    41.                 _collectableTransform.position = new Vector3(_collectableTransform.position.x, _hitInfo.point.y, _collectableTransform.position.z);
    42.                 _collectableTransform.rotation = Random.rotation;
    43.             }
    44.  
    45.             spawnedCollectables += 1;
    46.         }
    47.     }
    48. }
     
  2. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    You either have a layer problem, or the terrain doesn't have a appropriate collider. For one, raycast's are expensive performance wise, so if you have these spawners spawning above terrain and they fall to the ground, I would just use a standard collision check. if hit terrain = ready for business!
     
  3. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    46
    I tried adding a rigidbody and activating gravity when needed, but it falls really slowly even when I make the mass super high. Is there a better way for me to do it? Also, what do you mean by a layer problem?
     
  4. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    If the terrain isn't set to the terrain layer, or if your ray does layer masking(which it doesn't look like it does).

    But you don't need physics, just do
    transform.Translate(0, -speed, 0)
    . After finding a desired speed. Just don't go too fast, because it can "skip" pass terrain if the movement is too high.

    Unless you have trees and such that it might clip through, then true, it's better to use a rigidbody and keep bouncing until it hits terrain. But not sure why gravity won't pull it down faster, if I ever set gravity just a smidge too high it'll fly through the map. Unless you set drag immensely high? drag should be non-existent or at least very low.

    Also, I just noticed you have all this running in your Start() method, the checks should be in Update() or FixedUpdate() if using physics. As your "while" method might be cutting off too short for anything to finish thinking.