Crear una instancia de objetos dentro del área del terreno

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Teleport : MonoBehaviour { public Vector3 terrainArea; public float spinSpeed = 2.0f; public int cloneTeleportations; public GameObject prefab; private bool rotate = false; private bool exited = false; private Transform[] teleportations; private Random rnd = new Random(); private void Start() { GameObject go = GameObject.Find("Terrain"); Terrain terrain = go.GetComponent(Terrain); terrainArea = terrain.terrainData.size; for (int i = 0; i < cloneTeleportations; i++) { GameObject Teleportaion = Instantiate(prefab, new Vector3(Random.Range(i * 10.0F, i * 50.0F), 0, Random.Range(i * 10.0F, i * 50.0F)), Quaternion.identity); Teleportaion.transform.parent = this.transform; Teleportaion.transform.tag = "Teleportation"; } } } 

Ahora algunos objetos del juego están fuera del área del terreno. Lo que quiero hacer es mantener los clones en una posición aleatoria, pero solo dentro del área del terreno.

¿Cómo hago una instancia de objetos dentro del área del terreno?

Noté que estás creando una nueva instancia de la clase Random . No hagas eso con la API Random de Unity. Simplemente use Random.Range para generar números aleatorios.

En cuanto a generar GameObjects aleatorios en un terreno:

1. Encuentra la posición X:

 Min = terrain.terrainData.size.x. Max = terrain.transform.position.x + terrain.terrainData.size.x. 

La X aleatoria final debe ser:

 randX = UnityEngine.Random.Range(Min, Min + Max); 

2. Encuentra la posición Z:

 Min = terrain.transform.position.z; Max = terrain.transform.position.z + terrain.terrainData.size.z; 

El Z al azar final debe ser:

  randZ = UnityEngine.Random.Range(Min, Min + Max); 

3. Encuentra la posición Y:

El eje y no tiene que ser aleatorio. Aunque, puede hacer que sea un valor aleatorio si lo desea.

Simplemente tiene que estar sobre el terreno para que el objeto instanciado no esté debajo del terreno.

Aquí es donde Terrain.SampleHeight entra en su lugar. Debe usar esta función para generar perfectamente una posición que no esté debajo del terreno. Necesita el resultado de # 1 y # 2 para usar esto:

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

Si desea aplicar desplazamiento al eje y, ahora puede hacerlo en este momento.

 yVal = yVal + yOffset; 

A continuación hay un ejemplo general. Tienes que usar este ejemplo para extender tu código actual.

 public GameObject prefab; public Terrain terrain; public float yOffset = 0.5f; private float terrainWidth; private float terrainLength; private float xTerrainPos; private float zTerrainPos; void Start() { //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; generateObjectOnTerrain(); } void generateObjectOnTerrain() { //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; //Generate the Prefab on the generated position GameObject objInstance = (GameObject)Instantiate(prefab, new Vector3(randX, yVal, randZ), Quaternion.identity); }