Why the spawn object is not working on plane ? The objects spawn out of the plane area. On the terrain it's working

Viewed 62

The goal is to spawn objects either on the terrain area or the plane area.

It's working fine with the terrain but there are some problems :

When spawn the object on the terrain if the offset is 0.5 the objects spawn under the terrain if the terrain for example is position on 92 on the Y. How can I calculate the offset need to automatic spawn the objects on the terrain surface ? (Same for the plane).

When using plane it's spawning the objects near the plane outside the plane area. How can I make that it will spawn the objects on the plane area? I'm using at the bottom a method to get the plane size but it's not spawning the objects in the plane area.

How can I use coroutine for the GenerateObject method ? Now it's working in the Update() but I want to control the spawning speed.

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class SpawnObjects : MonoBehaviour
{
    public GameObject waypointsPrefab;
    public Terrain terrain;
    public GameObject plane;
    public float yOffset = 0.5f;
    public int waypointsAmount;
    public bool parent = true;
    public bool randomScale = false;
    public bool onTerrain = false;

    public Vector3 RandScaleMin;
    public Vector3 RandScaleMax;

    private float terrainWidth;
    private float terrainLength;
    private float xTerrainPos;
    private float zTerrainPos;
    private float planeWidth;
    private float planeLength;
    private float xPlanePos;
    private float zPlanePos;
    private float randX;
    private float randZ;
    private float yVal;
    private GameObject clonedObject;
    private ObjectPool objectPool;

    public void Start()
    {
        if (terrain != null)
        {
            //Get terrain size
            terrainWidth = terrain.terrainData.size.x;
            terrainLength = terrain.terrainData.size.z;

            //Get terrain position
            xTerrainPos = terrain.transform.position.x;
            zTerrainPos = terrain.transform.position.z;
        }

        planeWidth = PlaneSize().x;
        planeLength = PlaneSize().z;
        xPlanePos = plane.transform.position.x;
        zPlanePos = plane.transform.position.z;

        GenerateObject();


    }

    public void Update()
    {

    }

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

    public void GenerateObject()
    {
        objectPool = new ObjectPool(waypointsPrefab, waypointsAmount);

        for (int i = 0; i < waypointsAmount; i++)
        {
            if (terrain != null && onTerrain)
            {
                //Generate random x,z,y position on the terrain
                randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
                randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);

                yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));
            }
            else
            {
                randX = UnityEngine.Random.Range(xPlanePos, xPlanePos + planeWidth);
                randZ = UnityEngine.Random.Range(zPlanePos, zPlanePos + planeLength);

                yVal = 0;
            }

            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);

            //Apply Offset if needed
            yVal = yVal + yOffset;

            clonedObject = objectPool.GetInstance();

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

            if (parent)
            {
                GameObject parent = GameObject.Find("Waypoints");
                clonedObject.transform.parent = parent.transform;
            }

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

    private Vector3 PlaneSize()
    {
        Mesh planeMesh = plane.GetComponent<MeshFilter>().mesh;
        Bounds bounds = planeMesh.bounds;
        // size in pixels
        float boundsX = plane.transform.localScale.x * bounds.size.x;
        float boundsY = plane.transform.localScale.y * bounds.size.y;
        float boundsZ = plane.transform.localScale.z * bounds.size.z;

        return new Vector3(boundsX, boundsY, boundsZ);
    }
}

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;
    }
}

For the coroutine I did :

IEnumerator GenerateObject(float time)
    {
        objectPool = new ObjectPool(waypointsPrefab, waypointsAmount);

        for (int i = 0; i < waypointsAmount; i++)
        {
            if (terrain != null && onTerrain)
            {
                //Generate random x,z,y position on the terrain
                randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
                randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);

                yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));
            }
            else
            {
                randX = UnityEngine.Random.Range(xPlanePos, xPlanePos + planeWidth);
                randZ = UnityEngine.Random.Range(zPlanePos, zPlanePos + planeLength);

                yVal = 0;
            }

            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);

            //Apply Offset if needed
            yVal = yVal + yOffset;

            clonedObject = objectPool.GetInstance();

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

            if (parent)
            {
                GameObject parent = GameObject.Find("Waypoints");
                clonedObject.transform.parent = parent.transform;
            }

            clonedObject.tag = "Waypoint";
            clonedObject.transform.position = new Vector3(randX, yVal, randZ);

            if (time > 0)
            {
                yield return new WaitForSeconds(time);
            }
        }
    }
0 Answers
Related