123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using KairoEngine.Core;
- using KairoEngine.Chunks;
- using KairoEngine.NoiseUtilities;
- using Sirenix.OdinInspector;
- using UniRx;
- namespace KairoEngine.TerrainEngine
- {
- [HideMonoScript]
- public class ChunkTerrainGenerator : MonoBehaviour
- {
- public MarchingCubes3 marchingCubes3;
- public MarchingCubes2 marchingCubes2;
- public Vector3Int chunkSize = new Vector3Int(16, 16, 16);
- public Vector3Int chunkLimit = new Vector3Int(2, 1, 2);
- //public float noiseMultiplier = 1.5f;
- [InlineProperty, HideLabel, FoldoutGroup("Noise Generator")] public NoiseCombinator noiseCombinator = new NoiseCombinator();
- [HideInInspector] public ChunkSystem<BlockBase> chunkSystem;
- [Button("Generate"), ButtonGroup("Buttons")]
- void CreateChunks()
- {
- if(noiseCombinator == null)
- {
- Debug.LogError("Missing Noise Combinator", this.gameObject);
- return;
- }
- DestroyTerrain();
- Debug.Log("Starting chunk generation");
- chunkSystem = new ChunkSystem<BlockBase>(chunkSize, true);
- for (int x = 0; x < chunkLimit.x; x++) {
- for (int z = 0; z < chunkLimit.z; z++) {
- for (int y = 0; y < chunkLimit.y; y++) {
- Vector3Int chunkPos = new Vector3Int(x * chunkSize.x, y * chunkSize.y, z * chunkSize.z);
- chunkSystem.CreateChunk(chunkPos, (Chunk<BlockBase> c, Vector3Int pos) => new BlockBase(0, 0));
- GenerateChunkTerrain(chunkPos);
- }
- }
- }
- for (int x = 0; x < chunkLimit.x; x++) {
- for (int z = 0; z < chunkLimit.z; z++) {
- for (int y = 0; y < chunkLimit.y; y++) {
- Vector3Int chunkPos = new Vector3Int(x * chunkSize.x, y * chunkSize.y, z * chunkSize.z);
- if(marchingCubes3 != null) marchingCubes3.Generate(chunkSystem, chunkPos);
- else if(marchingCubes2 != null) marchingCubes2.Generate(chunkSystem, chunkPos);
- }
- }
- }
- #if UNITY_EDITOR
- UpdateEditor ();
- #endif
- }
- void GenerateChunkTerrain(Vector3Int initialPos)
- {
- float width = (float)(chunkLimit.x * chunkSize.x);
- float height = (float)(chunkLimit.y * chunkSize.y);
- float length = (float)(chunkLimit.z * chunkSize.z);
- for (int x = 0; x < chunkSize.x; x++) {
- for (int z = 0; z < chunkSize.z; z++) {
- for (int y = 0; y < chunkSize.y; y++) {
- // Get a terrain height using regular old Perlin noise.
- Vector3Int pos = initialPos + new Vector3Int(x, y, z);
- // Old example noise:
- //float thisHeight = height * Mathf.PerlinNoise((float)pos.x / width * noiseMultiplier + 0.001f, (float)pos.z / length * noiseMultiplier + 0.001f);
- float thisHeight = height * noiseCombinator.SamplePoint((float)pos.x / width, (float)pos.z / length);
- uint code = CalculateCode(thisHeight, height);
- BlockBase block = new BlockBase(code, (uint)Mathf.FloorToInt(thisHeight));
- chunkSystem.SetBlock(pos, block);
- }
- }
- }
- }
- void UpdateEditor ()
- {
- Timer.ExecuteRealTime(50, () => {
- if(marchingCubes3 != null)
- {
- marchingCubes3.UpdateFinishedJobs();
- if(!marchingCubes3.IsGeneratorDone()) UpdateEditor();
- }
- });
- }
- [Button("Destroy"), ButtonGroup("Buttons")]
- private void DestroyTerrain()
- {
- var childTransforms = this.gameObject.transform.GetComponentsInChildren<Transform>();
- if(childTransforms.Length > 0) Debug.Log($"Destroying {childTransforms.Length - 1} terrain objects");
- for (int i = 0; i < childTransforms.Length; i++)
- {
- if(childTransforms[i] == this.transform) continue;
- #if UNITY_EDITOR
- DestroyImmediate(childTransforms[i].gameObject);
- #else
- Destroy(childTransforms[i].gameObject);
- #endif
- }
- }
- private uint CalculateCode(float height, float maxHeight)
- {
- var value = height/maxHeight;
- if(value > 0.8) return 2;
- else if(value > 0.4) return 1;
- else return 0;
- }
- }
- }
|