Jump to content
Unity Insider Forum

Tilemap Procedural Generation


MustafGames

Recommended Posts

Grüße,

Zum selber nachtesten, braucht ihr nur eine Object als Spieler, welches in der Scene dann verschoben wird, ein Grid mit CellSize auf 1,1,0 und eine Tilemap mit Standartwerten.

bin auf ein Problem gestoßen, wenn ich meine Welt generiere sieht es schon erstmal ganz gut aus, es werden immer die Chunks um dem Spieler herum generiert auch richtig angeordnet, etwas mittiger zum Spieler könnte es sein, es lädt immer dann die Chunks wenn der Spieler unten links in der Ecke ist.

Problem 2: Die Noise sieht irgendwie komisch aus, als würde es die Positionen der Chunks nicht richtig berechnen, kann sein das ich irgendwo einen Tippfehler habe nur ich finde diesen nicht.

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

[System.Serializable]
public class Terrain {
    public string name;
    public float height;
    public TileBase tile;
}

public class WorldGeneration : MonoBehaviour {
    public Tilemap tilemap;
    public Terrain[] terrains;

    private int size = 10;
    private float scale = 50;
    private int octaves = 6;
    private float persistance = 0.55f;
    private float lacunarity = 1.92f;

    void Start () {
        tilemap.ClearAllTiles();
    }

    void Update () {
        LoadChunks();
    }

    public void LoadChunks () {
        Vector2Int pos = new Vector2Int((Mathf.RoundToInt(transform.position.x -5) / (size / 2)), Mathf.RoundToInt(transform.position.y -5) / (size / 2));
        for (int x = -1 + pos.x; x <= 1 + pos.x; x++) {
            for (int y = -1 + pos.y; y <= 1 + pos.y; y++) {
                Vector2Int a = new Vector2Int(x, y);
                Vector2Int b = new Vector2Int(a.x * (size / 6), a.y * (size / 6));
                //Debug.Log(b + "");
                Vector2Int c = new Vector2Int(b.x - (size / 8), b.y - (size / 8));

                float dist = Vector2.Distance(pos, c);
                //if (dist < 15) {
                Generate(b, false);
                //} else if (dist > 15) {
                //    Generate(new Vector2Int(chunk_x, chunk_y), true);
                //}
            }
        }
    }

    public void Generate (Vector2Int pos, bool unload) {
        for (int x = (pos.x * size); x < (pos.x * size + size); x++) {
            for (int y = (pos.y * size); y < (pos.y * size + size); y++) {
                float noiseHeight = Noise(x, y);

                for (int t = 0; t < terrains.Length; t++) {
                    Vector3Int tpos = new Vector3Int(x, y, t);
                    if (!unload) {
                        if (noiseHeight > terrains[t].height) {
                            tilemap.SetTile(tpos, terrains[t].tile);
                        }                   
                    } else {
                        tilemap.SetTile(tpos, null);
                    }
                }
            }
        }
    }

    public float Noise (int x, int y) {
        float amplitude = 1;
        float frequency = 1;
        float noiseHeight = 0;

        for (int i = 0; i < octaves; i++) {
            float noise = Mathf.PerlinNoise((x - (size / 2)) / scale * frequency, (y - (size / 2)) / scale * frequency) * 2 - 1;
            noiseHeight += noise * amplitude;
            amplitude *= persistance;
            frequency *= lacunarity;
        }

        if (noiseHeight > 1) {
            noiseHeight = 1;
        } else if (noiseHeight < 0) {
            noiseHeight = 0;
        }
        return noiseHeight;
    }
}

 

Würde mich sehr freuen wenn Ihr es mal testen könntet und vielleicht sogar mir sagen könntet wo ich mich verschrieben habe.

 

MfG Mustaf

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...