|
@@ -1,6 +1,7 @@
|
|
|
using System.Collections;
|
|
|
using System.Collections.Generic;
|
|
|
using UnityEngine;
|
|
|
+using NavMeshSurface = UnityEngine.AI.NavMeshSurface;
|
|
|
using KairoEngine.Core;
|
|
|
using KairoEngine.Chunks;
|
|
|
using KairoEngine.NoiseUtilities;
|
|
@@ -8,30 +9,42 @@ using Utilities = KairoEngine.Utility.Utilities;
|
|
|
using Sirenix.OdinInspector;
|
|
|
using UniRx;
|
|
|
|
|
|
+
|
|
|
namespace KairoEngine.TerrainEngine
|
|
|
{
|
|
|
[HideMonoScript]
|
|
|
public class ChunkTerrainGenerator : MonoBehaviour
|
|
|
{
|
|
|
-
|
|
|
[BoxGroup("Configurations")] public Vector3 voxelSize = new Vector3(1f, 1f, 1f);
|
|
|
[BoxGroup("Configurations")] public Vector3Int chunkSize = new Vector3Int(16, 16, 16);
|
|
|
[BoxGroup("Configurations")] public Vector3Int chunkLimit = new Vector3Int(2, 1, 2);
|
|
|
+ [BoxGroup("Configurations")] public StartConfig startConfiguration = StartConfig.DoNothing;
|
|
|
+ [BoxGroup("Configurations"), ShowIf("@startConfiguration == StartConfig.WaitForEvent")] public string generateWorldEvent = "GenerateWorld";
|
|
|
[BoxGroup("Configurations")] public int dataProcessLimit = 4;
|
|
|
[BoxGroup("Configurations")] public int parallelMeshJobs = 4;
|
|
|
+ [HorizontalGroup("Configurations/NavMesh")] public bool processNavMesh = false;
|
|
|
+ [HorizontalGroup("Configurations/NavMesh"), ShowIf("@processNavMesh"), HideLabel] public NavMeshSurface navMeshSurface;
|
|
|
+ [HorizontalGroup("Configurations/OnChunkGeneratedEvent")] public bool triggerOnChunkGeneratedEvent = true;
|
|
|
+ [HorizontalGroup("Configurations/OnChunkGeneratedEvent"), ShowIf("@triggerOnChunkGeneratedEvent"), HideLabel] public string onChunkGeneratedEvent;
|
|
|
+ [HorizontalGroup("Configurations/OnTerrainGeneratedEvent")] public bool triggerOnTerrainGeneratedEvent = true;
|
|
|
+ [HorizontalGroup("Configurations/OnTerrainGeneratedEvent"), ShowIf("@triggerOnTerrainGeneratedEvent"), HideLabel] public string onTerrainGeneratedEvent;
|
|
|
[BoxGroup("Configurations")] public bool showChunkData = false;
|
|
|
+ [BoxGroup("Configurations")] public bool showDebug = false;
|
|
|
|
|
|
[InlineProperty, HideLabel, BoxGroup("Marching Cubes")] public MarchingCubes4 marchingCubes = new();
|
|
|
+ [BoxGroup("Map Data Generator")] public bool useRandomSeed = false;
|
|
|
[BoxGroup("Map Data Generator"), InlineProperty, HideLabel, SerializeReference] public IMapDataGenerator mapDataGenerator;
|
|
|
|
|
|
[ShowIf("@showChunkData"), BoxGroup("Chunk System"), InlineProperty, HideLabel] public ChunkSystem<BlockBase> chunkSystem;
|
|
|
|
|
|
public Dictionary<Vector3, GameObject> terrainMeshes = new Dictionary<Vector3, GameObject>();
|
|
|
|
|
|
- private List<Vector3> chunkDataBuffer = new List<Vector3>(); // Store list of chunks for populating with data
|
|
|
- private List<Vector3> chunkMeshBuffer = new List<Vector3>(); // Store list of chunks for generating the mesh
|
|
|
+ [ShowInInspector] private List<Vector3> chunkDataBuffer = new List<Vector3>(); // Store list of chunks for populating with data
|
|
|
+ [ShowInInspector] private List<Vector3> chunkMeshBuffer = new List<Vector3>(); // Store list of chunks for generating the mesh
|
|
|
+ [ShowInInspector] private List<Vector3> chunkMeshProcessBuffer = new List<Vector3>(); // Store list of chunks that are waiting for their meshes
|
|
|
|
|
|
private bool initialized = false;
|
|
|
+ private bool buildingNavmesh = false;
|
|
|
|
|
|
public class VoxelUpdateData
|
|
|
{
|
|
@@ -46,11 +59,22 @@ namespace KairoEngine.TerrainEngine
|
|
|
}
|
|
|
private Dictionary<Vector3,List<VoxelUpdateData>> chunkUpdates = new Dictionary<Vector3, List<VoxelUpdateData>>();
|
|
|
|
|
|
+ private void Start()
|
|
|
+ {
|
|
|
+ if(startConfiguration == StartConfig.GenerateOnStart) GenerateWorld();
|
|
|
+ else if(startConfiguration == StartConfig.WaitForEvent) GenericEvents.StartListening(generateWorldEvent, GenerateWorld);
|
|
|
+ }
|
|
|
+
|
|
|
private void Update()
|
|
|
{
|
|
|
marchingCubes.UpdateFinishedJobs();
|
|
|
}
|
|
|
|
|
|
+ private void OnDisable()
|
|
|
+ {
|
|
|
+ if(startConfiguration == StartConfig.WaitForEvent) GenericEvents.StopListening(generateWorldEvent, GenerateWorld);
|
|
|
+ }
|
|
|
+
|
|
|
private void OnDestroy()
|
|
|
{
|
|
|
marchingCubes.OnDestroy();
|
|
@@ -60,6 +84,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
{
|
|
|
chunkSystem = new ChunkSystem<BlockBase>(chunkSize,voxelSize, true);
|
|
|
initialized = true;
|
|
|
+ if(useRandomSeed) mapDataGenerator.SetSeed(Random.Range(0, 100000));
|
|
|
}
|
|
|
|
|
|
public bool IsInitialized() => initialized;
|
|
@@ -162,9 +187,13 @@ namespace KairoEngine.TerrainEngine
|
|
|
public void GenerateTerrainMesh(Vector3 position, bool overwrite = false)
|
|
|
{
|
|
|
bool meshExists = terrainMeshes.TryGetValue(position, out GameObject obj);
|
|
|
- if(meshExists && !overwrite) return;
|
|
|
+ if(meshExists && !overwrite && obj != null) return;
|
|
|
if(!overwrite) terrainMeshes.Add(position, null);
|
|
|
- if(marchingCubes != null) marchingCubes.Generate(chunkSystem, this, position);
|
|
|
+ if(marchingCubes != null)
|
|
|
+ {
|
|
|
+ chunkMeshProcessBuffer.Add(position);
|
|
|
+ marchingCubes.Generate(chunkSystem, this, position);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public void UpdateGenerator()
|
|
@@ -276,7 +305,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
public void DestroyTerrain()
|
|
|
{
|
|
|
var childTransforms = this.gameObject.transform.GetComponentsInChildren<Transform>();
|
|
|
- if(childTransforms.Length > 0) Debug.Log($"Destroying {childTransforms.Length - 1} terrain objects");
|
|
|
+ if(childTransforms.Length > 0) Debug.Log($"Destroying {childTransforms.Length} terrain objects");
|
|
|
for (int i = 0; i < childTransforms.Length; i++)
|
|
|
{
|
|
|
if(childTransforms[i] == this.transform) continue;
|
|
@@ -385,6 +414,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
|
|
|
public void AddGeneratedTerrainMesh(Vector3 chunkPosition, GameObject meshObj)
|
|
|
{
|
|
|
+ chunkMeshProcessBuffer.Remove(chunkPosition);
|
|
|
bool meshExists = terrainMeshes.TryGetValue(chunkPosition, out GameObject currentMesh);
|
|
|
if(currentMesh != null)
|
|
|
{
|
|
@@ -398,6 +428,23 @@ namespace KairoEngine.TerrainEngine
|
|
|
//terrainMeshes.Add(chunkPosition, meshObj);
|
|
|
terrainMeshes[chunkPosition] = meshObj;
|
|
|
}
|
|
|
+ if(triggerOnChunkGeneratedEvent) GenericEvents.Trigger(onChunkGeneratedEvent, chunkPosition);
|
|
|
+ if(!buildingNavmesh && chunkMeshProcessBuffer.Count == 0 && chunkMeshBuffer.Count == 0 && chunkDataBuffer.Count == 0)
|
|
|
+ {
|
|
|
+ buildingNavmesh = true;
|
|
|
+ Timer.ExecuteRealTime(50, () => {
|
|
|
+ if(processNavMesh && navMeshSurface != null)
|
|
|
+ {
|
|
|
+ var cron = new Cronometer();
|
|
|
+ navMeshSurface.BuildNavMesh();
|
|
|
+ //navMeshSurface.UpdateNavMesh(navMeshSurface.navMeshData);
|
|
|
+ cron.Stop();
|
|
|
+ if(showDebug) Debug.Log($"Generated Navmesh in {cron.Print()}");
|
|
|
+ buildingNavmesh = false;
|
|
|
+ }
|
|
|
+ if(triggerOnTerrainGeneratedEvent) GenericEvents.Trigger(onTerrainGeneratedEvent);
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
[Button("Save"), ButtonGroup("Buttons")]
|
|
@@ -405,5 +452,12 @@ namespace KairoEngine.TerrainEngine
|
|
|
{
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+ public enum StartConfig
|
|
|
+ {
|
|
|
+ DoNothing,
|
|
|
+ GenerateOnStart,
|
|
|
+ WaitForEvent
|
|
|
+ }
|
|
|
}
|
|
|
}
|