Home > Blockchain >  How to spawn random objects as waypoints on scene depending no height?
How to spawn random objects as waypoints on scene depending no height?

Time:09-10

This script will work fine if i have a terrain in the scene but i don't have a terrain this case :

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class SpawnObjects : MonoBehaviour
{
    public GameObject prefab;
    public Terrain terrain;
    public int numberOfObjects;
    public float duration;
    public float yOffset = 0.5f;

    private float terrainWidth;
    private float terrainLength;

    private float xTerrainPos;
    private float zTerrainPos;


    void Awake()
    {
        //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;

        StartCoroutine(Generate());
    }

    IEnumerator Generate()
    {
        //Generate the Prefab on the generated position
        for (int i = 0; i < numberOfObjects; i  )
        {
            //Generate random x,z,y position on the terrain
            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));

            //Apply Offset if needed
            yVal = yVal   yOffset;

            GameObject objInstance = (GameObject)Instantiate(prefab,
                new Vector3(randX, yVal, randZ), Quaternion.identity);

            if (duration > 0)
            {
                yield return new WaitForSeconds(duration);
            }
        }
    }
}

In my scene i have some mountains objects not my own it's from a package. and i want to spawn random objects around the mountains.

scene

example of one of the mountains objects :

mountain

CodePudding user response:

Since your terrain has a mesh collider, you can Raycast. Raycasting is basically simulating a line from one point, going in a direction until it hits a collider. Info in this link.

How to use it

  1. We set the first argument to:

    Vector3 origin = (randomX, 999f, randomZ);

    Baically, we get a random number in the x and z. (Must be within the dimensions of the mountain) Also, it must be above the mountain, so set the y to a number larger than the mountain' height.

  2. The second one should be Vector3.down (we are checking where the position hits the mountain)

  3. Output the position that it hit.

Code for it:

...// in class
float fromX, toX, fromZ, toZ;
RaycastHit hit;
...
//In the coroutine
Vector3 mPos = mesh.bounds.center   transform.position;
fromX = -mesh.bounds.extents.x   mPos.x;
toX = mesh.bounds.extents.x   mPos.x;
fromZ = -mesh.bounds.extents.z   mPos.z;
toZ = mesh.bounds.extents.z   mPos.z;

float randX = Random.Range(fromX, toX);
float randZ = Random.Range(fromZ, toZ);
Vector3 checkPos = new Vector3(randX, 999f, randZ);

if (Physics.Raycast(checkPos, Vector3.down, our hit)
{
   Vector3 OUTPUT = hit.point;
}
else
{
   Debug.Log("No point found");
}
...

Edit:

If you want to automatically get toX get mesh.bounds.extents.x mesh.bounds.center transform.position. I edited the script

  • Related