Random Object Instantiation and Terrain Height

hello!

My code is working well to distribute my cacti over X and Z.

However, Terrain.activeTerrain.SampleHeight seems to be ignored, and my cacti are not displaced along with the terrain in scene.

Any advice on how I can fix up my code would be hugely appreciated.
cheers

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

public class SpawnTogether : MonoBehaviour
{
    public GameObject[] myObjects;
    public int cactusNumber;
   

    void Start()
    {
        CreateCacti(cactusNumber);
    }

    void CreateCacti(int cactiNum)
    {
        for (int i = 0; i < cactiNum; i++)
        {
            int randomIndex = Random.Range(0, myObjects.Length);

            Vector3 pos = transform.position;
            pos.y = Terrain.activeTerrain.SampleHeight(transform.position);
            pos.x = Random.Range(-110, 110);
            pos.z = Random.Range(-580, 580);

            Instantiate(myObjects[randomIndex], pos, Quaternion.identity);
        }
    }
}

Try getting and then setting.
Such
var the result of terrain active terrain sample height and then set the .y to this variable.

If all else fails
Debug log your active terrain

Is this was what you meant @LethalGenes ?
It made sense but I'm a coding pleb and this still isn't working as expected.

I'm hoping I've just made some really obvious mistake:

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

public class SpawnTogether : MonoBehaviour
{
    public GameObject[] myObjects;
    public int cactusNumber;


    void Start()
    {
        CreateCacti(cactusNumber);
    }

    void CreateCacti(int cactiNum)
    {
        for (int i = 0; i < cactiNum; i++)
        {
            int randomIndex = Random.Range(0, myObjects.Length);

            var spotHeight = new Vector3(i,Terrain.activeTerrain.SampleHeight(transform.position),i);

            Vector3 pos = transform.position;
            pos.y = spotHeight.y;
            pos.x = Random.Range(-110, 110);
            pos.z = Random.Range(-580, 580);

            Instantiate(myObjects[randomIndex], pos, Quaternion.identity);
        }
    }
}

You are always sampling the height at the same position(transform.position) for all cacti. What you probably wanted is sampling the height at the position where you are going spawn current cactus. Which means that you need to reorder things a bit:

  • choose random x, z values
  • sample height at chosen x, z position
  • create spawn position using the previously generated random x,z and height sampling result

Sorry I meant

float P = Terrain.activeTerrain.SampleHeight(transform.position);

Then you should apply that P instead of setting a get function. Sometimes you can set a get function absolutely fine but other times it can not work. So it’s best to get the float that you need before setting. Terrain.activeterrain sample of transform position is a long get request on the same line as a set request.

1 Like

yes, success.
thanks so much for taking the time to reply @karliss_coldwild and @LethalGenes
I’ll put my working code here for future noobs like myself

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

public class SpawnTogether : MonoBehaviour
{
    public GameObject[] myObjects;
    public int cactusNumber;
   

    void Start()
    {
        CreateCacti(cactusNumber);
    }

    void CreateCacti(int cactiNum)
    {
        for (int i = 0; i < cactiNum; i++)
        {
            int randomIndex = Random.Range(0, myObjects.Length);

            Vector3 randomSpawnPosition = new Vector3(Random.Range(-110, 110), i, Random.Range(-100, 110));

            float spotHeight = Terrain.activeTerrain.SampleHeight(randomSpawnPosition);

            Vector3 pos = transform.position;
            pos.y = spotHeight;
            pos.x = randomSpawnPosition.x;
            pos.z = randomSpawnPosition.z;

            Instantiate(myObjects[randomIndex], pos, Quaternion.identity);
        }
    }
}
2 Likes