Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Random prefab Instantiate on a certain zone

Discussion in 'Scripting' started by MikeyJY, May 23, 2020.

  1. MikeyJY

    MikeyJY

    Joined:
    Mar 2, 2018
    Posts:
    530
    i have a crab prefab, that I want to random place on the beach of islands that are on some neighbour terrains.
    upload_2020-5-23_13-17-22.png

    The beach is from the sea level to the grass zone. I have more islands:
    upload_2020-5-23_13-18-35.png
    THe islands are placed on neighbour terrains:
     
  2. leftshoe18

    leftshoe18

    Joined:
    Jul 29, 2017
    Posts:
    61
    You could do something like Random.insideUnitSphere to get a 3D point to place them at. What have you already tried?
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,971
    Perhaps as @leftshoe18 noted just place them randomly, but before emplacing them check the altitude of the ground at that point (raycast downwards) and if it is within your "sea level to the grass zone" height, make crab, otherwise pick again.

    Be careful you don't endlessly loop: only try it so many times, then give up, otherwise if you make a level with sheer steep cliffs on the islands, your crabs will have nowhere to spawn and the loop will lockup unless it has a given retry count.
     
  4. MikeyJY

    MikeyJY

    Joined:
    Mar 2, 2018
    Posts:
    530
    Since the crab is an agent I tried this:
    Code (CSharp):
    1.  
    Code (CSharp):
    1.  
    2. bool RandomPoint(Vector3 center, float range, out Vector3 result)
    3.    {
    4.        for (int i = 0; i < 30; i++)
    5.        {
    6.            Vector3 randomPoint = center + Random.insideUnitSphere * range;
    7.            NavMeshHit hit;
    8.            if (NavMesh.SamplePosition(randomPoint, out hit, 1.0f, NavMesh.AllAreas))
    9.            {
    10.                result = hit.position;
    11.                return true;
    12.            }
    13.        }
    14.        result = Vector3.zero;
    15.        return false;
    16.    }
    17. void Awake(){
    18.       StartCoroutine(Spawn());
    19. }
    20. public IEnumarator Spawn(){
    21.    int i = 0;
    22.    Vecotr3 spawnPos;
    23.    while(i < maxCrabs){
    24.        if(RandomPoint(new Vector3(0, 0, 0), 7000f, out spawnPos)){
    25.            if(Terrain.activeTerrain.SampleHeight(spawnPos) > seaLevel && Terrain.activeTerrain.SampleHeight(spawnPos) < grassLevel){
    26.             //Instantiate crab
    27.             yield return new WaitForEndOfFrame();
    28.             i++;
    29.             }
    30.        }
    31.  
    32.    }
    33. }
    34.  
    But I have more that 1 terrain so Terrain.activeTerrain doesn't works and I can't loop trough all Terrain.activeTerrains.
     
  5. MikeyJY

    MikeyJY

    Joined:
    Mar 2, 2018
    Posts:
    530
    I solved it, thanks