8 Commits fe52032630 ... f9eddd68b0

Author SHA1 Message Date
  James Peret f9eddd68b0 Bumped package version to 0.0.2 1 year ago
  James Peret 0f9df3cfb9 Added random seed to randomize terrain generation 1 year ago
  James Peret 38b8e718b2 Added NavMeshComponents dependecy 1 year ago
  James Peret 301106c437 Added OnChunkGenerated and OnTerrainGenerated Generic Events 1 year ago
  James Peret c3e569af3b Added support for building Navigation Meshes 1 year ago
  James Peret f6b61009c6 Added terrain generation on start or on Generic Event 1 year ago
  James Peret 982b8c099f Added ability to setup the generated mesh GameObject tag 1 year ago
  James Peret b3c5435c86 Added setting to change the generated terrain GameObject layer 1 year ago
7 changed files with 92 additions and 12 deletions
  1. 11 0
      ChangeLog.md
  2. 7 0
      ChangeLog.md.meta
  3. 3 1
      Readme.md
  4. 60 6
      Runtime/ChunkTerrainGenerator.cs
  5. 4 0
      Runtime/MarchingCubes4.cs
  6. 2 1
      Runtime/TerrainEngine.asmdef
  7. 5 4
      package.json

+ 11 - 0
ChangeLog.md

@@ -0,0 +1,11 @@
+# Change Log
+
+### v0.0.2
+
+- Added random seed to randomize terrain generation
+- Added NavMeshComponents dependecy
+- Added OnChunkGenerated and OnTerrainGenerated Generic Events
+- Added support for building Navigation Meshes after the terrain is generated
+- Added terrain generation on start or on Generic Event
+- Added ability to change the generated terrain mesh GameObject tag
+- Added ability to change the generated terrain mesh GameObject layer

+ 7 - 0
ChangeLog.md.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 231eac2ebfd85d9468f5ee8ba469fe59
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 1
Readme.md

@@ -1 +1,3 @@
-# Terrain Engine v0.0.1
+# Terrain Engine v0.0.2
+
+[Change Log](ChangeLog.md)

+ 60 - 6
Runtime/ChunkTerrainGenerator.cs

@@ -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
+        }
     }
 }

+ 4 - 0
Runtime/MarchingCubes4.cs

@@ -19,6 +19,8 @@ namespace KairoEngine.TerrainEngine
         public bool flatShaded;
         public Material material;
         public GameObject parent;
+        [Layer] public int terrainLayer;
+        [Tag] public string terrainTag;
         
 
         private MeshFilter meshFilter;
@@ -137,6 +139,8 @@ namespace KairoEngine.TerrainEngine
             mesh.RecalculateNormals();
             meshFilter.mesh = mesh;
             meshCollider.sharedMesh = mesh;
+            target.layer = terrainLayer;
+            target.tag = terrainTag;
         }
 
         private void ScheduleJob(Vector3 initialPosition)

+ 2 - 1
Runtime/TerrainEngine.asmdef

@@ -10,7 +10,8 @@
         "GUID:560b04d1a97f54a4e82edc0cbbb69285",
         "GUID:f452697229e6bcc469c0eff1574ac090",
         "GUID:142285d3db5e7e849b02ea3a75bc2de7",
-        "GUID:165d83fc3bb2a4144925c85421871d8e"
+        "GUID:165d83fc3bb2a4144925c85421871d8e",
+        "GUID:8c4dd21966739024fbd72155091d199e"
     ],
     "includePlatforms": [],
     "excludePlatforms": [],

+ 5 - 4
package.json

@@ -1,7 +1,7 @@
 {
     "name": "at.kairoscope.kairoengine.terrain-engine",
     "displayName" : "KairoEngine Terrain Engine",
-    "version": "0.0.1",
+    "version": "0.0.2",
     "unity": "2020.3",
     "description": "Terrain Engine for creating voxel worlds",
     "repository": {
@@ -11,14 +11,15 @@
     "author": "Kairoscope",
     "dependencies": {
       "at.kairoscope.thirdparty.sirenix":"1.1.0",
-      "at.kairoscope.kairoengine.core":"0.2.6",
+      "at.kairoscope.kairoengine.core":"0.2.7",
       "at.kairoscope.kairoengine.chunks":"0.0.1",
-      "at.kairoscope.kairoengine.noise-utilities":"0.0.1",
+      "at.kairoscope.kairoengine.noise-utilities":"0.0.2",
       "com.unity.collections":"1.2.4",
       "at.kairoscope.thirdparty.unirx":"1.0.0",
       "at.kairoscope.kairoengine.game-tools":"0.1.3",
       "at.kairoscope.kairoengine.ui":"0.2.9",
-      "at.kairoscope.kairoengine.utilities":"0.2.1"
+      "at.kairoscope.kairoengine.utilities":"0.2.1",
+      "at.kairoscope.thirdparty.nav-mesh-components":"2019.3.1"
     }
   }