TheLost Lostit TheLost Lostit - 2 months ago 11
C# Question

In Unity how can i create number of Spheres Game Objects with random number of Heights and objects?

What i want is to make a script that will create on a Terrain random number of gameObjects in this case Spheres and that it each one will have random Height.

using UnityEngine;
using System.Collections;

public class Random_Objects : MonoBehaviour {

public int Random_Object_Min = 1, Random_Object_Max = 51;
public int Random_Height_Min = 5, Random_Height_Max = 100;
[HideInInspector] private int[] Objects_Number;
[HideInInspector] private int[] Random_Heights;
[HideInInspector] private int Area_Size_To_Build = 0;
[HideInInspector] private Vector3 terrainSize;
[HideInInspector] private GameObject s;
[HideInInspector] private ArrayList myNodes;

// Use this for initialization
void Start () {

Objects_Number = new int[Random.Range (Random_Objects_Min,Random_Objects_Max)];
Random_Heights = new int[Random.Range(Random_Height_Min, Random_Height_Max)];

myNodes = new ArrayList ();
for (int i = 0; i < Objects_Number.Length; i++)
s = GameObject.CreatePrimitive(PrimitiveType.Sphere);
s.transform.position = new Vector3 ((Random.value*461)+10, (Random.value*300)+10, 0F);
//s.transform.localScale += new Vector3(


// Update is called once per frame
void Update () {


The first problem i face is when i create the int arrays i get random places in the array for example 7 indexs. But i also want to assign random heights and maybe also random positions.

So if i get in Objects_Number fro example 7 then in each one i want to have some values like random height for each one and random position for each one.

Then in the For loop some how to extract this random values and create the random Spheres. So in the end in the ArrayList myNodes i will something like:

0 = Position(5,67,0) Scale(30,4,0)

1 = Position(50,67,0) Scale(1,40,0)

And so on. Later i want to create the Spheres to display them in the Terrain when running the game.


Create tags: terrain, sphere

Create layer: terrain


Add terrain to scene, tip: to be able to paint you must assign textures to it first.

Assign terrain tag and layer to terrain.

Make sure it is centered, default size seems 500 so x/z should be -250.

enter image description here


This will place spheres randomly above terrain but ensures height is according terrain below:

using System;
using UnityEngine;
using Random = UnityEngine.Random;

public class SphereBuilder : MonoBehaviour
    // for tracking properties change
    private Vector3 _extents;
    private int _sphereCount;
    private float _sphereSize;

    /// <summary>
    ///     How far to place spheres randomly.
    /// </summary>
    public Vector3 Extents;

    /// <summary>
    ///     How many spheres wanted.
    /// </summary>
    public int SphereCount;

    public float SphereSize;

    private void OnValidate()
        // prevent wrong values to be entered
        Extents = new Vector3(Mathf.Max(0.0f, Extents.x), Mathf.Max(0.0f, Extents.y), Mathf.Max(0.0f, Extents.z));
        SphereCount = Mathf.Max(0, SphereCount);
        SphereSize = Mathf.Max(0.0f, SphereSize);

    private void Reset()
        Extents = new Vector3(250.0f, 20.0f, 250.0f);
        SphereCount = 100;
        SphereSize = 20.0f;

    private void Update()

    private void UpdateSpheres()
        if (Extents == _extents && SphereCount == _sphereCount && Mathf.Approximately(SphereSize, _sphereSize))

        // cleanup
        var spheres = GameObject.FindGameObjectsWithTag("Sphere");
        foreach (var t in spheres)
            if (Application.isEditor)

        var withTag = GameObject.FindWithTag("Terrain");
        if (withTag == null)
            throw new InvalidOperationException("Terrain not found");

        for (var i = 0; i < SphereCount; i++)
            var o = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            o.tag = "Sphere";
            o.transform.localScale = new Vector3(SphereSize, SphereSize, SphereSize);

            // get random position
            var x = Random.Range(-Extents.x, Extents.x);
            var y = Extents.y; // sphere altitude relative to terrain below
            var z = Random.Range(-Extents.z, Extents.z);

            // now send a ray down terrain to adjust Y according terrain below
            var height = 10000.0f; // should be higher than highest terrain altitude
            var origin = new Vector3(x, height, z);
            var ray = new Ray(origin, Vector3.down);
            RaycastHit hit;
            var maxDistance = 20000.0f;
            var nameToLayer = LayerMask.NameToLayer("Terrain");
            var layerMask = 1 << nameToLayer;
            if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
                var distance = hit.distance;
                y = height - distance + y; // adjust
                Debug.LogWarning("Terrain not hit, using default height !");

            // place !
            o.transform.position = new Vector3(x, y, z);

        _extents = Extents;
        _sphereCount = SphereCount;
        _sphereSize = SphereSize;

You could also get mesh bounds of your terrain and place spheres accordingly, if terrain is not zero-centered.


enter image description here

enter image description here

What's next ?