1
\$\begingroup\$
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InstantiateObjects : MonoBehaviour
{
    public GameObject objectToInstantiate;
    public Terrain terrain;
    public float yOffset = 0.5f;
    public int objectsToInstantiate;
    public bool parent = true;
    public bool randomScale = false;
    public bool manualScale = false;
    public bool patrolPoints = false;

    public Vector3 RandScaleMin;
    public Vector3 RandScaleMax;
    public Vector3 ManualScale;

    private float terrainWidth;
    private float terrainLength;
    private float xTerrainPos;
    private float zTerrainPos;
    private int numberOfObjectsToCreate;
    private GameObject clonedObject;
    private GameObject[] createdObjects;
    private string objname;
    private List<GameObject> list = new List<GameObject>();
    private ObjectPool objectPool;

    public void Start()
    {
        terrainWidth = terrain.terrainData.size.x;
        terrainLength = terrain.terrainData.size.z;

        xTerrainPos = terrain.transform.position.x;
        zTerrainPos = terrain.transform.position.z;

        numberOfObjectsToCreate = objectsToInstantiate;

        objname = objectToInstantiate.name;
        MyCustomEditor.TagsAndLayers.AddTag(objname);

        generateObjectOnTerrain();
    }

    public void ReleaseObjects()
    {
     GameObject[] allobj = GameObject.FindGameObjectsWithTag("ClonedObject");
            for (var i = 0; i < allobj.Length; i++)
            {
                objectPool.ReturnInstance(allobj[i]);
                allobj[i].hideFlags = HideFlags.HideInHierarchy;
            }
            generateObjectOnTerrain();
    }

    public void generateObjectOnTerrain()
    {
        objectPool = new ObjectPool(objectToInstantiate, objectsToInstantiate);

        for (int i = 0; i < objectsToInstantiate; i++)
        {
            float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
            float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);

            float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));

            var randScaleX = Random.Range(RandScaleMin.x, RandScaleMax.x);
            var randScaleY = Random.Range(RandScaleMin.y, RandScaleMax.y);
            var randScaleZ = Random.Range(RandScaleMin.z, RandScaleMax.z);
            var randVector3 = new Vector3(randScaleX, randScaleY, randScaleZ);

            yVal = yVal + yOffset;

            clonedObject = objectPool.GetInstance();

            if (randomScale == true)
                clonedObject.transform.localScale = randVector3;//new Vector3(randScaleX, randScaleY, randScaleZ);

            if (manualScale == true)
                clonedObject.transform.localScale = ManualScale;

            if (parent)
                clonedObject.transform.parent = this.transform;

            clonedObject.tag = "ClonedObject";//objname;

            clonedObject.transform.position = new Vector3(randX, yVal, randZ);
        }

        createdObjects = GameObject.FindGameObjectsWithTag(objname);
    }
}

And the ObjectPool class

using UnityEngine;
using System.Collections.Generic;

public class ObjectPool
{
    private GameObject prefab;

    private List<GameObject> pool;

    public ObjectPool(GameObject prefab, int initialSize)
    {
        this.prefab = prefab;

        this.pool = new List<GameObject>();
        for (int i = 0; i < initialSize; i++)
        {
            AllocateInstance();
        }
    }

    public GameObject GetInstance()
    {
        if (pool.Count == 0)
        {
            AllocateInstance();
        }

        int lastIndex = pool.Count - 1;
        GameObject instance = pool[lastIndex];
        pool.RemoveAt(lastIndex);

        instance.SetActive(true);
        return instance;
    }

    public void ReturnInstance(GameObject instance)
    {
        instance.SetActive(false);
        pool.Add(instance);
    }

    protected virtual GameObject AllocateInstance()
    {
        GameObject instance = (GameObject)GameObject.Instantiate(prefab);
        instance.SetActive(false);
        pool.Add(instance);

        return instance;
    }
}

When i set the ManualScale to 3,3,3 it's fine all the created objects are in the terrain area even if i create 150 game objects.

But if i change the scale to 10,10,10 or 30,30,30 even 7,7,7 some of the game objects if they are Instantiated on the terrain edge one of the edges half of them are out of the terrain area/edge.

I can't figure out yet what to change/add in the script to make the game object to be kept inside the terrain area no matter what scale they are.

In this screenshot the gameobjects scale i set them to 7,7,7 This cube is on the edge and some it is out of the terrain.

Scale 7

And this is scale 20 for example:

Scale 20

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.