Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
560 views
in Technique[技术] by (71.8m points)

c# - Instantiate objects within the terrain area

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

Now some gameobjects are out of the terrain area. What I want to do is to keep the clones to be in random position but only inside the terrain area.

How I do Instantiate Objects inside the terrain area?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I noticed that you are creating new instance of the Random class. Don't do that with Unity's Random API. Just use Random.Range to generate random numbers.

As for generating random GameObjects on a terrain:

1.Find the X position:

Min = terrain.terrainData.size.x.

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

The final random X should be:

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

2.Find the Z position:

Min = terrain.transform.position.z;

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

The final random Z should be:

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

3.Find the Y position:

The y-axis does not have to be random. Although, you can make it a random value if you want.

It just has to be over the terrain so that the Instantiated Object will not be under the terrain.

This is where Terrain.SampleHeight comes into place. You must use this function in order to perfectly generate a position that is not under the terrain. You need the result from #1 and #2 to use this:

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

If you want to apply offset to the y-axis, you can now do it at this time.

yVal = yVal + yOffset;

Below is a general example. You have to use this example to extend your current code.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...