From 14ac1fc7061fe83dde30efe2ee8066284e84c944 Mon Sep 17 00:00:00 2001 From: Ondrej Petrzilka Date: Wed, 31 Oct 2018 09:04:48 +0100 Subject: [PATCH 1/4] + when TerrainCollider found, adds tree colliders --- .../Scripts/NavMeshSurface.cs | 116 ++++++++++++++++-- 1 file changed, 105 insertions(+), 11 deletions(-) diff --git a/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs b/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs index 66377b03..bfaa831a 100644 --- a/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs +++ b/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace UnityEngine.AI @@ -281,6 +282,15 @@ List CollectSources() NavMeshBuilder.CollectSources(worldBounds, m_LayerMask, m_UseGeometry, m_DefaultArea, markups, sources); } + for (int i = 0; i < sources.Count; i++) + { + TerrainData terrain; + if (sources[i].sourceObject.TryCast(out terrain)) + { + CollectTrees(sources[i].component, terrain, sources[i].transform, m_LayerMask, m_UseGeometry, 1, sources); + } + } + if (m_IgnoreNavMeshAgent) sources.RemoveAll((x) => (x.component != null && x.component.gameObject.GetComponent() != null)); @@ -292,6 +302,90 @@ List CollectSources() return sources; } + private static void CollectTrees(Component owner, TerrainData terrain, Matrix4x4 transform, int layerMask, NavMeshCollectGeometry geometry, int area, List sources) + { + var size = terrain.size; + + foreach (var tree in terrain.treeInstances) + { + var proto = terrain.treePrototypes[tree.prototypeIndex].prefab; + var pos = Vector3.Scale(tree.position, size); + var rot = Quaternion.AngleAxis(Mathf.Rad2Deg * tree.rotation, Vector3.up); + var scale = new Vector3(tree.widthScale, tree.heightScale, tree.widthScale); + scale = Vector3.one; + var treeLocal = Matrix4x4.TRS(pos, rot, scale); + + foreach (var collider in proto.GetComponentsInChildren()) + { + Matrix4x4 colliderMatrix = proto.transform.worldToLocalMatrix * collider.transform.localToWorldMatrix; + + NavMeshBuildSource src = new NavMeshBuildSource(); + src.area = area; + src.component = owner; + src.sourceObject = null; + if (SetCollider(collider, transform * treeLocal * colliderMatrix, ref src)) + { + sources.Add(src); + } + } + } + } + + private static bool SetCollider(Collider collider, Matrix4x4 transform, ref NavMeshBuildSource source) + { + BoxCollider box; + SphereCollider sphere; + CapsuleCollider capsule; + MeshCollider mesh; + if (collider.TryCast(out sphere)) + { + // Size is supposed to be radius, but it's actually diameter + source.shape = NavMeshBuildSourceShape.Sphere; + source.size = sphere.radius * 2 * Vector3.one; + source.transform = transform * Matrix4x4.Translate(sphere.center); + return true; + } + else if (collider.TryCast(out capsule)) + { + // Capsule is expected to be in y-axis + var rot = Matrix4x4.identity; + if (capsule.direction == 0) + { + rot = Matrix4x4.Rotate(Quaternion.AngleAxis(90, Vector3.forward)); + } + else if (capsule.direction == 2) + { + rot = Matrix4x4.Rotate(Quaternion.AngleAxis(90, Vector3.right)); + } + + // Size is supposed to be (radius, height, radius), but it's actually diameter instead of radius + source.shape = NavMeshBuildSourceShape.Capsule; + source.size = new Vector3(capsule.radius * 2, capsule.height, capsule.radius * 2); + source.transform = transform * Matrix4x4.Translate(capsule.center) * rot; + return true; + } + else if (collider.TryCast(out box)) + { + source.shape = NavMeshBuildSourceShape.Box; + source.size = box.size; + source.transform = transform * Matrix4x4.Translate(box.center); + return true; + } + else if (collider.TryCast(out mesh)) + { + source.shape = NavMeshBuildSourceShape.Mesh; + source.size = Vector3.one; + source.transform = transform; + source.sourceObject = mesh.sharedMesh; + return true; + } + else + { + Debug.LogWarning("NavMeshSource tree collider not supported: " + collider.GetType().Name); + return false; + } + } + static Vector3 Abs(Vector3 v) { return new Vector3(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z)); @@ -319,18 +413,18 @@ Bounds CalculateWorldBounds(List sources) switch (src.shape) { case NavMeshBuildSourceShape.Mesh: - { - var m = src.sourceObject as Mesh; - result.Encapsulate(GetWorldBounds(worldToLocal * src.transform, m.bounds)); - break; - } + { + var m = src.sourceObject as Mesh; + result.Encapsulate(GetWorldBounds(worldToLocal * src.transform, m.bounds)); + break; + } case NavMeshBuildSourceShape.Terrain: - { - // Terrain pivot is lower/left corner - shift bounds accordingly - var t = src.sourceObject as TerrainData; - result.Encapsulate(GetWorldBounds(worldToLocal * src.transform, new Bounds(0.5f * t.size, t.size))); - break; - } + { + // Terrain pivot is lower/left corner - shift bounds accordingly + var t = src.sourceObject as TerrainData; + result.Encapsulate(GetWorldBounds(worldToLocal * src.transform, new Bounds(0.5f * t.size, t.size))); + break; + } case NavMeshBuildSourceShape.Box: case NavMeshBuildSourceShape.Sphere: case NavMeshBuildSourceShape.Capsule: From 35c319d21f3fbf18b80a07a5535178098dde7368 Mon Sep 17 00:00:00 2001 From: Ondrej Petrzilka Date: Wed, 31 Oct 2018 09:18:50 +0100 Subject: [PATCH 2/4] + NavMeshSurface, tree colliders, taking into account layerMask --- .../Scripts/NavMeshSurface.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs b/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs index bfaa831a..769acd87 100644 --- a/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs +++ b/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs @@ -287,7 +287,7 @@ List CollectSources() TerrainData terrain; if (sources[i].sourceObject.TryCast(out terrain)) { - CollectTrees(sources[i].component, terrain, sources[i].transform, m_LayerMask, m_UseGeometry, 1, sources); + CollectTrees(sources[i].component, terrain, sources[i].transform, m_LayerMask, 1, sources); } } @@ -302,7 +302,7 @@ List CollectSources() return sources; } - private static void CollectTrees(Component owner, TerrainData terrain, Matrix4x4 transform, int layerMask, NavMeshCollectGeometry geometry, int area, List sources) + private static void CollectTrees(Component owner, TerrainData terrain, Matrix4x4 transform, int layerMask, int area, List sources) { var size = terrain.size; @@ -317,15 +317,19 @@ private static void CollectTrees(Component owner, TerrainData terrain, Matrix4x4 foreach (var collider in proto.GetComponentsInChildren()) { - Matrix4x4 colliderMatrix = proto.transform.worldToLocalMatrix * collider.transform.localToWorldMatrix; - - NavMeshBuildSource src = new NavMeshBuildSource(); - src.area = area; - src.component = owner; - src.sourceObject = null; - if (SetCollider(collider, transform * treeLocal * colliderMatrix, ref src)) + // Take into account layer mask + if ((collider.gameObject.layer & layerMask) != 0) { - sources.Add(src); + Matrix4x4 colliderMatrix = proto.transform.worldToLocalMatrix * collider.transform.localToWorldMatrix; + + NavMeshBuildSource src = new NavMeshBuildSource(); + src.area = area; + src.component = owner; + src.sourceObject = null; + if (SetCollider(collider, transform * treeLocal * colliderMatrix, ref src)) + { + sources.Add(src); + } } } } From 38b85d62cc0c55c072673a4c3c8d1a35dd3de982 Mon Sep 17 00:00:00 2001 From: Ondrej Petrzilka Date: Wed, 31 Oct 2018 17:44:01 +0100 Subject: [PATCH 3/4] @ Layer mask --- Assets/NavMeshComponents/Scripts/NavMeshSurface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs b/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs index 769acd87..ba4ebe13 100644 --- a/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs +++ b/Assets/NavMeshComponents/Scripts/NavMeshSurface.cs @@ -318,7 +318,7 @@ private static void CollectTrees(Component owner, TerrainData terrain, Matrix4x4 foreach (var collider in proto.GetComponentsInChildren()) { // Take into account layer mask - if ((collider.gameObject.layer & layerMask) != 0) + if (((1 << collider.gameObject.layer) & layerMask) != 0) { Matrix4x4 colliderMatrix = proto.transform.worldToLocalMatrix * collider.transform.localToWorldMatrix; From 88d403cb05c5b0915419665457f1b18784600fc8 Mon Sep 17 00:00:00 2001 From: Ondrej Petrzilka Date: Thu, 9 Jan 2020 09:24:06 +0100 Subject: [PATCH 4/4] @ missing TryCast --- .../NavMeshComponents/Scripts/ObjectExtensions.cs | 15 +++++++++++++++ .../Scripts/ObjectExtensions.cs.meta | 11 +++++++++++ 2 files changed, 26 insertions(+) create mode 100644 Assets/NavMeshComponents/Scripts/ObjectExtensions.cs create mode 100644 Assets/NavMeshComponents/Scripts/ObjectExtensions.cs.meta diff --git a/Assets/NavMeshComponents/Scripts/ObjectExtensions.cs b/Assets/NavMeshComponents/Scripts/ObjectExtensions.cs new file mode 100644 index 00000000..31a9a0fa --- /dev/null +++ b/Assets/NavMeshComponents/Scripts/ObjectExtensions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public static class ObjectExtensions +{ + public static bool TryCast(this TIn obj, out TOut result) + where TIn : class + where TOut : class + { + result = obj as TOut; + return result != null; + } +} diff --git a/Assets/NavMeshComponents/Scripts/ObjectExtensions.cs.meta b/Assets/NavMeshComponents/Scripts/ObjectExtensions.cs.meta new file mode 100644 index 00000000..b53c6706 --- /dev/null +++ b/Assets/NavMeshComponents/Scripts/ObjectExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b458972556566914eb7c92421c9f9b89 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: