Search Unity

How can I make also the Y (Height) to be random ?

Discussion in 'Scripting' started by haimmoshe, Feb 16, 2018.

  1. haimmoshe

    haimmoshe

    Joined:
    Jun 3, 2017
    Posts:
    237
    Code (csharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using Random = UnityEngine.Random;
    5.  
    6. [ExecuteInEditMode]
    7. public class SpawnObjects : MonoBehaviour
    8. {
    9.     // for tracking properties change
    10.     private Vector3 _extents;
    11.     private int _objectCount;
    12.     private float _objectSize;
    13.  
    14.     public GameObject objectToSpawn;
    15.  
    16.     /// <summary>
    17.     ///     How far to place spheres randomly.
    18.     /// </summary>
    19.     public Vector3 Extents;
    20.  
    21.     /// <summary>
    22.     ///     How many spheres wanted.
    23.     /// </summary>
    24.     public int ObjectCount;
    25.  
    26.     public float ObjectSize;
    27.  
    28.     private void OnValidate()
    29.     {
    30.         // prevent wrong values to be entered
    31.         Extents = new Vector3(Mathf.Max(0.0f, Extents.x), Mathf.Max(0.0f, Extents.y), Mathf.Max(0.0f, Extents.z));
    32.         ObjectCount = Mathf.Max(0, ObjectCount);
    33.         ObjectSize = Mathf.Max(0.0f, ObjectSize);
    34.     }
    35.  
    36.     private void Reset()
    37.     {
    38.         Extents = new Vector3(250.0f, 20.0f, 250.0f);
    39.         ObjectCount = 100;
    40.         ObjectSize = 20.0f;
    41.     }
    42.  
    43.     private void Update()
    44.     {
    45.         UpdateSpheres();
    46.     }
    47.  
    48.     private void UpdateSpheres()
    49.     {
    50.         if (Extents == _extents && ObjectCount == _objectCount && Mathf.Approximately(ObjectSize, _objectSize))
    51.             return;
    52.  
    53.         // cleanup
    54.         var spheres = GameObject.FindGameObjectsWithTag("SpawnObject");
    55.         foreach (var t in spheres)
    56.         {
    57.             if (Application.isEditor)
    58.             {
    59.                 DestroyImmediate(t);
    60.             }
    61.             else
    62.             {
    63.                 Destroy(t);
    64.             }
    65.         }
    66.  
    67.         var withTag = GameObject.FindWithTag("Terrain");
    68.         if (withTag == null)
    69.             throw new InvalidOperationException("Terrain not found");
    70.  
    71.         for (var i = 0; i < ObjectCount; i++)
    72.         {
    73.             var o = Instantiate(objectToSpawn);
    74.             o.tag = "SpawnObject";
    75.             o.transform.localScale = new Vector3(ObjectSize, ObjectSize, ObjectSize);
    76.  
    77.             // get random position
    78.             var x = Random.Range(-Extents.x, Extents.x);
    79.             var y = Random.Range(-Extents.y, Extents.y); //Extents.y; // sphere altitude relative to terrain below
    80.             var z = Random.Range(-Extents.z, Extents.z);
    81.  
    82.             // now send a ray down terrain to adjust Y according terrain below
    83.             var height = 10000.0f; // should be higher than highest terrain altitude
    84.             var origin = new Vector3(x, height, z);
    85.             var ray = new Ray(origin, Vector3.down);
    86.             RaycastHit hit;
    87.             var maxDistance = 20000.0f;
    88.             var nameToLayer = LayerMask.NameToLayer("Terrain");
    89.             var layerMask = 1 << nameToLayer;
    90.             if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
    91.             {
    92.                 var distance = hit.distance;
    93.                 y = height - distance + y; // adjust
    94.             }
    95.             else
    96.             {
    97.                 Debug.LogWarning("Terrain not hit, using default height !");
    98.             }
    99.  
    100.             // place !
    101.             o.transform.position = new Vector3(x, y, z);
    102.         }
    103.  
    104.         _extents = Extents;
    105.         _objectCount = ObjectCount;
    106.         _objectSize = ObjectSize;
    107.     }
    108. }
    109.  
    I changed the line:

    Code (csharp):
    1.  
    2. var y = Random.Range(-Extents.y, Extents.y); //Extents.y; // sphere altitude relative to terrain below
    3.  
    But what I'm getting is part of the objects above the terrain and some under the terrain:



    And I want the random height to be only above the terrain.
    For example if I change the Extents Y value to 0 all objects will be on terrain ground if I change it to 100 all objects will be random heights from 0(ground) to 100 range.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    I'm not sure I understand your issue. If you want them all to be above, then you need to set your range to be only values available above. So if that is 0 to extents.y, then set your random to use 0 and extents.y.
     
    haimmoshe likes this.