0

I've managed to put together a procedural terrain with defined regions and I am looking to procedurally place objects within the world within these regions. The regions are defined by their height and I am trying to utilise this to correctly place certain objects in certain regions however my result seems to come out slightly odd where objects are able to spawn outside the defined region height. I am using an AnimationCurve as a mesh height curve to prevent water areas from becoming terrain like. I am unsure if this is causing the issue behind in the correct placement. Would appreciate any insight into where I might be going wrong

Defined regions: enter image description here

The Rock region is defined with a height of 0.7 and I try to spawn trees on the map only at a Rock location

Spawning object (Spawn 10) at rock location

    int amount = 0;
    for (int y = 0; y < mapHeight; y++)
    {
        if(amount < 10)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                float currentHeight = noiseMap[x, y];

                if(currentHeight.ToString("f1") == (0.7f).ToString())
                {
                    Debug.Log(currentHeight.ToString("f1"));

                    Vector3 spawnPosition = new Vector3(Random.Range((x), (mapWidth / 2)), currentHeight, Random.Range(y, (mapHeight / 2)));
                    var block = Instantiate(AssetsToSpawn[0].AssetPrefab, spawnPosition, Quaternion.identity);
                    block.transform.SetParent(this.transform);
                    amount++;
                    break;
                }

            }
        } else
        {
            return;
        }

Result

Some seem to spawn in the right location albeit looking slightly weird but the one on the far left is finding itself on flat land, with water and sand; an area not defined as 0.7 or Rock type. enter image description here

Krellex
  • 613
  • 2
  • 7
  • 20

1 Answers1

0

I think the issue lies in the line

Vector3 spawnPosition = new Vector3(Random.Range((x), (mapWidth / 2)), currentHeight, Random.Range(y, (mapHeight / 2)));

you seem to already iterate your map grid using x and y so why pick random positions on your map that might be anywhere between this current position and the center of the map?

I think you would rather want a random position within the current field and do e.g.

Vector3 spawnPosition = new Vector3(x + Random.Range(-0.5f, 0.5f), currentHeight, y + Random.Range(-0.5f, 0.5f));

Besides that why go through strings in

if(currentHeight.ToString("f1") == (0.7f).ToString())

I see that it's probably for the rounding but I would still prefer to rather do e.g.

if(Mathf.Abs(currentHeight - 0.7f) <= 0.05f)

which would have about the same effect but the threshold is better to control.

However, sounds to me like rock rather would be anything between 0.49 and 0.7 actually so actually it should be

if(currentHeight > 0.49f && currentHeight <= 0.7f)

Finally, unless you store somewhere which map position you already populated with a tree your outer for loop will always over and over enter at the exact same grid position, the first one that is encountered to fulfill your inner loop's condition!

So far you where always using the exact se position for all 10 trees, only the random position caused that it didn't seem so.

derHugo
  • 83,094
  • 9
  • 75
  • 115