False Place of Random Objects in Random Terrain

Hello, to time i try me in Generate Random Terrain and then place Random Objects on the Terrain. But when i start the Test, the Terrain generate, but the Assets spawn in one Line at the Edge of the Terrain and not in the correct height. Can any Dude or Dudin explain me, what i do wrong?

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

public class WorldGenerator : MonoBehaviour
{
    
     // Größe des Terrains
    public int width = 256;
    public int height = 256;
    public int depth = 20;
    public float scale = 20f;

    // Offset für die Perlin-Noise-Funktion
    public float offsetX = 100f;
    public float offsetY = 100f;

    // Liste von Prefabs, aus denen zufällig gewählt wird
    public GameObject[] prefabList;

        void Start()
        {
            // Zufälligen Offset für die Perlin-Noise-Funktion festlegen
            offsetX = Random.Range(0f, 9999f);
            offsetY = Random.Range(0f, 9999f);
   
            // Terrain erstellen
            Terrain terrain = GetComponent<Terrain>();
            terrain.terrainData = GenerateTerrain(terrain.terrainData);
   
            // Zufällige Objekte auf dem Terrain platzieren
            SpawnRandomObjects(terrain.terrainData, 100);
        }
   
        TerrainData GenerateTerrain(TerrainData terrainData)
        {
            // Größe und Auflösung der heightmap festlegen
            terrainData.heightmapResolution = width + 1;
            terrainData.size = new Vector3(width, depth, height);
   
            // Höhenwerte für die heightmap generieren
            float[,] heights = GenerateHeights();
   
            // Höhenwerte der heightmap festlegen
            terrainData.SetHeights(0, 0, heights);
   
            return terrainData;
        }
   
        float[,] GenerateHeights()
        {
            // Array für die Höhenwerte der heightmap erst
            float[,] heights = new float[width, height];
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    // Berechne Höhe an der aktuellen Stelle mit Perlin Noise
                    float xCoord = (float)x / width * scale + offsetX;
                    float yCoord = (float)y / height * scale + offsetY;
                    heights[x, y] = Mathf.PerlinNoise(xCoord, yCoord);
                }
            }
            return heights;
        }
   
        void SpawnRandomObjects(TerrainData terrainData, int maxObjects)
        {
            // Größe des Höhen-Arrays
            int mapWidth = terrainData.heightmapWidth;
            int mapHeight = terrainData.heightmapHeight;
       
            float[,] heights = terrainData.GetHeights(0, 0, mapWidth, mapHeight);
       
            // Zähle die bisher gespawnten Objekte
            int spawnedObjectCount = 0;
       
            // Beschränke die Schleife auf die Größe des Höhen-Arrays
            for (int x = 0; x < mapWidth; x++)
            {
                for (int y = 0; y < mapHeight; y++)
                {
                    // Wenn die maximale Anzahl an Objekten erreicht ist, beende die Schleife
                    if (spawnedObjectCount >= maxObjects)
                    {
                        break;
                    }
       
                    float height = heights[x, y];
                    Vector3 position = new Vector3(x, height, y);
       
                    // Berechne eine zufällige Wahrscheinlichkeit, ob an dieser Stelle ein Objekt gespawnt wird
                    float probability = Random.Range(0f, 1f);
                    if (probability < 0.1f) // z.B. 10% Wahrscheinlichkeit
                    {
                        // Wähle zufälliges Objekt aus der Liste von Prefabs
                        GameObject prefab = prefabList[Random.Range(0, prefabList.Length)];
                        // Spawne das Objekt an der entsprechenden Stelle und anpassen an die Höhe des Terrains
                        GameObject obj = Instantiate(prefab, position, Quaternion.identity);
                        obj.transform.position = position + Vector3.up * obj.transform.localScale.y * 0.5f;
                        // Erhöhe die Anzahl der gespawnten Objekte um 1
                        spawnedObjectCount++;
                    }
                }
            }
        }
}

Print some data using Debug.Log to gain additional insights. Apparantly your x is always 0 - why?
The trees also appear to spawn at the same height - why?

Print the position(s) and height(s) and look what’s going on. Once you know what is wrong, check the why.

1 Like