diff --git a/Assets/Plugins/NavMeshPlus.meta b/Assets/Plugins/NavMeshPlus.meta new file mode 100644 index 0000000..b79ef25 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0c1e14fc334dfb3458f268c703ed67f8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Gizmos.meta b/Assets/Plugins/NavMeshPlus/Gizmos.meta new file mode 100644 index 0000000..f997dfa --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Gizmos.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9f554f0dfb387d647ae9650f24589d6a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshLink Icon.png b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshLink Icon.png new file mode 100644 index 0000000..f420614 Binary files /dev/null and b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshLink Icon.png differ diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshLink Icon.png.meta b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshLink Icon.png.meta new file mode 100644 index 0000000..bf97686 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshLink Icon.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 68ad4f5d6fe957c4789aedd21ff67ced +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshModifierVolume Icon.png b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshModifierVolume Icon.png new file mode 100644 index 0000000..48f2efa Binary files /dev/null and b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshModifierVolume Icon.png differ diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshModifierVolume Icon.png.meta b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshModifierVolume Icon.png.meta new file mode 100644 index 0000000..dd8cb5b --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshModifierVolume Icon.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 273c8b5db6e39534781066db3444fe88 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface Icon.png b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface Icon.png new file mode 100644 index 0000000..a289cf6 Binary files /dev/null and b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface Icon.png differ diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface Icon.png.meta b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface Icon.png.meta new file mode 100644 index 0000000..e99641f --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface Icon.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 444810ca896903c41adf617b35274dc4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface2d Icon.png b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface2d Icon.png new file mode 100644 index 0000000..37124c5 Binary files /dev/null and b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface2d Icon.png differ diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface2d Icon.png.meta b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface2d Icon.png.meta new file mode 100644 index 0000000..e06ad44 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurface2d Icon.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: d5b0e13ebe59cd64e9f67284457c6868 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurfaceGears Icon.png b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurfaceGears Icon.png new file mode 100644 index 0000000..497a19b Binary files /dev/null and b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurfaceGears Icon.png differ diff --git a/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurfaceGears Icon.png.meta b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurfaceGears Icon.png.meta new file mode 100644 index 0000000..6e4d104 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Gizmos/NavMeshSurfaceGears Icon.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: e8142b1daeea8d3419cd0ffbd7b17a37 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/LICENSE b/Assets/Plugins/NavMeshPlus/LICENSE new file mode 100644 index 0000000..ed30590 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 h8man + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Assets/Plugins/NavMeshPlus/LICENSE.meta b/Assets/Plugins/NavMeshPlus/LICENSE.meta new file mode 100644 index 0000000..122cc1a --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/LICENSE.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4aafea534cdccb843b27a8b6e839a76f +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents.meta new file mode 100644 index 0000000..3366784 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b9669812fb313c842943ae58d9c50699 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor.meta new file mode 100644 index 0000000..3801fb1 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 455bb0723c59a9145bc3c035376ca788 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/AgentOverride2dEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/AgentOverride2dEditor.cs new file mode 100644 index 0000000..34f7628 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/AgentOverride2dEditor.cs @@ -0,0 +1,29 @@ +using UnityEditor; + +namespace NavMeshPlus.Extensions.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(AgentOverride2d))] + internal class AgentOverride2dEditor : Editor + { + //SerializedProperty m_OverrideByGrid; + //SerializedProperty m_UseMeshPrefab; + //SerializedProperty m_CompressBounds; + //SerializedProperty m_OverrideVector; + void OnEnable() + { + //m_OverrideByGrid = serializedObject.FindProperty("m_OverrideByGrid"); + //m_UseMeshPrefab = serializedObject.FindProperty("m_UseMeshPrefab"); + //m_CompressBounds = serializedObject.FindProperty("m_CompressBounds"); + //m_OverrideVector = serializedObject.FindProperty("m_OverrideVector"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + var agent = target as AgentOverride2d; + EditorGUILayout.LabelField("Agent Override", agent.agentOverride?.GetType().Name); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/AgentOverride2dEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/AgentOverride2dEditor.cs.meta new file mode 100644 index 0000000..0ce714f --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/AgentOverride2dEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86cc6cf350c6f62469395948494f0945 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSources2dEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSources2dEditor.cs new file mode 100644 index 0000000..39fbbed --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSources2dEditor.cs @@ -0,0 +1,82 @@ +using UnityEngine; +using UnityEditor; + +namespace NavMeshPlus.Extensions.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(CollectSources2d))] + internal class CollectSources2dEditor: Editor + { + SerializedProperty m_OverrideByGrid; + SerializedProperty m_UseMeshPrefab; + SerializedProperty m_CompressBounds; + SerializedProperty m_OverrideVector; + void OnEnable() + { + m_OverrideByGrid = serializedObject.FindProperty("m_OverrideByGrid"); + m_UseMeshPrefab = serializedObject.FindProperty("m_UseMeshPrefab"); + m_CompressBounds = serializedObject.FindProperty("m_CompressBounds"); + m_OverrideVector = serializedObject.FindProperty("m_OverrideVector"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + var surf = target as CollectSources2d; + + EditorGUILayout.PropertyField(m_OverrideByGrid); + using (new EditorGUI.DisabledScope(!m_OverrideByGrid.boolValue)) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_UseMeshPrefab); + EditorGUI.indentLevel--; + } + EditorGUILayout.PropertyField(m_CompressBounds); + EditorGUILayout.PropertyField(m_OverrideVector); + + EditorGUILayout.Space(); + + serializedObject.ApplyModifiedProperties(); + + using (new EditorGUI.DisabledScope(Application.isPlaying)) + { + GUILayout.BeginHorizontal(); + if (GUILayout.Button(new GUIContent("Rotate Surface to XY", "Rotates Surface along XY plane to face toward standard 2d camera."))) + { + foreach (CollectSources2d item in targets) + { + item.transform.rotation = Quaternion.Euler(-90f, 0f, 0f); + } + } +#if UNITY_6000_0_OR_NEWER + GUILayout.EndHorizontal(); + foreach (CollectSources2d navSurface in targets) + { + if (!Mathf.Approximately(navSurface.transform.eulerAngles.x, 270f)) + { + EditorGUILayout.HelpBox("NavMeshSurface is not rotated respectively to (x-90;y0;z0). Apply rotation unless intended.", MessageType.Warning); + } + } +#else + if (GUILayout.Button(new GUIContent("Tilt Surface", "If your agent get stuck on vertical movement it may help to solve the issue. This will tilt Surface to -89.98. It may impact baking and navigation."))) + { + foreach (CollectSources2d item in targets) + { + item.transform.rotation = Quaternion.Euler(-89.98f, 0f, 0f); + } + } + GUILayout.EndHorizontal(); + foreach (CollectSources2d navSurface in targets) + { + if (!Mathf.Approximately(navSurface.transform.eulerAngles.x, 270.0198f) && !Mathf.Approximately(navSurface.transform.eulerAngles.x, 270f)) + { + EditorGUILayout.HelpBox("NavMeshSurface is not rotated respectively to (x-90;y0;z0). Apply rotation unless intended.", MessageType.Warning); + } + } +#endif + } + } + } + +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSources2dEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSources2dEditor.cs.meta new file mode 100644 index 0000000..f1a4a2d --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSources2dEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3fc821cbc11a48745bc9edea6bfda007 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSourcesCache2dEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSourcesCache2dEditor.cs new file mode 100644 index 0000000..e707c27 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSourcesCache2dEditor.cs @@ -0,0 +1,40 @@ +using UnityEngine; +using UnityEditor; + +namespace NavMeshPlus.Extensions.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(CollectSourcesCache2d))] + internal class CollectSourcesCache2dEditor : Editor + { + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + var surf = target as CollectSourcesCache2d; + + serializedObject.ApplyModifiedProperties(); + using (new EditorGUI.DisabledScope(!Application.isPlaying)) + { + GUILayout.BeginHorizontal(); + GUILayout.Label("Sources:"); + if (Application.isPlaying) + { + GUILayout.Label(surf.SourcesCount.ToString()); + GUILayout.Label("Cached:"); + GUILayout.Label(surf.CahcheCount.ToString()); + } + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + GUILayout.Label("Actions:"); + if (GUILayout.Button("Update Mesh")) + { + surf.UpdateNavMesh(); + } + GUILayout.EndHorizontal(); + } + } + } + +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSourcesCache2dEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSourcesCache2dEditor.cs.meta new file mode 100644 index 0000000..66f8061 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/CollectSourcesCache2dEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3616009fd1ab770409e0321881372357 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAgentAttributePropertyDrawer.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAgentAttributePropertyDrawer.cs new file mode 100644 index 0000000..3cabce5 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAgentAttributePropertyDrawer.cs @@ -0,0 +1,21 @@ +using NavMeshPlus.Components.Editors; +using UnityEditor; +using UnityEngine; + + +//*********************************************************************************** +// Contributed by author jl-randazzo github.com/jl-randazzo +//*********************************************************************************** +namespace NavMeshPlus.Extensions.Editors +{ + [CustomPropertyDrawer(typeof(NavMeshAgentAttribute))] + public class NavMeshAgentAttributePropertyDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + NavMeshComponentsGUIUtility.AgentTypePopup(position, label.text, property); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) => NavMeshComponentsGUIUtility.IsAgentSelectionValid(property) ? 20 : 40; + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAgentAttributePropertyDrawer.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAgentAttributePropertyDrawer.cs.meta new file mode 100644 index 0000000..def39b4 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAgentAttributePropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d43a96ce80684449a8b4eee132e5d47 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAreaAttributePropertyDrawer.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAreaAttributePropertyDrawer.cs new file mode 100644 index 0000000..e8dbe45 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAreaAttributePropertyDrawer.cs @@ -0,0 +1,20 @@ +using NavMeshPlus.Components.Editors; +using UnityEditor; +using UnityEngine; + +//*********************************************************************************** +// Contributed by author jl-randazzo github.com/jl-randazzo +//*********************************************************************************** +namespace NavMeshPlus.Extensions.Editors +{ + [CustomPropertyDrawer(typeof(NavMeshAreaAttribute))] + public class NavMeshAreaAttributePropertyDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + NavMeshComponentsGUIUtility.AreaPopup(position, label.text, property); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) => 20; + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAreaAttributePropertyDrawer.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAreaAttributePropertyDrawer.cs.meta new file mode 100644 index 0000000..51960c7 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAreaAttributePropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51136e93cfad4dd7883ae6248247b6a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d5b0e13ebe59cd64e9f67284457c6868, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAssetManager.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAssetManager.cs new file mode 100644 index 0000000..dba3940 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAssetManager.cs @@ -0,0 +1,334 @@ +using System.Collections.Generic; +using System.IO; +using UnityEditor.SceneManagement; +using UnityEngine.AI; +using UnityEngine; +using UnityEditor; + +namespace NavMeshPlus.Components.Editors +{ + public class NavMeshAssetManager : ScriptableSingleton + { + internal struct AsyncBakeOperation + { + public NavMeshSurface surface; + public NavMeshData bakeData; + public AsyncOperation bakeOperation; + } + + List m_BakeOperations = new List(); + internal List GetBakeOperations() { return m_BakeOperations; } + + struct SavedPrefabNavMeshData + { + public NavMeshSurface surface; + public NavMeshData navMeshData; + } + + List m_PrefabNavMeshDataAssets = new List(); + + static string GetAndEnsureTargetPath(NavMeshSurface surface) + { + // Create directory for the asset if it does not exist yet. + var activeScenePath = surface.gameObject.scene.path; + + var targetPath = "Assets"; + if (!string.IsNullOrEmpty(activeScenePath)) + { + targetPath = Path.Combine(Path.GetDirectoryName(activeScenePath), Path.GetFileNameWithoutExtension(activeScenePath)); + } + else + { + var prefabStage = PrefabStageUtility.GetPrefabStage(surface.gameObject); + var isPartOfPrefab = prefabStage != null && prefabStage.IsPartOfPrefabContents(surface.gameObject); + + if (isPartOfPrefab) + { +#if UNITY_2020_1_OR_NEWER + var assetPath = prefabStage.assetPath; +#else + var assetPath = prefabStage.prefabAssetPath; +#endif + if (!string.IsNullOrEmpty(assetPath)) + { + var prefabDirectoryName = Path.GetDirectoryName(assetPath); + if (!string.IsNullOrEmpty(prefabDirectoryName)) + targetPath = prefabDirectoryName; + } + } + } + if (!Directory.Exists(targetPath)) + Directory.CreateDirectory(targetPath); + return targetPath; + } + + static void CreateNavMeshAsset(NavMeshSurface surface) + { + var targetPath = GetAndEnsureTargetPath(surface); + + var combinedAssetPath = Path.Combine(targetPath, "NavMesh-" + surface.name + ".asset"); + combinedAssetPath = AssetDatabase.GenerateUniqueAssetPath(combinedAssetPath); + AssetDatabase.CreateAsset(surface.navMeshData, combinedAssetPath); + } + + NavMeshData GetNavMeshAssetToDelete(NavMeshSurface navSurface) + { + if (PrefabUtility.IsPartOfPrefabInstance(navSurface) && !PrefabUtility.IsPartOfModelPrefab(navSurface)) + { + // Don't allow deleting the asset belonging to the prefab parent + var parentSurface = PrefabUtility.GetCorrespondingObjectFromSource(navSurface) as NavMeshSurface; + if (parentSurface && navSurface.navMeshData == parentSurface.navMeshData) + return null; + } + + // Do not delete the NavMeshData asset referenced from a prefab until the prefab is saved + var prefabStage = PrefabStageUtility.GetPrefabStage(navSurface.gameObject); + var isPartOfPrefab = prefabStage != null && prefabStage.IsPartOfPrefabContents(navSurface.gameObject); + if (isPartOfPrefab && IsCurrentPrefabNavMeshDataStored(navSurface)) + return null; + + return navSurface.navMeshData; + } + + void ClearSurface(NavMeshSurface navSurface) + { + var hasNavMeshData = navSurface.navMeshData != null; + StoreNavMeshDataIfInPrefab(navSurface); + + var assetToDelete = GetNavMeshAssetToDelete(navSurface); + navSurface.RemoveData(); + + if (hasNavMeshData) + { + SetNavMeshData(navSurface, null); + EditorSceneManager.MarkSceneDirty(navSurface.gameObject.scene); + } + + if (assetToDelete) + AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(assetToDelete)); + } + + public void StartBakingSurfaces(UnityEngine.Object[] surfaces) + { + // Remove first to avoid double registration of the callback + EditorApplication.update -= UpdateAsyncBuildOperations; + EditorApplication.update += UpdateAsyncBuildOperations; + + foreach (NavMeshSurface surf in surfaces) + { + StoreNavMeshDataIfInPrefab(surf); + + var oper = new AsyncBakeOperation(); + + oper.bakeData = InitializeBakeData(surf); + oper.bakeOperation = surf.UpdateNavMesh(oper.bakeData); + oper.surface = surf; + + m_BakeOperations.Add(oper); + } + } + + static NavMeshData InitializeBakeData(NavMeshSurface surface) + { + var emptySources = new List(); + var emptyBounds = new Bounds(); + return UnityEngine.AI.NavMeshBuilder.BuildNavMeshData(surface.GetBuildSettings(), emptySources, emptyBounds + , surface.transform.position, surface.transform.rotation); + } + + void UpdateAsyncBuildOperations() + { + foreach (var oper in m_BakeOperations) + { + if (oper.surface == null || oper.bakeOperation == null) + continue; + + if (oper.bakeOperation.isDone) + { + var surface = oper.surface; + var delete = GetNavMeshAssetToDelete(surface); + if (delete != null) + AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(delete)); + + surface.RemoveData(); + SetNavMeshData(surface, oper.bakeData); + + if (surface.isActiveAndEnabled) + surface.AddData(); + CreateNavMeshAsset(surface); + EditorSceneManager.MarkSceneDirty(surface.gameObject.scene); + } + } + m_BakeOperations.RemoveAll(o => o.bakeOperation == null || o.bakeOperation.isDone); + if (m_BakeOperations.Count == 0) + EditorApplication.update -= UpdateAsyncBuildOperations; + } + + public bool IsSurfaceBaking(NavMeshSurface surface) + { + if (surface == null) + return false; + + foreach (var oper in m_BakeOperations) + { + if (oper.surface == null || oper.bakeOperation == null) + continue; + + if (oper.surface == surface) + return true; + } + + return false; + } + + public void ClearSurfaces(UnityEngine.Object[] surfaces) + { + foreach (NavMeshSurface s in surfaces) + ClearSurface(s); + } + + static void SetNavMeshData(NavMeshSurface navSurface, NavMeshData navMeshData) + { + var so = new SerializedObject(navSurface); + var navMeshDataProperty = so.FindProperty("m_NavMeshData"); + navMeshDataProperty.objectReferenceValue = navMeshData; + so.ApplyModifiedPropertiesWithoutUndo(); + } + + void StoreNavMeshDataIfInPrefab(NavMeshSurface surfaceToStore) + { + var prefabStage = PrefabStageUtility.GetPrefabStage(surfaceToStore.gameObject); + var isPartOfPrefab = prefabStage != null && prefabStage.IsPartOfPrefabContents(surfaceToStore.gameObject); + if (!isPartOfPrefab) + return; + + // check if data has already been stored for this surface + foreach (var storedAssetInfo in m_PrefabNavMeshDataAssets) + if (storedAssetInfo.surface == surfaceToStore) + return; + + if (m_PrefabNavMeshDataAssets.Count == 0) + { + PrefabStage.prefabSaving -= DeleteStoredNavMeshDataAssetsForOwnedSurfaces; + PrefabStage.prefabSaving += DeleteStoredNavMeshDataAssetsForOwnedSurfaces; + + PrefabStage.prefabStageClosing -= ForgetUnsavedNavMeshDataChanges; + PrefabStage.prefabStageClosing += ForgetUnsavedNavMeshDataChanges; + } + + var isDataOwner = true; + if (PrefabUtility.IsPartOfPrefabInstance(surfaceToStore) && !PrefabUtility.IsPartOfModelPrefab(surfaceToStore)) + { + var basePrefabSurface = PrefabUtility.GetCorrespondingObjectFromSource(surfaceToStore) as NavMeshSurface; + isDataOwner = basePrefabSurface == null || surfaceToStore.navMeshData != basePrefabSurface.navMeshData; + } + m_PrefabNavMeshDataAssets.Add(new SavedPrefabNavMeshData { surface = surfaceToStore, navMeshData = isDataOwner ? surfaceToStore.navMeshData : null }); + } + + bool IsCurrentPrefabNavMeshDataStored(NavMeshSurface surface) + { + if (surface == null) + return false; + + foreach (var storedAssetInfo in m_PrefabNavMeshDataAssets) + { + if (storedAssetInfo.surface == surface) + return storedAssetInfo.navMeshData == surface.navMeshData; + } + + return false; + } + + void DeleteStoredNavMeshDataAssetsForOwnedSurfaces(GameObject gameObjectInPrefab) + { + // Debug.LogFormat("DeleteStoredNavMeshDataAsset() when saving prefab {0}", gameObjectInPrefab.name); + + var surfaces = gameObjectInPrefab.GetComponentsInChildren(true); + foreach (var surface in surfaces) + DeleteStoredPrefabNavMeshDataAsset(surface); + } + + void DeleteStoredPrefabNavMeshDataAsset(NavMeshSurface surface) + { + for (var i = m_PrefabNavMeshDataAssets.Count - 1; i >= 0; i--) + { + var storedAssetInfo = m_PrefabNavMeshDataAssets[i]; + if (storedAssetInfo.surface == surface) + { + var storedNavMeshData = storedAssetInfo.navMeshData; + if (storedNavMeshData != null && storedNavMeshData != surface.navMeshData) + { + var assetPath = AssetDatabase.GetAssetPath(storedNavMeshData); + AssetDatabase.DeleteAsset(assetPath); + } + + m_PrefabNavMeshDataAssets.RemoveAt(i); + break; + } + } + + if (m_PrefabNavMeshDataAssets.Count == 0) + { + PrefabStage.prefabSaving -= DeleteStoredNavMeshDataAssetsForOwnedSurfaces; + PrefabStage.prefabStageClosing -= ForgetUnsavedNavMeshDataChanges; + } + } + + void ForgetUnsavedNavMeshDataChanges(PrefabStage prefabStage) + { + // Debug.Log("On prefab closing - forget about this object's surfaces and stop caring about prefab saving"); + + if (prefabStage == null) + return; + + var allSurfacesInPrefab = prefabStage.prefabContentsRoot.GetComponentsInChildren(true); + NavMeshSurface surfaceInPrefab = null; + var index = 0; + do + { + if (allSurfacesInPrefab.Length > 0) + surfaceInPrefab = allSurfacesInPrefab[index]; + + for (var i = m_PrefabNavMeshDataAssets.Count - 1; i >= 0; i--) + { + var storedPrefabInfo = m_PrefabNavMeshDataAssets[i]; + if (storedPrefabInfo.surface == null) + { + // Debug.LogFormat("A surface from the prefab got deleted after it has baked a new NavMesh but it hasn't saved it. Now the unsaved asset gets deleted. ({0})", storedPrefabInfo.navMeshData); + + // surface got deleted, thus delete its initial NavMeshData asset + if (storedPrefabInfo.navMeshData != null) + { + var assetPath = AssetDatabase.GetAssetPath(storedPrefabInfo.navMeshData); + AssetDatabase.DeleteAsset(assetPath); + } + + m_PrefabNavMeshDataAssets.RemoveAt(i); + } + else if (surfaceInPrefab != null && storedPrefabInfo.surface == surfaceInPrefab) + { + //Debug.LogFormat("The surface {0} from the prefab was storing the original navmesh data and now will be forgotten", surfaceInPrefab); + + var baseSurface = PrefabUtility.GetCorrespondingObjectFromSource(surfaceInPrefab) as NavMeshSurface; + if (baseSurface == null || surfaceInPrefab.navMeshData != baseSurface.navMeshData) + { + var assetPath = AssetDatabase.GetAssetPath(surfaceInPrefab.navMeshData); + AssetDatabase.DeleteAsset(assetPath); + + //Debug.LogFormat("The surface {0} from the prefab has baked new NavMeshData but did not save this change so the asset has been now deleted. ({1})", + // surfaceInPrefab, assetPath); + } + + m_PrefabNavMeshDataAssets.RemoveAt(i); + } + } + } while (++index < allSurfacesInPrefab.Length); + + if (m_PrefabNavMeshDataAssets.Count == 0) + { + PrefabStage.prefabSaving -= DeleteStoredNavMeshDataAssetsForOwnedSurfaces; + PrefabStage.prefabStageClosing -= ForgetUnsavedNavMeshDataChanges; + } + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAssetManager.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAssetManager.cs.meta new file mode 100644 index 0000000..80dd8ef --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshAssetManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d969266144f4fb47be21604dd1e7900 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsEditor.asmdef b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsEditor.asmdef new file mode 100644 index 0000000..3aa024e --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsEditor.asmdef @@ -0,0 +1,16 @@ +{ + "name": "NavMeshPlusEditor", + "references": [ + "NavMeshPlus" + ], + "optionalUnityReferences": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [] +} \ No newline at end of file diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsEditor.asmdef.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsEditor.asmdef.meta new file mode 100644 index 0000000..d294c82 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsEditor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a38ed33481bedd74d8c590f5043f49dc +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs new file mode 100644 index 0000000..89da460 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs @@ -0,0 +1,276 @@ +using UnityEditor; +using UnityEditor.AI; +using UnityEngine; +using UnityEngine.AI; + +namespace NavMeshPlus.Components.Editors +{ + public static class NavMeshComponentsGUIUtility + { + public static void AreaPopup(Rect rect, string labelName, SerializedProperty areaProperty) + { + var areaIndex = -1; + var areaNames = NavMesh.GetAreaNames(); + for (var i = 0; i < areaNames.Length; i++) + { + var areaValue = NavMesh.GetAreaFromName(areaNames[i]); + if (areaValue == areaProperty.intValue) + areaIndex = i; + } + ArrayUtility.Add(ref areaNames, ""); + ArrayUtility.Add(ref areaNames, "Open Area Settings..."); + + EditorGUI.BeginProperty(rect, GUIContent.none, areaProperty); + + EditorGUI.BeginChangeCheck(); + areaIndex = EditorGUI.Popup(rect, labelName, areaIndex, areaNames); + + if (EditorGUI.EndChangeCheck()) + { + if (areaIndex >= 0 && areaIndex < areaNames.Length - 2) + areaProperty.intValue = NavMesh.GetAreaFromName(areaNames[areaIndex]); + else if (areaIndex == areaNames.Length - 1) + NavMeshEditorHelpers.OpenAreaSettings(); + } + + EditorGUI.EndProperty(); + } + + public static bool IsAgentSelectionValid(SerializedProperty agentTypeID) + { + var count = NavMesh.GetSettingsCount(); + for (var i = 0; i < count; i++) + { + var id = NavMesh.GetSettingsByIndex(i).agentTypeID; + var name = NavMesh.GetSettingsNameFromID(id); + if (id == agentTypeID.intValue) + return true; + } + return false; + } + + public static void AgentTypePopup(Rect rect, string labelName, SerializedProperty agentTypeID) + { + var index = -1; + var count = NavMesh.GetSettingsCount(); + var agentTypeNames = new string[count + 2]; + for (var i = 0; i < count; i++) + { + var id = NavMesh.GetSettingsByIndex(i).agentTypeID; + var name = NavMesh.GetSettingsNameFromID(id); + agentTypeNames[i] = name; + if (id == agentTypeID.intValue) + index = i; + } + agentTypeNames[count] = ""; + agentTypeNames[count + 1] = "Open Agent Settings..."; + + bool validAgentType = index != -1; + if (!validAgentType) + { + Rect warningRect = rect; + warningRect.height *= .5f; + warningRect.y += warningRect.height; + EditorGUI.HelpBox(warningRect, "Agent Type invalid.", MessageType.Warning); + + rect.height *= .5f; + } + + EditorGUI.BeginProperty(rect, GUIContent.none, agentTypeID); + + EditorGUI.BeginChangeCheck(); + index = EditorGUI.Popup(rect, labelName, index, agentTypeNames); + if (EditorGUI.EndChangeCheck()) + { + if (index >= 0 && index < count) + { + var id = NavMesh.GetSettingsByIndex(index).agentTypeID; + agentTypeID.intValue = id; + } + else if (index == count + 1) + { + NavMeshEditorHelpers.OpenAgentSettings(-1); + } + } + + EditorGUI.EndProperty(); + } + + // Agent mask is a set (internally array/list) of agentTypeIDs. + // It is used to describe which agents modifiers apply to. + // There is a special case of "None" which is an empty array. + // There is a special case of "All" which is an array of length 1, and value of -1. + public static void AgentMaskPopup(string labelName, SerializedProperty agentMask) + { + // Contents of the dropdown box. + string popupContent = ""; + + if (agentMask.hasMultipleDifferentValues) + popupContent = "\u2014"; + else + popupContent = GetAgentMaskLabelName(agentMask); + + var content = new GUIContent(popupContent); + var popupRect = GUILayoutUtility.GetRect(content, EditorStyles.popup); + + EditorGUI.BeginProperty(popupRect, GUIContent.none, agentMask); + popupRect = EditorGUI.PrefixLabel(popupRect, 0, new GUIContent(labelName)); + bool pressed = GUI.Button(popupRect, content, EditorStyles.popup); + + if (pressed) + { + var show = !agentMask.hasMultipleDifferentValues; + var showNone = show && agentMask.arraySize == 0; + var showAll = show && IsAll(agentMask); + + var menu = new GenericMenu(); + menu.AddItem(new GUIContent("None"), showNone, SetAgentMaskNone, agentMask); + menu.AddItem(new GUIContent("All"), showAll, SetAgentMaskAll, agentMask); + menu.AddSeparator(""); + + var count = NavMesh.GetSettingsCount(); + for (var i = 0; i < count; i++) + { + var id = NavMesh.GetSettingsByIndex(i).agentTypeID; + var sname = NavMesh.GetSettingsNameFromID(id); + + var showSelected = show && AgentMaskHasSelectedAgentTypeID(agentMask, id); + var userData = new object[] { agentMask, id, !showSelected }; + menu.AddItem(new GUIContent(sname), showSelected, ToggleAgentMaskItem, userData); + } + + menu.DropDown(popupRect); + } + + EditorGUI.EndProperty(); + } + + public static GameObject CreateAndSelectGameObject(string suggestedName, GameObject parent) + { + var parentTransform = parent != null ? parent.transform : null; + var uniqueName = GameObjectUtility.GetUniqueNameForSibling(parentTransform, suggestedName); + var child = new GameObject(uniqueName); + + Undo.RegisterCreatedObjectUndo(child, "Create " + uniqueName); + if (parentTransform != null) + Undo.SetTransformParent(child.transform, parentTransform, "Parent " + uniqueName); + + Selection.activeGameObject = child; + + return child; + } + + static bool IsAll(SerializedProperty agentMask) + { + return agentMask.arraySize == 1 && agentMask.GetArrayElementAtIndex(0).intValue == -1; + } + + static void ToggleAgentMaskItem(object userData) + { + var args = (object[])userData; + var agentMask = (SerializedProperty)args[0]; + var agentTypeID = (int)args[1]; + var value = (bool)args[2]; + + ToggleAgentMaskItem(agentMask, agentTypeID, value); + } + + static void ToggleAgentMaskItem(SerializedProperty agentMask, int agentTypeID, bool value) + { + if (agentMask.hasMultipleDifferentValues) + { + agentMask.ClearArray(); + agentMask.serializedObject.ApplyModifiedProperties(); + } + + // Find which index this agent type is in the agentMask array. + int idx = -1; + for (var j = 0; j < agentMask.arraySize; j++) + { + var elem = agentMask.GetArrayElementAtIndex(j); + if (elem.intValue == agentTypeID) + idx = j; + } + + // Handle "All" special case. + if (IsAll(agentMask)) + { + agentMask.DeleteArrayElementAtIndex(0); + } + + // Toggle value. + if (value) + { + if (idx == -1) + { + agentMask.InsertArrayElementAtIndex(agentMask.arraySize); + agentMask.GetArrayElementAtIndex(agentMask.arraySize - 1).intValue = agentTypeID; + } + } + else + { + if (idx != -1) + { + agentMask.DeleteArrayElementAtIndex(idx); + } + } + + agentMask.serializedObject.ApplyModifiedProperties(); + } + + static void SetAgentMaskNone(object data) + { + var agentMask = (SerializedProperty)data; + agentMask.ClearArray(); + agentMask.serializedObject.ApplyModifiedProperties(); + } + + static void SetAgentMaskAll(object data) + { + var agentMask = (SerializedProperty)data; + agentMask.ClearArray(); + agentMask.InsertArrayElementAtIndex(0); + agentMask.GetArrayElementAtIndex(0).intValue = -1; + agentMask.serializedObject.ApplyModifiedProperties(); + } + + static string GetAgentMaskLabelName(SerializedProperty agentMask) + { + if (agentMask.arraySize == 0) + return "None"; + + if (IsAll(agentMask)) + return "All"; + + if (agentMask.arraySize <= 3) + { + var labelName = ""; + for (var j = 0; j < agentMask.arraySize; j++) + { + var elem = agentMask.GetArrayElementAtIndex(j); + var settingsName = NavMesh.GetSettingsNameFromID(elem.intValue); + if (string.IsNullOrEmpty(settingsName)) + continue; + + if (labelName.Length > 0) + labelName += ", "; + labelName += settingsName; + } + return labelName; + } + + return "Mixed..."; + } + + static bool AgentMaskHasSelectedAgentTypeID(SerializedProperty agentMask, int agentTypeID) + { + for (var j = 0; j < agentMask.arraySize; j++) + { + var elem = agentMask.GetArrayElementAtIndex(j); + if (elem.intValue == agentTypeID) + return true; + } + return false; + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs.meta new file mode 100644 index 0000000..d02f1fa --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d05c56cb29ad5240bc671605f95db0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshLinkEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshLinkEditor.cs new file mode 100644 index 0000000..d3dab86 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshLinkEditor.cs @@ -0,0 +1,279 @@ +using UnityEditor; +using UnityEngine; + +namespace NavMeshPlus.Components.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(NavMeshLink))] + class NavMeshLinkEditor : Editor + { + SerializedProperty m_AgentTypeID; + SerializedProperty m_Area; + SerializedProperty m_CostModifier; + SerializedProperty m_AutoUpdatePosition; + SerializedProperty m_Bidirectional; + SerializedProperty m_EndPoint; + SerializedProperty m_StartPoint; + SerializedProperty m_Width; + + static int s_SelectedID; + static int s_SelectedPoint = -1; + + static Color s_HandleColor = new Color(255f, 167f, 39f, 210f) / 255; + static Color s_HandleColorDisabled = new Color(255f * 0.75f, 167f * 0.75f, 39f * 0.75f, 100f) / 255; + + void OnEnable() + { + m_AgentTypeID = serializedObject.FindProperty("m_AgentTypeID"); + m_Area = serializedObject.FindProperty("m_Area"); + m_CostModifier = serializedObject.FindProperty("m_CostModifier"); + m_AutoUpdatePosition = serializedObject.FindProperty("m_AutoUpdatePosition"); + m_Bidirectional = serializedObject.FindProperty("m_Bidirectional"); + m_EndPoint = serializedObject.FindProperty("m_EndPoint"); + m_StartPoint = serializedObject.FindProperty("m_StartPoint"); + m_Width = serializedObject.FindProperty("m_Width"); + + s_SelectedID = 0; + s_SelectedPoint = -1; + + + } + + + + static Matrix4x4 UnscaledLocalToWorldMatrix(Transform t) + { + return Matrix4x4.TRS(t.position, t.rotation, Vector3.one); + } + + void AlignTransformToEndPoints(NavMeshLink navLink) + { + var mat = UnscaledLocalToWorldMatrix(navLink.transform); + + var worldStartPt = mat.MultiplyPoint(navLink.startPoint); + var worldEndPt = mat.MultiplyPoint(navLink.endPoint); + + var forward = worldEndPt - worldStartPt; + var up = navLink.transform.up; + + // Flatten + forward -= Vector3.Dot(up, forward) * up; + + var transform = navLink.transform; + transform.rotation = Quaternion.LookRotation(forward, up); + transform.position = (worldEndPt + worldStartPt) * 0.5f; + transform.localScale = Vector3.one; + + navLink.startPoint = transform.InverseTransformPoint(worldStartPt); + navLink.endPoint = transform.InverseTransformPoint(worldEndPt); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_AgentTypeID); + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_StartPoint); + EditorGUILayout.PropertyField(m_EndPoint); + + GUILayout.BeginHorizontal(); + GUILayout.Space(EditorGUIUtility.labelWidth); + if (GUILayout.Button("Swap")) + { + foreach (NavMeshLink navLink in targets) + { + var tmp = navLink.startPoint; + navLink.startPoint = navLink.endPoint; + navLink.endPoint = tmp; + } + SceneView.RepaintAll(); + } + if (GUILayout.Button("Align Transform")) + { + foreach (NavMeshLink navLink in targets) + { + Undo.RecordObject(navLink.transform, "Align Transform to End Points"); + Undo.RecordObject(navLink, "Align Transform to End Points"); + AlignTransformToEndPoints(navLink); + } + SceneView.RepaintAll(); + } + GUILayout.EndHorizontal(); + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_Width); + EditorGUILayout.PropertyField(m_CostModifier); + EditorGUILayout.PropertyField(m_AutoUpdatePosition); + EditorGUILayout.PropertyField(m_Bidirectional); + EditorGUILayout.PropertyField(m_Area); + + serializedObject.ApplyModifiedProperties(); + + EditorGUILayout.Space(); + } + + static Vector3 CalcLinkRight(NavMeshLink navLink) + { + var dir = navLink.endPoint - navLink.startPoint; + return (new Vector3(-dir.z, 0.0f, dir.x)).normalized; + } + + static void DrawLink(NavMeshLink navLink) + { + var right = CalcLinkRight(navLink); + var rad = navLink.width * 0.5f; + + Gizmos.DrawLine(navLink.startPoint - right * rad, navLink.startPoint + right * rad); + Gizmos.DrawLine(navLink.endPoint - right * rad, navLink.endPoint + right * rad); + Gizmos.DrawLine(navLink.startPoint - right * rad, navLink.endPoint - right * rad); + Gizmos.DrawLine(navLink.startPoint + right * rad, navLink.endPoint + right * rad); + } + + + [DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.Active | GizmoType.Pickable)] + + static void RenderBoxGizmo(NavMeshLink navLink, GizmoType gizmoType) + { + if (!EditorApplication.isPlaying && navLink.isActiveAndEnabled) + navLink.UpdateLink(); + + var color = s_HandleColor; + if (!navLink.enabled) + color = s_HandleColorDisabled; + + var oldColor = Gizmos.color; + var oldMatrix = Gizmos.matrix; + + Gizmos.matrix = UnscaledLocalToWorldMatrix(navLink.transform); + + Gizmos.color = color; + DrawLink(navLink); + + Gizmos.matrix = oldMatrix; + Gizmos.color = oldColor; + + Gizmos.DrawIcon(navLink.transform.position, "NavMeshLink Icon", true); + } + + [DrawGizmo(GizmoType.NotInSelectionHierarchy | GizmoType.Pickable)] + static void RenderBoxGizmoNotSelected(NavMeshLink navLink, GizmoType gizmoType) + { + if (!EditorApplication.isPlaying && navLink.isActiveAndEnabled) + navLink.UpdateLink(); + + { + var color = s_HandleColor; + if (!navLink.enabled) + color = s_HandleColorDisabled; + + var oldColor = Gizmos.color; + var oldMatrix = Gizmos.matrix; + + Gizmos.matrix = UnscaledLocalToWorldMatrix(navLink.transform); + + Gizmos.color = color; + DrawLink(navLink); + + Gizmos.matrix = oldMatrix; + Gizmos.color = oldColor; + } + + Gizmos.DrawIcon(navLink.transform.position, "NavMeshLink Icon", true); + } + + public void OnSceneGUI() + { + var navLink = (NavMeshLink)target; + if (!navLink.enabled) + return; + + var mat = UnscaledLocalToWorldMatrix(navLink.transform); + + var startPt = mat.MultiplyPoint(navLink.startPoint); + var endPt = mat.MultiplyPoint(navLink.endPoint); + var midPt = Vector3.Lerp(startPt, endPt, 0.35f); + var startSize = HandleUtility.GetHandleSize(startPt); + var endSize = HandleUtility.GetHandleSize(endPt); + var midSize = HandleUtility.GetHandleSize(midPt); + + var zup = Quaternion.FromToRotation(Vector3.forward, Vector3.up); + var right = mat.MultiplyVector(CalcLinkRight(navLink)); + + var oldColor = Handles.color; + Handles.color = s_HandleColor; + + Vector3 pos; + + if (navLink.GetInstanceID() == s_SelectedID && s_SelectedPoint == 0) + { + EditorGUI.BeginChangeCheck(); + Handles.CubeHandleCap(0, startPt, zup, 0.1f * startSize, Event.current.type); + pos = Handles.PositionHandle(startPt, navLink.transform.rotation); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(navLink, "Move link point"); + navLink.startPoint = mat.inverse.MultiplyPoint(pos); + } + } + else + { + if (Handles.Button(startPt, zup, 0.1f * startSize, 0.1f * startSize, Handles.CubeHandleCap)) + { + s_SelectedPoint = 0; + s_SelectedID = navLink.GetInstanceID(); + } + } + + if (navLink.GetInstanceID() == s_SelectedID && s_SelectedPoint == 1) + { + EditorGUI.BeginChangeCheck(); + Handles.CubeHandleCap(0, endPt, zup, 0.1f * startSize, Event.current.type); + pos = Handles.PositionHandle(endPt, navLink.transform.rotation); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(navLink, "Move link point"); + navLink.endPoint = mat.inverse.MultiplyPoint(pos); + } + } + else + { + if (Handles.Button(endPt, zup, 0.1f * endSize, 0.1f * endSize, Handles.CubeHandleCap)) + { + s_SelectedPoint = 1; + s_SelectedID = navLink.GetInstanceID(); + } + } + + EditorGUI.BeginChangeCheck(); + pos = Handles.Slider(midPt + right * navLink.width * 0.5f, right, midSize * 0.03f, Handles.DotHandleCap, 0); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(navLink, "Adjust link width"); + navLink.width = Mathf.Max(0.0f, 2.0f * Vector3.Dot(right, (pos - midPt))); + } + + EditorGUI.BeginChangeCheck(); + pos = Handles.Slider(midPt - right * navLink.width * 0.5f, -right, midSize * 0.03f, Handles.DotHandleCap, 0); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(navLink, "Adjust link width"); + navLink.width = Mathf.Max(0.0f, 2.0f * Vector3.Dot(-right, (pos - midPt))); + } + + Handles.color = oldColor; + } + + [MenuItem("GameObject/Navigation/NavMesh Link", false, 2002)] + public static void CreateNavMeshLink(MenuCommand menuCommand) + { + var parent = menuCommand.context as GameObject; + GameObject go = NavMeshComponentsGUIUtility.CreateAndSelectGameObject("NavMesh Link", parent); + go.AddComponent(); + var view = SceneView.lastActiveSceneView; + if (view != null) + view.MoveToView(go.transform); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshLinkEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshLinkEditor.cs.meta new file mode 100644 index 0000000..e07e698 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshLinkEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 03832abc07e3394479eec5708b22e984 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierEditor.cs new file mode 100644 index 0000000..5125896 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierEditor.cs @@ -0,0 +1,46 @@ +using UnityEditor; + +namespace NavMeshPlus.Components.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(NavMeshModifier))] + class NavMeshModifierEditor : Editor + { + SerializedProperty m_AffectedAgents; + SerializedProperty m_Area; + SerializedProperty m_IgnoreFromBuild; + SerializedProperty m_OverrideArea; + + void OnEnable() + { + m_AffectedAgents = serializedObject.FindProperty("m_AffectedAgents"); + m_Area = serializedObject.FindProperty("m_Area"); + m_IgnoreFromBuild = serializedObject.FindProperty("m_IgnoreFromBuild"); + m_OverrideArea = serializedObject.FindProperty("m_OverrideArea"); + + + } + + + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_IgnoreFromBuild); + + EditorGUILayout.PropertyField(m_OverrideArea); + if (m_OverrideArea.boolValue) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_Area); + EditorGUI.indentLevel--; + } + + NavMeshComponentsGUIUtility.AgentMaskPopup("Affected Agents", m_AffectedAgents); + EditorGUILayout.Space(); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierEditor.cs.meta new file mode 100644 index 0000000..6eebccb --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8fce3c13f011874d92d75ca24a90702 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierTilemapEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierTilemapEditor.cs new file mode 100644 index 0000000..0da4732 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierTilemapEditor.cs @@ -0,0 +1,198 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEngine.Tilemaps; + +//*********************************************************************************** +// Contributed by author jl-randazzo github.com/jl-randazzo +//*********************************************************************************** +namespace NavMeshPlus.Components.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(NavMeshModifierTilemap))] + class NavMeshModifierTilemapEditor : Editor + { + SerializedProperty m_AffectedAgents; + SerializedProperty m_TileModifiers; + + void OnEnable() + { + m_AffectedAgents = serializedObject.FindProperty("m_AffectedAgents"); + m_TileModifiers = serializedObject.FindProperty("m_TileModifiers"); + } + + public override void OnInspectorGUI() + { + NavMeshModifierTilemap modifierTilemap = target as NavMeshModifierTilemap; + + serializedObject.Update(); + + NavMeshComponentsGUIUtility.AgentMaskPopup("Affected Agents", m_AffectedAgents); + + EditorGUILayout.PropertyField(m_TileModifiers); + + if (modifierTilemap.HasDuplicateTileModifiers()) + { + EditorGUILayout.HelpBox("There are duplicate Tile entries in the tilemap modifiers! Only the first will be used.", MessageType.Warning); + } + + EditorGUILayout.Space(); + + Tilemap tilemap = modifierTilemap.GetComponent(); + if (tilemap) + { + if (GUILayout.Button("Add Used Tiles")) + { + AddUsedTiles(tilemap, modifierTilemap); + } + } + else + { + EditorGUILayout.HelpBox("Missing required component 'Tilemap'", MessageType.Error); + } + + if (serializedObject.ApplyModifiedProperties()) + { + modifierTilemap.CacheModifiers(); + } + } + + private void AddUsedTiles(Tilemap tilemap, NavMeshModifierTilemap modifierTilemap) + { + Dictionary tileModifiers = modifierTilemap.GetModifierMap(); + + BoundsInt bounds = tilemap.cellBounds; + for (int i = bounds.xMin; i <= bounds.xMax; i++) + { + for (int j = bounds.yMin; j <= bounds.yMax; j++) + { + for (int k = bounds.zMin; k <= bounds.zMax; k++) + { + if (tilemap.GetTile(new Vector3Int(i, j, k)) is TileBase tileBase) + { + if (!tileModifiers.ContainsKey(tileBase)) + { + tileModifiers.Add(tileBase, new NavMeshModifierTilemap.TileModifier()); + + int idx = m_TileModifiers.arraySize; + m_TileModifiers.InsertArrayElementAtIndex(idx); + var newElem = m_TileModifiers.GetArrayElementAtIndex(idx); + var tileProperty = newElem.FindPropertyRelative(nameof(NavMeshModifierTilemap.TileModifier.tile)); + tileProperty.objectReferenceValue = tileBase; + } + } + } + } + } + } + + [CustomPropertyDrawer(typeof(NavMeshModifierTilemap.TileModifier))] + class TileModifierPropertyDrawer : PropertyDrawer + { + + private static Dictionary Previews; + + private Rect ClaimAdvance(ref Rect position, float height) + { + Rect retVal = position; + retVal.height = height; + position.y += height; + position.height -= height; + return retVal; + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + Rect expandRect = ClaimAdvance(ref position, 20); + property.isExpanded = EditorGUI.Foldout(expandRect, property.isExpanded, label); + if (property.isExpanded) + { + var tileProperty = property.FindPropertyRelative(nameof(NavMeshModifierTilemap.TileModifier.tile)); + Rect tileRect = ClaimAdvance(ref position, 40); + tileRect.width -= 40; + + Rect previewRect = tileRect; + previewRect.width = 40; + previewRect.x += tileRect.width; + tileRect.height /= 2; + + // Adding the tile selector and a preview image. + EditorGUI.PropertyField(tileRect, tileProperty); + TileBase tileBase = tileProperty.objectReferenceValue as TileBase; + TileData tileData = new TileData(); + Texture textureToDraw; + try + { + tileBase?.GetTileData(Vector3Int.zero, null, ref tileData); + textureToDraw = tileData.sprite?.texture; + } + catch + { + try + { + + textureToDraw = GetPreview(tileBase); + } + catch + { + textureToDraw = EditorGUIUtility.IconContent("console.erroricon.sml").image; + } + } + + if (textureToDraw) + { + EditorGUI.DrawPreviewTexture(previewRect, textureToDraw, null, ScaleMode.ScaleToFit, 0); + } + + Rect toggleRect = ClaimAdvance(ref position, 20); + var overrideAreaProperty = property.FindPropertyRelative(nameof(NavMeshModifierTilemap.TileModifier.overrideArea)); + EditorGUI.PropertyField(toggleRect, overrideAreaProperty); + + if (overrideAreaProperty.boolValue) + { + Rect areaRect = ClaimAdvance(ref position, 20); + var areaProperty = property.FindPropertyRelative(nameof(NavMeshModifierTilemap.TileModifier.area)); + EditorGUI.indentLevel++; + EditorGUI.PropertyField(areaRect, areaProperty); + EditorGUI.indentLevel--; + } + } + } + + static Texture2D GetPreview(Object objectToPreview) + { + int maxResolution = 128; + Previews ??= new Dictionary(); + if (!Previews.TryGetValue(objectToPreview, out var preview) || preview == null) + { + var path = AssetDatabase.GetAssetPath(objectToPreview); + if (objectToPreview) + { + var editor = CreateEditor(objectToPreview); + preview = editor.RenderStaticPreview(path, null, maxResolution, maxResolution); + preview.Apply(); + DestroyImmediate(editor); + Previews[objectToPreview] = preview; + } + } + + return preview; + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + if (property.isExpanded) + { + var overrideAreaProperty = property.FindPropertyRelative(nameof(NavMeshModifierTilemap.TileModifier.overrideArea)); + if (overrideAreaProperty.boolValue) + { + return 100; + } + return 80; + } + return 20; + + } + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierTilemapEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierTilemapEditor.cs.meta new file mode 100644 index 0000000..f4c890a --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierTilemapEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1fa3ed80a7c8401995efba10b64226e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs new file mode 100644 index 0000000..b1df610 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs @@ -0,0 +1,137 @@ +using UnityEditor.IMGUI.Controls; +using UnityEditorInternal; +using UnityEngine; +using UnityEditor; + +namespace NavMeshPlus.Components.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(NavMeshModifierVolume))] + class NavMeshModifierVolumeEditor : Editor + { + SerializedProperty m_AffectedAgents; + SerializedProperty m_Area; + SerializedProperty m_Center; + SerializedProperty m_Size; + + static Color s_HandleColor = new Color(187f, 138f, 240f, 210f) / 255; + static Color s_HandleColorDisabled = new Color(187f * 0.75f, 138f * 0.75f, 240f * 0.75f, 100f) / 255; + + BoxBoundsHandle m_BoundsHandle = new BoxBoundsHandle(); + + bool editingCollider + { + get { return EditMode.editMode == EditMode.SceneViewEditMode.Collider && EditMode.IsOwner(this); } + } + + void OnEnable() + { + m_AffectedAgents = serializedObject.FindProperty("m_AffectedAgents"); + m_Area = serializedObject.FindProperty("m_Area"); + m_Center = serializedObject.FindProperty("m_Center"); + m_Size = serializedObject.FindProperty("m_Size"); } + + Bounds GetBounds() + { + var navModifier = (NavMeshModifierVolume)target; + return new Bounds(navModifier.transform.position, navModifier.size); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditMode.DoEditModeInspectorModeButton(EditMode.SceneViewEditMode.Collider, "Edit Volume", + EditorGUIUtility.IconContent("EditCollider"), GetBounds, this); + + EditorGUILayout.PropertyField(m_Size); + EditorGUILayout.PropertyField(m_Center); + EditorGUILayout.PropertyField(m_Area); + NavMeshComponentsGUIUtility.AgentMaskPopup("Affected Agents", m_AffectedAgents); + EditorGUILayout.Space(); + + serializedObject.ApplyModifiedProperties(); + } + + + [DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.Active)] + static void RenderBoxGizmo(NavMeshModifierVolume navModifier, GizmoType gizmoType) + { + var color = navModifier.enabled ? s_HandleColor : s_HandleColorDisabled; + var colorTrans = new Color(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, color.a * 0.15f); + + var oldColor = Gizmos.color; + var oldMatrix = Gizmos.matrix; + + Gizmos.matrix = navModifier.transform.localToWorldMatrix; + + Gizmos.color = colorTrans; + Gizmos.DrawCube(navModifier.center, navModifier.size); + + Gizmos.color = color; + Gizmos.DrawWireCube(navModifier.center, navModifier.size); + + Gizmos.matrix = oldMatrix; + Gizmos.color = oldColor; + + Gizmos.DrawIcon(navModifier.transform.position, "NavMeshModifierVolume Icon", true); + } + + [DrawGizmo(GizmoType.NotInSelectionHierarchy | GizmoType.Pickable)] + static void RenderBoxGizmoNotSelected(NavMeshModifierVolume navModifier, GizmoType gizmoType) + { + { + var color = navModifier.enabled ? s_HandleColor : s_HandleColorDisabled; + var oldColor = Gizmos.color; + var oldMatrix = Gizmos.matrix; + + Gizmos.matrix = navModifier.transform.localToWorldMatrix; + + Gizmos.color = color; + Gizmos.DrawWireCube(navModifier.center, navModifier.size); + + Gizmos.matrix = oldMatrix; + Gizmos.color = oldColor; + } + + Gizmos.DrawIcon(navModifier.transform.position, "NavMeshModifierVolume Icon", true); + } + + void OnSceneGUI() + { + if (!editingCollider) + return; + + var vol = (NavMeshModifierVolume)target; + var color = vol.enabled ? s_HandleColor : s_HandleColorDisabled; + using (new Handles.DrawingScope(color, vol.transform.localToWorldMatrix)) + { + m_BoundsHandle.center = vol.center; + m_BoundsHandle.size = vol.size; + + EditorGUI.BeginChangeCheck(); + m_BoundsHandle.DrawHandle(); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(vol, "Modified NavMesh Modifier Volume"); + Vector3 center = m_BoundsHandle.center; + Vector3 size = m_BoundsHandle.size; + vol.center = center; + vol.size = size; + EditorUtility.SetDirty(target); + } + } + } + + [MenuItem("GameObject/Navigation/NavMesh Modifier Volume", false, 2001)] + static public void CreateNavMeshModifierVolume(MenuCommand menuCommand) + { + var parent = menuCommand.context as GameObject; + var go = NavMeshComponentsGUIUtility.CreateAndSelectGameObject("NavMesh Modifier Volume", parent); + go.AddComponent(); + var view = SceneView.lastActiveSceneView; + if (view != null) + view.MoveToView(go.transform); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs.meta new file mode 100644 index 0000000..c8212e5 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5999826ec8e37f74a80d7f6ee2700a3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs new file mode 100644 index 0000000..bb21aa7 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs @@ -0,0 +1,428 @@ +#define NAVMESHCOMPONENTS_SHOW_NAVMESHDATA_REF + +using System.Linq; +using UnityEditor.IMGUI.Controls; +using UnityEditorInternal; +using UnityEngine.AI; +using UnityEngine; +using UnityEditor; +using UnityEditor.AI; +using System.Reflection; + +namespace NavMeshPlus.Components.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(NavMeshSurface))] + class NavMeshSurfaceEditor : Editor + { + SerializedProperty m_AgentTypeID; + SerializedProperty m_BuildHeightMesh; + SerializedProperty m_Center; + SerializedProperty m_CollectObjects; + SerializedProperty m_DefaultArea; + SerializedProperty m_LayerMask; + SerializedProperty m_OverrideTileSize; + SerializedProperty m_OverrideVoxelSize; + SerializedProperty m_Size; + SerializedProperty m_TileSize; + SerializedProperty m_UseGeometry; + SerializedProperty m_VoxelSize; + SerializedProperty m_MinRegionArea; + SerializedProperty m_HideEditorLogs; + +#if NAVMESHCOMPONENTS_SHOW_NAVMESHDATA_REF + SerializedProperty m_NavMeshData; +#endif + class Styles + { + public readonly GUIContent m_LayerMask = new GUIContent("Include Layers"); + public readonly GUIContent m_MinRegionArea = new GUIContent("Minimum Region Area"); + public readonly GUIContent m_ShowInputGeom = new GUIContent("Show Input Geom"); + public readonly GUIContent m_ShowVoxels = new GUIContent("Show Voxels"); + public readonly GUIContent m_ShowRegions = new GUIContent("Show Regions"); + public readonly GUIContent m_ShowRawContours = new GUIContent("Show Raw Contours"); + public readonly GUIContent m_ShowContours = new GUIContent("Show Contours"); + public readonly GUIContent m_ShowPolyMesh = new GUIContent("Show Poly Mesh"); + public readonly GUIContent m_ShowPolyMeshDetail = new GUIContent("Show Poly Mesh Detail"); + } + + static Styles s_Styles; + + static bool s_ShowDebugOptions; + + static Color s_HandleColor = new Color(127f, 214f, 244f, 100f) / 255; + static Color s_HandleColorSelected = new Color(127f, 214f, 244f, 210f) / 255; + static Color s_HandleColorDisabled = new Color(127f * 0.75f, 214f * 0.75f, 244f * 0.75f, 100f) / 255; + + BoxBoundsHandle m_BoundsHandle = new BoxBoundsHandle(); + + bool editingCollider + { + get { return EditMode.editMode == EditMode.SceneViewEditMode.Collider && EditMode.IsOwner(this); } + } + + void OnEnable() + { + m_AgentTypeID = serializedObject.FindProperty("m_AgentTypeID"); + m_BuildHeightMesh = serializedObject.FindProperty("m_BuildHeightMesh"); + m_Center = serializedObject.FindProperty("m_Center"); + m_CollectObjects = serializedObject.FindProperty("m_CollectObjects"); + m_DefaultArea = serializedObject.FindProperty("m_DefaultArea"); + m_LayerMask = serializedObject.FindProperty("m_LayerMask"); + m_OverrideTileSize = serializedObject.FindProperty("m_OverrideTileSize"); + m_OverrideVoxelSize = serializedObject.FindProperty("m_OverrideVoxelSize"); + m_Size = serializedObject.FindProperty("m_Size"); + m_TileSize = serializedObject.FindProperty("m_TileSize"); + m_UseGeometry = serializedObject.FindProperty("m_UseGeometry"); + m_VoxelSize = serializedObject.FindProperty("m_VoxelSize"); + m_MinRegionArea = serializedObject.FindProperty("m_MinRegionArea"); + m_HideEditorLogs = serializedObject.FindProperty("m_HideEditorLogs"); + +#if NAVMESHCOMPONENTS_SHOW_NAVMESHDATA_REF + m_NavMeshData = serializedObject.FindProperty("m_NavMeshData"); +#endif + +#if !UNITY_2022_2_OR_NEWER + NavMeshVisualizationSettings.showNavigation++; +#endif + } + +#if !UNITY_2022_2_OR_NEWER + void OnDisable() + { + NavMeshVisualizationSettings.showNavigation--; + } +#endif + + Bounds GetBounds() + { + var navSurface = (NavMeshSurface)target; + return new Bounds(navSurface.transform.position, navSurface.size); + } + + public override void OnInspectorGUI() + { + if (s_Styles == null) + s_Styles = new Styles(); + + serializedObject.Update(); + + var bs = NavMesh.GetSettingsByID(m_AgentTypeID.intValue); + + if (bs.agentTypeID != -1) + { + // Draw image + const float diagramHeight = 80.0f; + Rect agentDiagramRect = EditorGUILayout.GetControlRect(false, diagramHeight); + NavMeshEditorHelpers.DrawAgentDiagram(agentDiagramRect, bs.agentRadius, bs.agentHeight, bs.agentClimb, bs.agentSlope); + } + + EditorGUILayout.PropertyField(m_AgentTypeID); + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_CollectObjects); + if ((CollectObjects)m_CollectObjects.enumValueIndex == CollectObjects.Volume) + { + EditorGUI.indentLevel++; + + EditMode.DoEditModeInspectorModeButton(EditMode.SceneViewEditMode.Collider, "Edit Volume", + EditorGUIUtility.IconContent("EditCollider"), GetBounds, this); + EditorGUILayout.PropertyField(m_Size); + EditorGUILayout.PropertyField(m_Center); + + EditorGUI.indentLevel--; + } + else + { + if (editingCollider) + EditMode.QuitEditMode(); + } + + EditorGUILayout.PropertyField(m_LayerMask, s_Styles.m_LayerMask); + EditorGUILayout.PropertyField(m_UseGeometry); + + EditorGUILayout.Space(); + + m_OverrideVoxelSize.isExpanded = EditorGUILayout.Foldout(m_OverrideVoxelSize.isExpanded, "Advanced"); + if (m_OverrideVoxelSize.isExpanded) + { + EditorGUI.indentLevel++; + + EditorGUILayout.PropertyField(m_DefaultArea); + + // Override voxel size. + EditorGUILayout.PropertyField(m_OverrideVoxelSize); + + using (new EditorGUI.DisabledScope(!m_OverrideVoxelSize.boolValue || m_OverrideVoxelSize.hasMultipleDifferentValues)) + { + EditorGUI.indentLevel++; + + EditorGUILayout.PropertyField(m_VoxelSize); + + if (!m_OverrideVoxelSize.hasMultipleDifferentValues) + { + if (!m_AgentTypeID.hasMultipleDifferentValues) + { + float voxelsPerRadius = m_VoxelSize.floatValue > 0.0f ? (bs.agentRadius / m_VoxelSize.floatValue) : 0.0f; + EditorGUILayout.LabelField(" ", voxelsPerRadius.ToString("0.00") + " voxels per agent radius", EditorStyles.miniLabel); + } + if (m_OverrideVoxelSize.boolValue) + EditorGUILayout.HelpBox("Voxel size controls how accurately the navigation mesh is generated from the level geometry. A good voxel size is 2-4 voxels per agent radius. Making voxel size smaller will increase build time.", MessageType.None); + } + EditorGUI.indentLevel--; + } + + // Override tile size + EditorGUILayout.PropertyField(m_OverrideTileSize); + + using (new EditorGUI.DisabledScope(!m_OverrideTileSize.boolValue || m_OverrideTileSize.hasMultipleDifferentValues)) + { + EditorGUI.indentLevel++; + + EditorGUILayout.PropertyField(m_TileSize); + + if (!m_TileSize.hasMultipleDifferentValues && !m_VoxelSize.hasMultipleDifferentValues) + { + float tileWorldSize = m_TileSize.intValue * m_VoxelSize.floatValue; + EditorGUILayout.LabelField(" ", tileWorldSize.ToString("0.00") + " world units", EditorStyles.miniLabel); + } + + if (!m_OverrideTileSize.hasMultipleDifferentValues) + { + if (m_OverrideTileSize.boolValue) + EditorGUILayout.HelpBox("Tile size controls the how local the changes to the world are (rebuild or carve). Small tile size allows more local changes, while potentially generating more data overall.", MessageType.None); + } + EditorGUI.indentLevel--; + } + + EditorGUILayout.PropertyField(m_MinRegionArea, s_Styles.m_MinRegionArea); + + // Height mesh + using (new EditorGUI.DisabledScope(true)) + { + EditorGUILayout.PropertyField(m_BuildHeightMesh); + } + + EditorGUILayout.PropertyField(m_HideEditorLogs); + + EditorGUILayout.Space(); + EditorGUI.indentLevel--; + } + + EditorGUILayout.Space(); + + serializedObject.ApplyModifiedProperties(); + + var hadError = false; + var multipleTargets = targets.Length > 1; + foreach (NavMeshSurface navSurface in targets) + { + var settings = navSurface.GetBuildSettings(); + // Calculating bounds is potentially expensive when unbounded - so here we just use the center/size. + // It means the validation is not checking vertical voxel limit correctly when the surface is set to something else than "in volume". + var bounds = new Bounds(Vector3.zero, Vector3.zero); + if (navSurface.collectObjects == CollectObjects.Volume) + { + bounds = new Bounds(navSurface.center, navSurface.size); + } + + var errors = settings.ValidationReport(bounds); + if (errors.Length > 0) + { + if (multipleTargets) + EditorGUILayout.LabelField(navSurface.name); + foreach (var err in errors) + { + EditorGUILayout.HelpBox(err, MessageType.Warning); + } + GUILayout.BeginHorizontal(); + GUILayout.Space(EditorGUIUtility.labelWidth); + if (GUILayout.Button("Open Agent Settings...", EditorStyles.miniButton)) + NavMeshEditorHelpers.OpenAgentSettings(navSurface.agentTypeID); + GUILayout.EndHorizontal(); + hadError = true; + } + } + + if (hadError) + EditorGUILayout.Space(); + +#if NAVMESHCOMPONENTS_SHOW_NAVMESHDATA_REF + var nmdRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); + + EditorGUI.BeginProperty(nmdRect, GUIContent.none, m_NavMeshData); + var rectLabel = EditorGUI.PrefixLabel(nmdRect, GUIUtility.GetControlID(FocusType.Passive), new GUIContent(m_NavMeshData.displayName)); + EditorGUI.EndProperty(); + + using (new EditorGUI.DisabledScope(true)) + { + EditorGUI.BeginProperty(nmdRect, GUIContent.none, m_NavMeshData); + EditorGUI.ObjectField(rectLabel, m_NavMeshData, GUIContent.none); + EditorGUI.EndProperty(); + } +#endif + using (new EditorGUI.DisabledScope(Application.isPlaying || m_AgentTypeID.intValue == -1)) + { + GUILayout.BeginHorizontal(); + GUILayout.Space(EditorGUIUtility.labelWidth); + if (GUILayout.Button("Clear")) + { + NavMeshAssetManager.instance.ClearSurfaces(targets); + SceneView.RepaintAll(); + } + + if (GUILayout.Button("Bake")) + { + NavMeshAssetManager.instance.StartBakingSurfaces(targets); + } + + GUILayout.EndHorizontal(); + } + + // Show progress for the selected targets + var bakeOperations = NavMeshAssetManager.instance.GetBakeOperations(); + for (int i = bakeOperations.Count - 1; i >= 0; --i) + { + if (!targets.Contains(bakeOperations[i].surface)) + continue; + + var oper = bakeOperations[i].bakeOperation; + if (oper == null) + continue; + + var p = oper.progress; + if (oper.isDone) + { + SceneView.RepaintAll(); + continue; + } + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button("Cancel", EditorStyles.miniButton)) + { + var bakeData = bakeOperations[i].bakeData; + UnityEngine.AI.NavMeshBuilder.Cancel(bakeData); + bakeOperations.RemoveAt(i); + } + + EditorGUI.ProgressBar(EditorGUILayout.GetControlRect(), p, "Baking: " + (int)(100 * p) + "%"); + if (p <= 1) + Repaint(); + + GUILayout.EndHorizontal(); + } + } + +#if UNITY_2022_2_OR_NEWER + [DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.Active | GizmoType.Pickable)] + static void RenderGizmoSelected(NavMeshSurface navSurface, GizmoType gizmoType) + { + //navSurface.navMeshDataInstance.FlagAsInSelectionHierarchy(); + var method = navSurface.navMeshDataInstance.GetType().GetMethod("FlagAsInSelectionHierarchy", BindingFlags.NonPublic | BindingFlags.Instance); + method.Invoke(navSurface.navMeshDataInstance, null); + RenderBoxGizmo(navSurface, gizmoType, true); + } + + [DrawGizmo(GizmoType.NotInSelectionHierarchy | GizmoType.Pickable)] + static void RenderGizmoNotSelected(NavMeshSurface navSurface, GizmoType gizmoType) + { + RenderBoxGizmo(navSurface, gizmoType, false); + } +#else + [DrawGizmo(GizmoType.Selected | GizmoType.Active | GizmoType.Pickable)] + static void RenderBoxGizmoSelected(NavMeshSurface navSurface, GizmoType gizmoType) + { + RenderBoxGizmo(navSurface, gizmoType, true); + } + + [DrawGizmo(GizmoType.NotInSelectionHierarchy | GizmoType.Pickable)] + static void RenderBoxGizmoNotSelected(NavMeshSurface navSurface, GizmoType gizmoType) + { + if (NavMeshVisualizationSettings.showNavigation > 0) + RenderBoxGizmo(navSurface, gizmoType, false); + else + Gizmos.DrawIcon(navSurface.transform.position, "NavMeshSurface Icon", true); + } +#endif + + static void RenderBoxGizmo(NavMeshSurface navSurface, GizmoType gizmoType, bool selected) + { + var color = selected ? s_HandleColorSelected : s_HandleColor; + if (!navSurface.enabled) + color = s_HandleColorDisabled; + + var oldColor = Gizmos.color; + var oldMatrix = Gizmos.matrix; + + // Use the unscaled matrix for the NavMeshSurface + var localToWorld = Matrix4x4.TRS(navSurface.transform.position, navSurface.transform.rotation, Vector3.one); + Gizmos.matrix = localToWorld; + + if (navSurface.collectObjects == CollectObjects.Volume) + { + Gizmos.color = color; + Gizmos.DrawWireCube(navSurface.center, navSurface.size); + + if (selected && navSurface.enabled) + { + var colorTrans = new Color(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, color.a * 0.15f); + Gizmos.color = colorTrans; + Gizmos.DrawCube(navSurface.center, navSurface.size); + } + } + else + { + if (navSurface.navMeshData != null) + { + var bounds = navSurface.navMeshData.sourceBounds; + Gizmos.color = Color.grey; + Gizmos.DrawWireCube(bounds.center, bounds.size); + } + } + + Gizmos.matrix = oldMatrix; + Gizmos.color = oldColor; + + Gizmos.DrawIcon(navSurface.transform.position, "NavMeshSurface Icon", true); + } + + void OnSceneGUI() + { + if (!editingCollider) + return; + + var navSurface = (NavMeshSurface)target; + var color = navSurface.enabled ? s_HandleColor : s_HandleColorDisabled; + var localToWorld = Matrix4x4.TRS(navSurface.transform.position, navSurface.transform.rotation, Vector3.one); + using (new Handles.DrawingScope(color, localToWorld)) + { + m_BoundsHandle.center = navSurface.center; + m_BoundsHandle.size = navSurface.size; + + EditorGUI.BeginChangeCheck(); + m_BoundsHandle.DrawHandle(); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(navSurface, "Modified NavMesh Surface"); + Vector3 center = m_BoundsHandle.center; + Vector3 size = m_BoundsHandle.size; + navSurface.center = center; + navSurface.size = size; + EditorUtility.SetDirty(target); + } + } + } + + [MenuItem("GameObject/Navigation/NavMesh Surface", false, 2000)] + public static void CreateNavMeshSurface(MenuCommand menuCommand) + { + var parent = menuCommand.context as GameObject; + var go = NavMeshComponentsGUIUtility.CreateAndSelectGameObject("NavMesh Surface", parent); + go.AddComponent(); + var view = SceneView.lastActiveSceneView; + if (view != null) + view.MoveToView(go.transform); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs.meta new file mode 100644 index 0000000..d3e5f2e --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a7b2ae8284a9b14abd6d688cc877cef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/RootSources2dEditor.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/RootSources2dEditor.cs new file mode 100644 index 0000000..79498e9 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/RootSources2dEditor.cs @@ -0,0 +1,36 @@ +using UnityEditor; +using NavMeshPlus.Components; + +namespace NavMeshPlus.Extensions.Editors +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(RootSources2d))] + internal class RootSources2dEditor: Editor + { + SerializedProperty _rootSources; + void OnEnable() + { + _rootSources = serializedObject.FindProperty("_rootSources"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + var surf = target as RootSources2d; + EditorGUILayout.HelpBox("Add GameObjects to create NavMesh form it and it's ancestors", MessageType.Info); + + if (surf.NavMeshSurfaceOwner.collectObjects != CollectObjects.Children) + { + EditorGUILayout.Space(); + EditorGUILayout.HelpBox("Root Sources are only suitable for 'CollectObjects - Children'", MessageType.Info); + EditorGUILayout.Space(); + + } + EditorGUILayout.PropertyField(_rootSources); + + serializedObject.ApplyModifiedProperties(); + } + } + +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/RootSources2dEditor.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/RootSources2dEditor.cs.meta new file mode 100644 index 0000000..640fc84 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Editor/RootSources2dEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e3d768af6ee1774cb39815bd8e5b221 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts.meta new file mode 100644 index 0000000..6d58076 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 29f130eb3fdf4574a8a586b2bc99f11a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentOverride2d.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentOverride2d.cs new file mode 100644 index 0000000..77ec1c7 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentOverride2d.cs @@ -0,0 +1,36 @@ +using UnityEngine; +using UnityEngine.AI; + +namespace NavMeshPlus.Extensions +{ + public interface IAgentOverride + { + void UpdateAgent(); + } + + public class AgentDefaultOverride : IAgentOverride + { + public void UpdateAgent() + { + } + } + public class AgentOverride2d: MonoBehaviour + { + public NavMeshAgent Agent { get; private set; } + public IAgentOverride agentOverride { get; set; } + private void Awake() + { + Agent = GetComponent(); + } + private void Start() + { + Agent.updateRotation = false; + Agent.updateUpAxis = false; + } + + private void Update() + { + agentOverride?.UpdateAgent(); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentOverride2d.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentOverride2d.cs.meta new file mode 100644 index 0000000..5d2310f --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentOverride2d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e39f6090724e4a4a8aadeb042afa2bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d5b0e13ebe59cd64e9f67284457c6868, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotate2d.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotate2d.cs new file mode 100644 index 0000000..f1f79c0 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotate2d.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +namespace NavMeshPlus.Extensions +{ + public class AgentRotate2d: MonoBehaviour + { + private AgentOverride2d override2D; + private void Start() + { + override2D = GetComponent(); + override2D.agentOverride = new RotateAgentInstantly(override2D.Agent, override2D); + } + + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotate2d.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotate2d.cs.meta new file mode 100644 index 0000000..7cedfbb --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotate2d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8550f034611a06e4f88fc261204d8a7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d5b0e13ebe59cd64e9f67284457c6868, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotateSmooth2d.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotateSmooth2d.cs new file mode 100644 index 0000000..57aeae7 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotateSmooth2d.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +namespace NavMeshPlus.Extensions +{ + class AgentRotateSmooth2d: MonoBehaviour + { + public float angularSpeed; + private AgentOverride2d override2D; + + private void Start() + { + override2D = GetComponent(); + override2D.agentOverride = new RotateAgentSmoothly(override2D.Agent, override2D, angularSpeed); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotateSmooth2d.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotateSmooth2d.cs.meta new file mode 100644 index 0000000..ea6efda --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/AgentRotateSmooth2d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c7f4db162bab4443818dd13bed4b1dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d5b0e13ebe59cd64e9f67284457c6868, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSources2d.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSources2d.cs new file mode 100644 index 0000000..1ad5fad --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSources2d.cs @@ -0,0 +1,90 @@ +using NavMeshPlus.Components; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; +using UnityEngine.Tilemaps; + +namespace NavMeshPlus.Extensions +{ + [ExecuteAlways] + [AddComponentMenu("Navigation/Navigation CollectSources2d", 30)] + public class CollectSources2d: NavMeshExtension + { + [SerializeField] + bool m_OverrideByGrid; + public bool overrideByGrid { get { return m_OverrideByGrid; } set { m_OverrideByGrid = value; } } + + [SerializeField] + GameObject m_UseMeshPrefab; + public GameObject useMeshPrefab { get { return m_UseMeshPrefab; } set { m_UseMeshPrefab = value; } } + + [SerializeField] + bool m_CompressBounds; + public bool compressBounds { get { return m_CompressBounds; } set { m_CompressBounds = value; } } + + [SerializeField] + Vector3 m_OverrideVector = Vector3.one; + public Vector3 overrideVector { get { return m_OverrideVector; } set { m_OverrideVector = value; } } + + public override void CalculateWorldBounds(NavMeshSurface surface, List sources, NavMeshBuilderState navNeshState) + { + if (surface.collectObjects != CollectObjects.Volume) + { + navNeshState.worldBounds.Encapsulate(CalculateGridWorldBounds(surface, navNeshState.worldToLocal, navNeshState.worldBounds)); + } + } + + private static Bounds CalculateGridWorldBounds(NavMeshSurface surface, Matrix4x4 worldToLocal, Bounds bounds) + { + var grid = FindObjectOfType(); + var tilemaps = grid?.GetComponentsInChildren(); + if (tilemaps == null || tilemaps.Length < 1) + { + return bounds; + } + foreach (var tilemap in tilemaps) + { + var lbounds = NavMeshSurface.GetWorldBounds(worldToLocal * tilemap.transform.localToWorldMatrix, tilemap.localBounds); + bounds.Encapsulate(lbounds); + if (!surface.hideEditorLogs) + { + Debug.Log($"From Local Bounds [{tilemap.name}]: {tilemap.localBounds}"); + Debug.Log($"To World Bounds: {bounds}"); + } + } + return bounds; + } + + public override void CollectSources(NavMeshSurface surface, List sources, NavMeshBuilderState navNeshState) + { + if (!surface.hideEditorLogs) + { + if (!Mathf.Approximately(transform.eulerAngles.x, 270f)) + { + Debug.LogWarning("NavMeshSurface is not rotated respectively to (x-90;y0;z0). Apply rotation unless intended."); + } + if (Application.isPlaying) + { + if (surface.useGeometry == NavMeshCollectGeometry.PhysicsColliders && Time.frameCount <= 1) + { + Debug.LogWarning("Use Geometry - Physics Colliders option in NavMeshSurface may cause inaccurate mesh bake if executed before Physics update."); + } + } + } + var builder = navNeshState.GetExtraState(); + builder.defaultArea = surface.defaultArea; + builder.layerMask = surface.layerMask; + builder.agentID = surface.agentTypeID; + builder.useMeshPrefab = useMeshPrefab; + builder.overrideByGrid = overrideByGrid; + builder.compressBounds = compressBounds; + builder.overrideVector = overrideVector; + builder.CollectGeometry = surface.useGeometry; + builder.CollectObjects = (CollectObjects)(int)surface.collectObjects; + builder.parent = surface.gameObject; + builder.hideEditorLogs = surface.hideEditorLogs; + builder.SetRoot(navNeshState.roots); + NavMeshBuilder2d.CollectSources(sources, builder); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSources2d.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSources2d.cs.meta new file mode 100644 index 0000000..89f1119 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSources2d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 70bd44a44cd62c64fbfc1eea95b24880 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d5b0e13ebe59cd64e9f67284457c6868, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSourcesCache2d.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSourcesCache2d.cs new file mode 100644 index 0000000..318a420 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSourcesCache2d.cs @@ -0,0 +1,115 @@ +using NavMeshPlus.Components; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; + +namespace NavMeshPlus.Extensions +{ + [ExecuteAlways] + [AddComponentMenu("Navigation/Navigation CacheSources2d", 30)] + public class CollectSourcesCache2d : NavMeshExtension + { + List _sources; + Dictionary _lookup; + private Bounds _sourcesBounds; + public bool IsDirty { get; protected set; } + + private NavMeshBuilder2dState _state; + + public int SourcesCount => _sources.Count; + public int CahcheCount => _lookup.Count; + + public List Cache { get => _sources; } + + protected override void Awake() + { + _lookup = new Dictionary(); + _sources = new List(); + IsDirty = false; + Order = -1000; + _sourcesBounds = new Bounds(); + base.Awake(); + } + protected override void OnDestroy() + { + _state?.Dispose(); + base.OnDestroy(); + } + + public bool AddSource(GameObject gameObject, NavMeshBuildSource source) + { + var res = _lookup.ContainsKey(gameObject); + if (res) + { + return UpdateSource(gameObject); + } + _sources.Add(source); + _lookup.Add(gameObject, source); + IsDirty = true; + return true; + } + public bool UpdateSource(GameObject gameObject) + { + var res = _lookup.ContainsKey(gameObject); + if(res) + { + IsDirty = true; + var source = _lookup[gameObject]; + var idx = _sources.IndexOf(source); + if (idx >= 0) + { + source.transform = Matrix4x4.TRS(gameObject.transform.position, gameObject.transform.rotation, gameObject.transform.lossyScale); + _sources[idx] = source; + _lookup[gameObject] = source; + } + } + return res; + } + + public bool RemoveSource(GameObject gameObject) + { + var res = _lookup.ContainsKey(gameObject); + if (res) + { + IsDirty = true; + var source = _lookup[gameObject]; + _lookup.Remove(gameObject); + _sources.Remove(source); + } + return res; + } + + public AsyncOperation UpdateNavMesh(NavMeshData data) + { + IsDirty = false; + return NavMeshBuilder.UpdateNavMeshDataAsync(data, NavMeshSurfaceOwner.GetBuildSettings(), _sources, _sourcesBounds); + } + public AsyncOperation UpdateNavMesh() + { + return UpdateNavMesh(NavMeshSurfaceOwner.navMeshData); + } + public override void CollectSources(NavMeshSurface surface, List sources, NavMeshBuilderState navMeshState) + { + _lookup.Clear(); + IsDirty = false; + _state?.Dispose(); + _state = navMeshState.GetExtraState(false); + _state.lookupCallback = LookupCallback; + } + + private void LookupCallback(UnityEngine.Object component, NavMeshBuildSource source) + { + if (component == null) + { + return; + } + _lookup.Add(component, source); + } + + public override void PostCollectSources(NavMeshSurface surface, List sources, NavMeshBuilderState navNeshState) + { + _sourcesBounds = navNeshState.worldBounds; + _sources = sources; + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSourcesCache2d.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSourcesCache2d.cs.meta new file mode 100644 index 0000000..852a745 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectSourcesCache2d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5492b7ed96378624cbcd72212fce093d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d5b0e13ebe59cd64e9f67284457c6868, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectTilemapSourcesCache2d.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectTilemapSourcesCache2d.cs new file mode 100644 index 0000000..762ac9e --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectTilemapSourcesCache2d.cs @@ -0,0 +1,95 @@ +using NavMeshPlus.Components; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; +using UnityEngine.Tilemaps; + +namespace NavMeshPlus.Extensions +{ + [ExecuteAlways] + [AddComponentMenu("Navigation/Navigation CacheTilemapSources2d", 30)] + public class CollectTilemapSourcesCache2d : NavMeshExtension + { + [SerializeField] private Tilemap _tilemap; + [SerializeField] private NavMeshModifier _modifier; + [SerializeField] private NavMeshModifierTilemap _modifierTilemap; + + private List _sources; + private Dictionary _lookup; + private Dictionary _modifierMap; + + protected override void Awake() + { + _modifier ??= _tilemap.GetComponent(); + _modifierTilemap ??= _tilemap.GetComponent(); + _modifierMap = _modifierTilemap.GetModifierMap(); + Order = -1000; + base.Awake(); + } + +#if UNITY_EDITOR || UNITY_2022_2_OR_NEWER + private void OnTilemapTileChanged(Tilemap tilemap, Tilemap.SyncTile[] syncTiles) + { + if (tilemap == _tilemap) + { + foreach (Tilemap.SyncTile syncTile in syncTiles) + { + Vector3Int position = syncTile.position; + if (syncTile.tile != null && _modifierMap.TryGetValue(syncTile.tile, out NavMeshModifierTilemap.TileModifier tileModifier)) + { + int i = _lookup[position]; + NavMeshBuildSource source = _sources[i]; + source.area = tileModifier.area; + _sources[i] = source; + } + else if (_modifier.overrideArea) + { + int i = _lookup[position]; + NavMeshBuildSource source = _sources[i]; + source.area = _modifier.area; + _sources[i] = source; + } + } + } + } +#endif + + + public AsyncOperation UpdateNavMesh(NavMeshData data) + { + return NavMeshBuilder.UpdateNavMeshDataAsync(data, NavMeshSurfaceOwner.GetBuildSettings(), _sources, data.sourceBounds); + } + + public AsyncOperation UpdateNavMesh() + { + return UpdateNavMesh(NavMeshSurfaceOwner.navMeshData); + } + + public override void PostCollectSources(NavMeshSurface surface, List sources, NavMeshBuilderState navNeshState) + { + _sources = sources; + if (_lookup == null) + { + _lookup = new Dictionary(); + for (int i = 0; i < _sources.Count; i++) + { + NavMeshBuildSource source = _sources[i]; + Vector3Int position = _tilemap.WorldToCell(source.transform.GetPosition()); + _lookup[position] = i; + } + } + #if UNITY_EDITOR || UNITY_2022_2_OR_NEWER + Tilemap.tilemapTileChanged -= OnTilemapTileChanged; + Tilemap.tilemapTileChanged += OnTilemapTileChanged; + #endif + } + + protected override void OnDestroy() + { + #if UNITY_EDITOR || UNITY_2022_2_OR_NEWER + Tilemap.tilemapTileChanged -= OnTilemapTileChanged; + #endif + base.OnDestroy(); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectTilemapSourcesCache2d.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectTilemapSourcesCache2d.cs.meta new file mode 100644 index 0000000..433976d --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/CollectTilemapSourcesCache2d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4db9c2c5aca397f41a57740bd678fd51 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAgentAttribute.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAgentAttribute.cs new file mode 100644 index 0000000..038e05b --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAgentAttribute.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +//*********************************************************************************** +// Contributed by author jl-randazzo github.com/jl-randazzo +//*********************************************************************************** +namespace NavMeshPlus.Extensions +{ + [System.Serializable] + public class NavMeshAgentAttribute : PropertyAttribute + { + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAgentAttribute.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAgentAttribute.cs.meta new file mode 100644 index 0000000..2a710df --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAgentAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f3fe2b336bf34749a146f6bf7d462d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAreaAttribute.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAreaAttribute.cs new file mode 100644 index 0000000..5868703 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAreaAttribute.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +//*********************************************************************************** +// Contributed by author jl-randazzo github.com/jl-randazzo +//*********************************************************************************** +namespace NavMeshPlus.Extensions +{ + [System.Serializable] + // See also NavMeshAreaAttributePropertyDrawer + public class NavMeshAreaAttribute : PropertyAttribute + { + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAreaAttribute.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAreaAttribute.cs.meta new file mode 100644 index 0000000..4446803 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshAreaAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed6d9f7764b9451f97a6658cdc760e00 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d5b0e13ebe59cd64e9f67284457c6868, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilder2d.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilder2d.cs new file mode 100644 index 0000000..b8f1eaa --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilder2d.cs @@ -0,0 +1,398 @@ +using NavMeshPlus.Components; +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; +using UnityEngine.SceneManagement; +using UnityEngine.Tilemaps; +using Object = UnityEngine.Object; + +namespace NavMeshPlus.Extensions +{ + class NavMeshBuilder2dState: IDisposable + { + public Dictionary spriteMeshMap; + public Dictionary coliderMeshMap; + public Action lookupCallback; + public int defaultArea; + public int layerMask; + public int agentID; + public bool overrideByGrid; + public GameObject useMeshPrefab; + public bool compressBounds; + public Vector3 overrideVector; + public NavMeshCollectGeometry CollectGeometry; + public CollectObjects CollectObjects; + public GameObject parent; + public bool hideEditorLogs; + + protected IEnumerable _root; + private bool _disposed; + + public IEnumerable Root => _root ?? GetRoot(); + + public NavMeshBuilder2dState() + { + spriteMeshMap = new Dictionary(); + coliderMeshMap = new Dictionary(); + _root = null; + } + + public Mesh GetMesh(Sprite sprite) + { + Mesh mesh; + if (spriteMeshMap.ContainsKey(sprite)) + { + mesh = spriteMeshMap[sprite]; + } + else + { + mesh = new Mesh(); + NavMeshBuilder2d.sprite2mesh(sprite, mesh); + spriteMeshMap.Add(sprite, mesh); + } + return mesh; + } + + public Mesh GetMesh(Collider2D collider) + { +#if UNITY_2019_3_OR_NEWER + Mesh mesh; + uint hash = collider.GetShapeHash(); + if (coliderMeshMap.ContainsKey(hash)) + { + mesh = coliderMeshMap[hash]; + } + else + { + mesh = collider.CreateMesh(false, false); + coliderMeshMap.Add(hash, mesh); + } + return mesh; +#else + throw new InvalidOperationException("PhysicsColliders supported in Unity 2019.3 and higher."); +#endif + } + public void SetRoot(IEnumerable root) + { + _root = root; + } + public IEnumerable GetRoot() + { + switch (CollectObjects) + { + case CollectObjects.Children: return new[] { parent }; + case CollectObjects.Volume: + case CollectObjects.All: + default: + { + var list = new List(); + var roots = new List(); + for (int i = 0; i < SceneManager.sceneCount; ++i) + { + var s = SceneManager.GetSceneAt(i); + if (!s.isLoaded) continue; + s.GetRootGameObjects(list); + roots.AddRange(list); + } + return roots; + } + } + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + if (disposing) + { + // TODO: dispose managed state (managed objects). + foreach (var item in spriteMeshMap) + { +#if UNITY_EDITOR + Object.DestroyImmediate(item.Value); +#else + Object.Destroy(item.Value); +#endif + } + foreach (var item in coliderMeshMap) + { +#if UNITY_EDITOR + Object.DestroyImmediate(item.Value); +#else + Object.Destroy(item.Value); +#endif + } + spriteMeshMap.Clear(); + coliderMeshMap.Clear(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. + // TODO: set large fields to null. + + _disposed = true; + } + + public void Dispose() + { + // Dispose of unmanaged resources. + Dispose(true); + // Suppress finalization. + GC.SuppressFinalize(this); + } + } + + class NavMeshBuilder2d + { + public static void CollectSources(List sources, NavMeshBuilder2dState builder) + { + foreach (var it in builder.Root) + { + CollectSources(it, sources, builder); + } + if (!builder.hideEditorLogs) Debug.Log("Sources " + sources.Count); + } + + public static void CollectSources(GameObject root, List sources, NavMeshBuilder2dState builder) + { + foreach (var modifier in root.GetComponentsInChildren()) + { + if (((0x1 << modifier.gameObject.layer) & builder.layerMask) == 0) + { + continue; + } + if (!modifier.AffectsAgentType(builder.agentID)) + { + continue; + } + int area = builder.defaultArea; + //if it is walkable + if (builder.defaultArea != 1 && !modifier.ignoreFromBuild) + { + AddDefaultWalkableTilemap(sources, builder, modifier); + } + + if (modifier.overrideArea) + { + area = modifier.area; + } + if (!modifier.ignoreFromBuild) + { + CollectSources(sources, builder, modifier, area); + } + } + } + + public static void CollectSources(List sources, NavMeshBuilder2dState builder, NavMeshModifier modifier, int area) + { + if (builder.CollectGeometry == NavMeshCollectGeometry.PhysicsColliders) + { + var collider = modifier.GetComponent(); + if (collider != null) + { + CollectSources(sources, collider, area, builder); + } + } + else + { + var tilemap = modifier.GetComponent(); + if (tilemap != null) + { + CollectTileSources(sources, tilemap, area, builder); + } + var sprite = modifier.GetComponent(); + if (sprite != null) + { + CollectSources(sources, sprite, area, builder); + } + } + } + + private static void AddDefaultWalkableTilemap(List sources, NavMeshBuilder2dState builder, NavMeshModifier modifier) + { + var tilemap = modifier.GetComponent(); + if (tilemap != null) + { + if (builder.compressBounds) + { + tilemap.CompressBounds(); + } + + if (!builder.hideEditorLogs) Debug.Log($"Walkable Bounds [{tilemap.name}]: {tilemap.localBounds}"); + var box = BoxBoundSource(NavMeshSurface.GetWorldBounds(tilemap.transform.localToWorldMatrix, tilemap.localBounds)); + box.area = builder.defaultArea; + sources.Add(box); + } + } + + public static void CollectSources(List sources, SpriteRenderer spriteRenderer, int area, NavMeshBuilder2dState builder) + { + if (spriteRenderer == null || spriteRenderer.sprite == null) + { + return; + } + Mesh mesh; + mesh = builder.GetMesh(spriteRenderer.sprite); + if (mesh == null) + { + if (!builder.hideEditorLogs) Debug.Log($"{spriteRenderer.name} mesh is null"); + return; + } + var src = new NavMeshBuildSource(); + src.shape = NavMeshBuildSourceShape.Mesh; + src.component = spriteRenderer; + src.area = area; + src.transform = Matrix4x4.TRS(Vector3.Scale(spriteRenderer.transform.position, builder.overrideVector), spriteRenderer.transform.rotation, spriteRenderer.transform.lossyScale); + src.sourceObject = mesh; + sources.Add(src); + + builder.lookupCallback?.Invoke(spriteRenderer.gameObject, src); + } + + public static void CollectSources(List sources, Collider2D collider, int area, NavMeshBuilder2dState builder) + { + if (collider.usedByComposite) + { + collider = collider.GetComponent(); + } + + Mesh mesh; + mesh = builder.GetMesh(collider); + if (mesh == null) + { + if (!builder.hideEditorLogs) Debug.Log($"{collider.name} mesh is null"); + return; + } + + var src = new NavMeshBuildSource(); + src.shape = NavMeshBuildSourceShape.Mesh; + src.area = area; + src.component = collider; + src.sourceObject = mesh; + if (collider.attachedRigidbody) + { + src.transform = Matrix4x4.TRS(Vector3.Scale(collider.attachedRigidbody.transform.position, builder.overrideVector), collider.attachedRigidbody.transform.rotation, Vector3.one); + } + else + { + src.transform = Matrix4x4.identity; + } + + sources.Add(src); + + builder.lookupCallback?.Invoke(collider.gameObject, src); + } + + public static void CollectTileSources(List sources, Tilemap tilemap, int area, NavMeshBuilder2dState builder) + { + var bound = tilemap.cellBounds; + + var modifierTilemap = tilemap.GetComponent(); + + if (modifierTilemap && !modifierTilemap.AffectsAgentType(builder.agentID)) + { + return; + } + + var vec3int = new Vector3Int(0, 0, 0); + + var size = new Vector3(tilemap.layoutGrid.cellSize.x, tilemap.layoutGrid.cellSize.y, 0); + Mesh sharedMesh = null; + Quaternion rot = default; + + if (builder.useMeshPrefab != null) + { + sharedMesh = builder.useMeshPrefab.GetComponent().sharedMesh; + size = builder.useMeshPrefab.transform.localScale; + rot = builder.useMeshPrefab.transform.rotation; + } + for (int i = bound.xMin; i < bound.xMax; i++) + { + for (int j = bound.yMin; j < bound.yMax; j++) + { + var src = new NavMeshBuildSource(); + src.area = area; + + vec3int.x = i; + vec3int.y = j; + if (!tilemap.HasTile(vec3int)) + { + continue; + } + + CollectTile(tilemap, builder, vec3int, size, sharedMesh, rot, ref src); + if (modifierTilemap && modifierTilemap.TryGetTileModifier(vec3int, tilemap, out NavMeshModifierTilemap.TileModifier tileModifier)) + { + src.area = tileModifier.overrideArea ? tileModifier.area : area; + } + sources.Add(src); + + builder.lookupCallback?.Invoke(tilemap.GetInstantiatedObject(vec3int), src); + } + } + } + + private static void CollectTile(Tilemap tilemap, NavMeshBuilder2dState builder, Vector3Int vec3int, Vector3 size, Mesh sharedMesh, Quaternion rot, ref NavMeshBuildSource src) + { + if (!builder.overrideByGrid && tilemap.GetColliderType(vec3int) == Tile.ColliderType.Sprite) + { + var sprite = tilemap.GetSprite(vec3int); + if (sprite != null) + { + Mesh mesh = builder.GetMesh(sprite); + src.component = tilemap; + src.transform = GetCellTransformMatrix(tilemap, builder.overrideVector, vec3int); + src.shape = NavMeshBuildSourceShape.Mesh; + src.sourceObject = mesh; + } + } + else if (builder.useMeshPrefab != null || (builder.overrideByGrid && builder.useMeshPrefab != null)) + { + src.transform = Matrix4x4.TRS(Vector3.Scale(tilemap.GetCellCenterWorld(vec3int), builder.overrideVector), rot, size); + src.shape = NavMeshBuildSourceShape.Mesh; + src.sourceObject = sharedMesh; + } + else //default to box + { + src.transform = GetCellTransformMatrix(tilemap, builder.overrideVector, vec3int); + src.shape = NavMeshBuildSourceShape.Box; + src.size = size; + } + } + + public static Matrix4x4 GetCellTransformMatrix(Tilemap tilemap, Vector3 scale, Vector3Int vec3int) + { + return Matrix4x4.TRS(Vector3.Scale(tilemap.GetCellCenterWorld(vec3int), scale) - tilemap.layoutGrid.cellGap, tilemap.transform.rotation, tilemap.transform.lossyScale) * tilemap.orientationMatrix * tilemap.GetTransformMatrix(vec3int); + } + + internal static void sprite2mesh(Sprite sprite, Mesh mesh) + { + Vector3[] vert = new Vector3[sprite.vertices.Length]; + for (int i = 0; i < sprite.vertices.Length; i++) + { + vert[i] = new Vector3(sprite.vertices[i].x, sprite.vertices[i].y, 0); + } + mesh.vertices = vert; + mesh.uv = sprite.uv; + int[] tri = new int[sprite.triangles.Length]; + for (int i = 0; i < sprite.triangles.Length; i++) + { + tri[i] = sprite.triangles[i]; + } + mesh.triangles = tri; + } + + static private NavMeshBuildSource BoxBoundSource(Bounds localBounds) + { + var src = new NavMeshBuildSource(); + src.transform = Matrix4x4.Translate(localBounds.center); + src.shape = NavMeshBuildSourceShape.Box; + src.size = localBounds.size; + src.area = 0; + return src; + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilder2d.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilder2d.cs.meta new file mode 100644 index 0000000..5d109bb --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilder2d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc6dd3809c1761a4e9a227c70117ed54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: e8142b1daeea8d3419cd0ffbd7b17a37, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilderState.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilderState.cs new file mode 100644 index 0000000..be66cb8 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilderState.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace NavMeshPlus.Extensions +{ + public class NavMeshBuilderState: IDisposable + { + public Matrix4x4 worldToLocal; + public Bounds worldBounds; + public IEnumerable roots; + private CompositeDisposable disposable; + private Dictionary mExtraState; + private bool _disposed; + + public T GetExtraState(bool dispose = true) where T : class, new() + { + if (mExtraState == null) + { + mExtraState = new Dictionary(); + disposable = new CompositeDisposable(); + } + if (!mExtraState.TryGetValue(typeof(T), out System.Object extra)) + { + extra = mExtraState[typeof(T)] = new T(); + if (dispose) + { + disposable.Add(extra); + } + } + + return extra as T; + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + if (disposing) + { + // TODO: dispose managed state (managed objects). + disposable?.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. + // TODO: set large fields to null. + + _disposed = true; + } + + public void Dispose() + { + // Dispose of unmanaged resources. + Dispose(true); + // Suppress finalization. + GC.SuppressFinalize(this); + } + } + partial class CompositeDisposable: IDisposable + { + private bool _disposed; + private List extraStates = new List(); + + public void Add(IDisposable dispose) + { + extraStates.Add(dispose); + } + public void Add(object dispose) + { + if(dispose is IDisposable) + { + extraStates.Add((IDisposable)dispose); + } + } + protected virtual void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + if (disposing) + { + // TODO: dispose managed state (managed objects). + foreach (var item in extraStates) + { + item?.Dispose(); + } + extraStates.Clear(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. + // TODO: set large fields to null. + + _disposed = true; + } + + public void Dispose() + { + // Dispose of unmanaged resources. + Dispose(true); + // Suppress finalization. + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilderState.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilderState.cs.meta new file mode 100644 index 0000000..32cafaf --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshBuilderState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 710022065e740cf40bf86ccac60e3741 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: e8142b1daeea8d3419cd0ffbd7b17a37, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshComponents.asmdef b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshComponents.asmdef new file mode 100644 index 0000000..9ad51a6 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshComponents.asmdef @@ -0,0 +1,20 @@ +{ + "name": "NavMeshPlus", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.modules.terrain", + "expression": "0", + "define": "IS_TERRAIN_USED" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshComponents.asmdef.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshComponents.asmdef.meta new file mode 100644 index 0000000..779f99b --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshComponents.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 299beb10465c46f41abeaf10478b4727 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtension.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtension.cs new file mode 100644 index 0000000..5459ccd --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtension.cs @@ -0,0 +1,58 @@ +using NavMeshPlus.Components; +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; + +namespace NavMeshPlus.Extensions +{ + public abstract class NavMeshExtension: MonoBehaviour + { + public int Order { get; protected set; } + public virtual void CollectSources(NavMeshSurface surface, List sources, NavMeshBuilderState navNeshState) { } + public virtual void CalculateWorldBounds(NavMeshSurface surface, List sources, NavMeshBuilderState navNeshState) { } + public virtual void PostCollectSources(NavMeshSurface surface, List sources, NavMeshBuilderState navNeshState) { } + public NavMeshSurface NavMeshSurfaceOwner + { + get + { + if (m_navMeshOwner == null) + m_navMeshOwner = GetComponent(); + return m_navMeshOwner; + } + } + NavMeshSurface m_navMeshOwner; + + protected virtual void Awake() + { + ConnectToVcam(true); + } +#if UNITY_EDITOR + [UnityEditor.Callbacks.DidReloadScripts] + static void OnScriptReload() + { + var extensions = Resources.FindObjectsOfTypeAll( + typeof(NavMeshExtension)) as NavMeshExtension[]; + foreach (var e in extensions) + e.ConnectToVcam(true); + } +#endif + protected virtual void OnEnable() { } + protected virtual void OnDestroy() + { + ConnectToVcam(false); + } + protected virtual void ConnectToVcam(bool connect) + { + if (connect && NavMeshSurfaceOwner == null) + Debug.LogError("NevMeshExtension requires a NavMeshSurface component"); + if (NavMeshSurfaceOwner != null) + { + if (connect) + NavMeshSurfaceOwner.NevMeshExtensions.Add(this, Order); + else + NavMeshSurfaceOwner.NevMeshExtensions.Remove(this); + } + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtension.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtension.cs.meta new file mode 100644 index 0000000..4194706 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0528335b682da1f42901dc790b763830 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: e8142b1daeea8d3419cd0ffbd7b17a37, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtensionsProvider.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtensionsProvider.cs new file mode 100644 index 0000000..29de173 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtensionsProvider.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace NavMeshPlus.Extensions +{ + public interface INavMeshExtensionsProvider + { + int Count { get; } + NavMeshExtension this[int index] { get; } + void Add(NavMeshExtension extension, int order); + void Remove(NavMeshExtension extension); + } + internal class NavMeshExtensionMeta + { + public int order; + + public NavMeshExtensionMeta(int order, NavMeshExtension extension) + { + this.order = order; + this.extension = extension; + } + + public NavMeshExtension extension; + } + internal class NavMeshExtensionsProvider : INavMeshExtensionsProvider + { + List _extensions = new List(); + static Comparer Comparer = Comparer.Create((x, y) => x.order > y.order ? 1 : x.order < y.order ? -1 : 0); + public NavMeshExtension this[int index] => _extensions[index].extension; + + public int Count => _extensions.Count; + + public void Add(NavMeshExtension extension, int order) + { + var meta = new NavMeshExtensionMeta(order, extension); + var at = _extensions.BinarySearch(meta, Comparer); + if (at < 0) + { + _extensions.Add(meta); + _extensions.Sort(Comparer); + } + else + { + _extensions.Insert(at, meta); + } + } + + public void Remove(NavMeshExtension extension) + { + _extensions.RemoveAll(x => x.extension = extension); + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtensionsProvider.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtensionsProvider.cs.meta new file mode 100644 index 0000000..b999690 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshExtensionsProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc9c5ff0af7a2f247a2c64921cf9d045 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: e8142b1daeea8d3419cd0ffbd7b17a37, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshLink.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshLink.cs new file mode 100644 index 0000000..56ecc93 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshLink.cs @@ -0,0 +1,175 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; +using NavMeshPlus.Extensions; + +namespace NavMeshPlus.Components +{ + [ExecuteInEditMode] + [DefaultExecutionOrder(-101)] + [AddComponentMenu("Navigation/Navigation Link", 33)] + [HelpURL("https://github.com/Unity-Technologies/NavMeshPlus#documentation-draft")] + public class NavMeshLink : MonoBehaviour + { + [SerializeField, NavMeshAgent] + int m_AgentTypeID; + public int agentTypeID { get { return m_AgentTypeID; } set { m_AgentTypeID = value; UpdateLink(); } } + + [SerializeField] + Vector3 m_StartPoint = new Vector3(0.0f, 0.0f, -2.5f); + public Vector3 startPoint { get { return m_StartPoint; } set { m_StartPoint = value; UpdateLink(); } } + + [SerializeField] + Vector3 m_EndPoint = new Vector3(0.0f, 0.0f, 2.5f); + public Vector3 endPoint { get { return m_EndPoint; } set { m_EndPoint = value; UpdateLink(); } } + + [SerializeField] + float m_Width; + public float width { get { return m_Width; } set { m_Width = value; UpdateLink(); } } + + [SerializeField] + int m_CostModifier = -1; + public int costModifier { get { return m_CostModifier; } set { m_CostModifier = value; UpdateLink(); } } + + [SerializeField] + bool m_Bidirectional = true; + public bool bidirectional { get { return m_Bidirectional; } set { m_Bidirectional = value; UpdateLink(); } } + + [SerializeField] + bool m_AutoUpdatePosition; + public bool autoUpdate { get { return m_AutoUpdatePosition; } set { SetAutoUpdate(value); } } + + [SerializeField, NavMeshArea] + int m_Area; + public int area { get { return m_Area; } set { m_Area = value; UpdateLink(); } } + + NavMeshLinkInstance m_LinkInstance = new NavMeshLinkInstance(); + + Vector3 m_LastPosition = Vector3.zero; + Quaternion m_LastRotation = Quaternion.identity; + + static readonly List s_Tracked = new List(); + + void OnEnable() + { + AddLink(); + if (m_AutoUpdatePosition && m_LinkInstance.valid) + AddTracking(this); + } + + void OnDisable() + { + RemoveTracking(this); + m_LinkInstance.Remove(); + } + + public void UpdateLink() + { + m_LinkInstance.Remove(); + AddLink(); + } + + static void AddTracking(NavMeshLink link) + { +#if UNITY_EDITOR + if (s_Tracked.Contains(link)) + { + Debug.LogError("Link is already tracked: " + link); + return; + } +#endif + + if (s_Tracked.Count == 0) + NavMesh.onPreUpdate += UpdateTrackedInstances; + + s_Tracked.Add(link); + } + + static void RemoveTracking(NavMeshLink link) + { + s_Tracked.Remove(link); + + if (s_Tracked.Count == 0) + NavMesh.onPreUpdate -= UpdateTrackedInstances; + } + + void SetAutoUpdate(bool value) + { + if (m_AutoUpdatePosition == value) + return; + m_AutoUpdatePosition = value; + if (value) + AddTracking(this); + else + RemoveTracking(this); + } + + void AddLink() + { +#if UNITY_EDITOR + if (m_LinkInstance.valid) + { + Debug.LogError("Link is already added: " + this); + return; + } +#endif + + var link = new NavMeshLinkData(); + link.startPosition = m_StartPoint; + link.endPosition = m_EndPoint; + link.width = m_Width; + link.costModifier = m_CostModifier; + link.bidirectional = m_Bidirectional; + link.area = m_Area; + link.agentTypeID = m_AgentTypeID; + m_LinkInstance = NavMesh.AddLink(link, transform.position, transform.rotation); + if (m_LinkInstance.valid) + m_LinkInstance.owner = this; + + m_LastPosition = transform.position; + m_LastRotation = transform.rotation; + } + + bool HasTransformChanged() + { + if (m_LastPosition != transform.position) return true; + if (m_LastRotation != transform.rotation) return true; + return false; + } + + void OnDidApplyAnimationProperties() + { + UpdateLink(); + } + + static void UpdateTrackedInstances() + { + foreach (var instance in s_Tracked) + { + if (instance.HasTransformChanged()) + instance.UpdateLink(); + } + } + +#if UNITY_EDITOR + void OnValidate() + { + m_Width = Mathf.Max(0.0f, m_Width); + + if (!m_LinkInstance.valid) + return; + + UpdateLink(); + + if (!m_AutoUpdatePosition) + { + RemoveTracking(this); + } + else if (!s_Tracked.Contains(this)) + { + AddTracking(this); + } + } +#endif + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshLink.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshLink.cs.meta new file mode 100644 index 0000000..6ee5ec1 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshLink.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b9acdb93a5f98644a2e18d4884f04e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 68ad4f5d6fe957c4789aedd21ff67ced, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifier.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifier.cs new file mode 100644 index 0000000..e009bd2 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifier.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using UnityEngine; +using NavMeshPlus.Extensions; + +namespace NavMeshPlus.Components +{ + [ExecuteInEditMode] + [AddComponentMenu("Navigation/Navigation Modifier", 32)] + [HelpURL("https://github.com/Unity-Technologies/NavMeshComponents#documentation-draft")] + public class NavMeshModifier : MonoBehaviour + { + [SerializeField] + bool m_OverrideArea; + public bool overrideArea { get { return m_OverrideArea; } set { m_OverrideArea = value; } } + + [SerializeField, NavMeshArea] + int m_Area; + public int area { get { return m_Area; } set { m_Area = value; } } + + [SerializeField] + bool m_IgnoreFromBuild; + public bool ignoreFromBuild { get { return m_IgnoreFromBuild; } set { m_IgnoreFromBuild = value; } } + + // List of agent types the modifier is applied for. + // Special values: empty == None, m_AffectedAgents[0] =-1 == All. + [SerializeField] + List m_AffectedAgents = new List(new int[] { -1 }); // Default value is All + + static readonly List s_NavMeshModifiers = new List(); + + public static List activeModifiers + { + get { return s_NavMeshModifiers; } + } + + void OnEnable() + { + if (!s_NavMeshModifiers.Contains(this)) + s_NavMeshModifiers.Add(this); + } + + void OnDisable() + { + s_NavMeshModifiers.Remove(this); + } + + public bool AffectsAgentType(int agentTypeID) + { + if (m_AffectedAgents.Count == 0) + return false; + if (m_AffectedAgents[0] == -1) + return true; + return m_AffectedAgents.IndexOf(agentTypeID) != -1; + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifier.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifier.cs.meta new file mode 100644 index 0000000..cf0ebd8 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9809bf1345abc5648af68b3a82653f08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 273c8b5db6e39534781066db3444fe88, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierTilemap.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierTilemap.cs new file mode 100644 index 0000000..d02a89d --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierTilemap.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using NavMeshPlus.Extensions; +using UnityEngine.Tilemaps; + +//*********************************************************************************** +// Contributed by author jl-randazzo github.com/jl-randazzo +//*********************************************************************************** +namespace NavMeshPlus.Components +{ + [AddComponentMenu("Navigation/Navigation Modifier Tilemap", 33)] + [HelpURL("https://github.com/Unity-Technologies/NavMeshComponents#documentation-draft")] + [RequireComponent(typeof(Tilemap))] + [RequireComponent(typeof(NavMeshModifier))] + [DisallowMultipleComponent] + [ExecuteInEditMode] + public class NavMeshModifierTilemap : MonoBehaviour + { + [System.Serializable] + public struct TileModifier + { + public TileBase tile; + public bool overrideArea; + [NavMeshArea] public int area; + } + + private class MatchingTileComparator : IEqualityComparer + { + public static readonly IEqualityComparer Instance = new MatchingTileComparator(); + public bool Equals(TileModifier a, TileModifier b) => a.tile == b.tile; + public int GetHashCode(TileModifier tileModifier) => tileModifier.GetHashCode(); + } + + // List of agent types the modifier is applied for. + // Special values: empty == None, m_AffectedAgents[0] =-1 == All. + [SerializeField] + List m_AffectedAgents = new List(new int[] { -1 }); // Default value is All + + [SerializeField] + List m_TileModifiers = new List(); + + private Dictionary m_ModifierMap; + + public Dictionary GetModifierMap() => m_TileModifiers.Where(mod => mod.tile != null).Distinct(MatchingTileComparator.Instance).ToDictionary(mod => mod.tile); + + void OnEnable() + { + CacheModifiers(); + } + + public void CacheModifiers() + { + m_ModifierMap = GetModifierMap(); + } + +#if UNITY_EDITOR + public bool HasDuplicateTileModifiers() + { + return m_TileModifiers.Count != m_TileModifiers.Distinct(MatchingTileComparator.Instance).Count(); + } +#endif // UNITY_EDITOR + + public virtual bool TryGetTileModifier(Vector3Int coords, Tilemap tilemap, out TileModifier modifier) + { + if (tilemap.GetTile(coords) is TileBase tileBase) + { + return m_ModifierMap.TryGetValue(tileBase, out modifier); + } + modifier = new TileModifier(); + return false; + } + + public bool AffectsAgentType(int agentTypeID) + { + if (m_AffectedAgents.Count == 0) + return false; + if (m_AffectedAgents[0] == -1) + return true; + return m_AffectedAgents.IndexOf(agentTypeID) != -1; + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierTilemap.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierTilemap.cs.meta new file mode 100644 index 0000000..c2f9628 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierTilemap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 709c8d6349be44c68dff3d220992400c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 273c8b5db6e39534781066db3444fe88, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierVolume.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierVolume.cs new file mode 100644 index 0000000..1b80168 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierVolume.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using UnityEngine; +using NavMeshPlus.Extensions; + +namespace NavMeshPlus.Components +{ + [ExecuteInEditMode] + [AddComponentMenu("Navigation/Navigation ModifierVolume", 31)] + [HelpURL("https://github.com/Unity-Technologies/NavMeshComponents#documentation-draft")] + public class NavMeshModifierVolume : MonoBehaviour + { + [SerializeField] + Vector3 m_Size = new Vector3(4.0f, 3.0f, 4.0f); + public Vector3 size { get { return m_Size; } set { m_Size = value; } } + + [SerializeField] + Vector3 m_Center = new Vector3(0, 1.0f, 0); + public Vector3 center { get { return m_Center; } set { m_Center = value; } } + + [SerializeField, NavMeshArea] + int m_Area; + public int area { get { return m_Area; } set { m_Area = value; } } + + // List of agent types the modifier is applied for. + // Special values: empty == None, m_AffectedAgents[0] =-1 == All. + [SerializeField] + List m_AffectedAgents = new List(new int[] { -1 }); // Default value is All + + static readonly List s_NavMeshModifiers = new List(); + + public static List activeModifiers + { + get { return s_NavMeshModifiers; } + } + + void OnEnable() + { + if (!s_NavMeshModifiers.Contains(this)) + s_NavMeshModifiers.Add(this); + } + + void OnDisable() + { + s_NavMeshModifiers.Remove(this); + } + + public bool AffectsAgentType(int agentTypeID) + { + if (m_AffectedAgents.Count == 0) + return false; + if (m_AffectedAgents[0] == -1) + return true; + return m_AffectedAgents.IndexOf(agentTypeID) != -1; + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierVolume.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierVolume.cs.meta new file mode 100644 index 0000000..98ec520 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshModifierVolume.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7fa0352a4d56abd42ad2fc69deb72448 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 273c8b5db6e39534781066db3444fe88, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshSurface.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshSurface.cs new file mode 100644 index 0000000..6686aca --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshSurface.cs @@ -0,0 +1,551 @@ +using NavMeshPlus.Extensions; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; +#if UNITY_EDITOR +using UnityEditor; +using UnityEditor.SceneManagement; +#endif + +namespace NavMeshPlus.Components +{ + public enum CollectObjects + { + All = 0, + Volume = 1, + Children = 2, + } + + [ExecuteAlways] + [DefaultExecutionOrder(-102)] + [AddComponentMenu("Navigation/Navigation Surface", 30)] + [HelpURL("https://github.com/Unity-Technologies/NavMeshComponents#documentation-draft")] + public class NavMeshSurface : MonoBehaviour + { + [SerializeField, NavMeshAgent] + int m_AgentTypeID; + public int agentTypeID { get { return m_AgentTypeID; } set { m_AgentTypeID = value; } } + + [SerializeField] + CollectObjects m_CollectObjects = CollectObjects.All; + public CollectObjects collectObjects { get { return m_CollectObjects; } set { m_CollectObjects = value; } } + + [SerializeField] + Vector3 m_Size = new Vector3(10.0f, 10.0f, 10.0f); + public Vector3 size { get { return m_Size; } set { m_Size = value; } } + + [SerializeField] + Vector3 m_Center = new Vector3(0, 2.0f, 0); + public Vector3 center { get { return m_Center; } set { m_Center = value; } } + + [SerializeField] + LayerMask m_LayerMask = ~0; + public LayerMask layerMask { get { return m_LayerMask; } set { m_LayerMask = value; } } + + [SerializeField] + NavMeshCollectGeometry m_UseGeometry = NavMeshCollectGeometry.RenderMeshes; + public NavMeshCollectGeometry useGeometry { get { return m_UseGeometry; } set { m_UseGeometry = value; } } + + [SerializeField, NavMeshArea] + int m_DefaultArea; + public int defaultArea { get { return m_DefaultArea; } set { m_DefaultArea = value; } } + + [SerializeField] + bool m_IgnoreNavMeshAgent = true; + public bool ignoreNavMeshAgent { get { return m_IgnoreNavMeshAgent; } set { m_IgnoreNavMeshAgent = value; } } + + [SerializeField] + bool m_IgnoreNavMeshObstacle = true; + public bool ignoreNavMeshObstacle { get { return m_IgnoreNavMeshObstacle; } set { m_IgnoreNavMeshObstacle = value; } } + + [SerializeField] + bool m_OverrideTileSize; + public bool overrideTileSize { get { return m_OverrideTileSize; } set { m_OverrideTileSize = value; } } + [SerializeField] + int m_TileSize = 256; + public int tileSize { get { return m_TileSize; } set { m_TileSize = value; } } + [SerializeField] + bool m_OverrideVoxelSize; + public bool overrideVoxelSize { get { return m_OverrideVoxelSize; } set { m_OverrideVoxelSize = value; } } + [SerializeField] + float m_VoxelSize; + public float voxelSize { get { return m_VoxelSize; } set { m_VoxelSize = value; } } + + // Currently not supported advanced options + [SerializeField] + bool m_BuildHeightMesh; + public bool buildHeightMesh { get { return m_BuildHeightMesh; } set { m_BuildHeightMesh = value; } } + + [SerializeField] + float m_MinRegionArea = 0; + public float minRegionArea { get { return m_MinRegionArea; } set { m_MinRegionArea = value; } } + + [SerializeField] + bool m_HideEditorLogs; + public bool hideEditorLogs { get { return m_HideEditorLogs; } set { m_HideEditorLogs = value; } } + + // Reference to whole scene navmesh data asset. + [UnityEngine.Serialization.FormerlySerializedAs("m_BakedNavMeshData")] + [SerializeField] + NavMeshData m_NavMeshData; + public NavMeshData navMeshData { get { return m_NavMeshData; } set { m_NavMeshData = value; } } + + // Do not serialize - runtime only state. + NavMeshDataInstance m_NavMeshDataInstance; + Vector3 m_LastPosition = Vector3.zero; + Quaternion m_LastRotation = Quaternion.identity; + + public NavMeshDataInstance navMeshDataInstance => m_NavMeshDataInstance; + + static readonly List s_NavMeshSurfaces = new List(); + public INavMeshExtensionsProvider NevMeshExtensions { get; set; } = new NavMeshExtensionsProvider(); + + public static List activeSurfaces + { + get { return s_NavMeshSurfaces; } + } + + void OnEnable() + { + Register(this); + AddData(); + } + + void OnDisable() + { + RemoveData(); + Unregister(this); + } + + public void AddData() + { +#if UNITY_EDITOR + var isInPreviewScene = EditorSceneManager.IsPreviewSceneObject(this); + var isPrefab = isInPreviewScene || EditorUtility.IsPersistent(this); + if (isPrefab) + { + //Debug.LogFormat("NavMeshData from {0}.{1} will not be added to the NavMesh world because the gameObject is a prefab.", + // gameObject.name, name); + return; + } +#endif + if (m_NavMeshDataInstance.valid) + return; + + if (m_NavMeshData != null) + { + m_NavMeshDataInstance = NavMesh.AddNavMeshData(m_NavMeshData, transform.position, transform.rotation); + m_NavMeshDataInstance.owner = this; + } + + m_LastPosition = transform.position; + m_LastRotation = transform.rotation; + } + + public void RemoveData() + { + m_NavMeshDataInstance.Remove(); + m_NavMeshDataInstance = new NavMeshDataInstance(); + } + + public NavMeshBuildSettings GetBuildSettings() + { + var buildSettings = NavMesh.GetSettingsByID(m_AgentTypeID); + if (buildSettings.agentTypeID == -1) + { + if (!m_HideEditorLogs) Debug.LogWarning("No build settings for agent type ID " + agentTypeID, this); + buildSettings.agentTypeID = m_AgentTypeID; + } + + if (overrideTileSize) + { + buildSettings.overrideTileSize = true; + buildSettings.tileSize = tileSize; + } + if (overrideVoxelSize) + { + buildSettings.overrideVoxelSize = true; + buildSettings.voxelSize = voxelSize; + } + + buildSettings.minRegionArea = minRegionArea; + return buildSettings; + } + + public void BuildNavMesh() + { + using var builderState = new NavMeshBuilderState() { }; + + var sources = CollectSources(builderState); + + // Use unscaled bounds - this differs in behaviour from e.g. collider components. + // But is similar to reflection probe - and since navmesh data has no scaling support - it is the right choice here. + var sourcesBounds = new Bounds(m_Center, Abs(m_Size)); + if (m_CollectObjects == CollectObjects.All || m_CollectObjects == CollectObjects.Children) + { + sourcesBounds = CalculateWorldBounds(sources); + } + builderState.worldBounds = sourcesBounds; + for (int i = 0; i < NevMeshExtensions.Count; ++i) + { + NevMeshExtensions[i].PostCollectSources(this, sources, builderState); + } + var data = NavMeshBuilder.BuildNavMeshData(GetBuildSettings(), + sources, sourcesBounds, transform.position, transform.rotation); + + if (data != null) + { + data.name = gameObject.name; + RemoveData(); + m_NavMeshData = data; + if (isActiveAndEnabled) + AddData(); + } + } + + // Source: https://github.com/Unity-Technologies/NavMeshComponents/issues/97#issuecomment-528692289 + public AsyncOperation BuildNavMeshAsync() + { + RemoveData(); + m_NavMeshData = new NavMeshData(m_AgentTypeID) + { + name = gameObject.name, + position = transform.position, + rotation = transform.rotation + }; + + if (isActiveAndEnabled) + { + AddData(); + } + + return UpdateNavMesh(m_NavMeshData); + } + + public AsyncOperation UpdateNavMesh(NavMeshData data) + { + using var builderState = new NavMeshBuilderState() { }; + + var sources = CollectSources(builderState); + + // Use unscaled bounds - this differs in behaviour from e.g. collider components. + // But is similar to reflection probe - and since navmesh data has no scaling support - it is the right choice here. + var sourcesBounds = new Bounds(m_Center, Abs(m_Size)); + if (m_CollectObjects == CollectObjects.All || m_CollectObjects == CollectObjects.Children) + { + sourcesBounds = CalculateWorldBounds(sources); + } + builderState.worldBounds = sourcesBounds; + for (int i = 0; i < NevMeshExtensions.Count; ++i) + { + NevMeshExtensions[i].PostCollectSources(this, sources, builderState); + } + return NavMeshBuilder.UpdateNavMeshDataAsync(data, GetBuildSettings(), sources, sourcesBounds); + } + + static void Register(NavMeshSurface surface) + { +#if UNITY_EDITOR + var isInPreviewScene = EditorSceneManager.IsPreviewSceneObject(surface); + var isPrefab = isInPreviewScene || EditorUtility.IsPersistent(surface); + if (isPrefab) + { + //Debug.LogFormat("NavMeshData from {0}.{1} will not be added to the NavMesh world because the gameObject is a prefab.", + // surface.gameObject.name, surface.name); + return; + } +#endif + if (s_NavMeshSurfaces.Count == 0) + NavMesh.onPreUpdate += UpdateActive; + + if (!s_NavMeshSurfaces.Contains(surface)) + s_NavMeshSurfaces.Add(surface); + } + + static void Unregister(NavMeshSurface surface) + { + s_NavMeshSurfaces.Remove(surface); + + if (s_NavMeshSurfaces.Count == 0) + NavMesh.onPreUpdate -= UpdateActive; + } + + static void UpdateActive() + { + for (var i = 0; i < s_NavMeshSurfaces.Count; ++i) + s_NavMeshSurfaces[i].UpdateDataIfTransformChanged(); + } + + void AppendModifierVolumes(ref List sources) + { +#if UNITY_EDITOR + var myStage = StageUtility.GetStageHandle(gameObject); + if (!myStage.IsValid()) + return; +#endif + // Modifiers + List modifiers; + if (m_CollectObjects == CollectObjects.Children) + { + modifiers = new List(GetComponentsInChildren()); + modifiers.RemoveAll(x => !x.isActiveAndEnabled); + } + else + { + modifiers = NavMeshModifierVolume.activeModifiers; + } + + foreach (var m in modifiers) + { + if ((m_LayerMask & (1 << m.gameObject.layer)) == 0) + continue; + if (!m.AffectsAgentType(m_AgentTypeID)) + continue; +#if UNITY_EDITOR + if (!myStage.Contains(m.gameObject)) + continue; +#endif + var mcenter = m.transform.TransformPoint(m.center); + var scale = m.transform.lossyScale; + var msize = new Vector3(m.size.x * Mathf.Abs(scale.x), m.size.y * Mathf.Abs(scale.y), m.size.z * Mathf.Abs(scale.z)); + + var src = new NavMeshBuildSource(); + src.shape = NavMeshBuildSourceShape.ModifierBox; + src.transform = Matrix4x4.TRS(mcenter, m.transform.rotation, Vector3.one); + src.size = msize; + src.area = m.area; + sources.Add(src); + } + } + + List CollectSources(NavMeshBuilderState builderState) + { + var sources = new List(); + var markups = new List(); + + List modifiers; + if (m_CollectObjects == CollectObjects.Children) + { + modifiers = new List(GetComponentsInChildren()); + modifiers.RemoveAll(x => !x.isActiveAndEnabled); + } + else + { + modifiers = NavMeshModifier.activeModifiers; + } + + foreach (var m in modifiers) + { + if ((m_LayerMask & (1 << m.gameObject.layer)) == 0) + continue; + if (!m.AffectsAgentType(m_AgentTypeID)) + continue; + var markup = new NavMeshBuildMarkup(); + markup.root = m.transform; + markup.overrideArea = m.overrideArea; + markup.area = m.area; + markup.ignoreFromBuild = m.ignoreFromBuild; + markups.Add(markup); + } + +#if UNITY_EDITOR + if (!EditorApplication.isPlaying) + { + if (m_CollectObjects == CollectObjects.All) + { + UnityEditor.AI.NavMeshEditorHelpers.CollectSourcesInStage( + null, m_LayerMask, m_UseGeometry, m_DefaultArea, markups, gameObject.scene, sources); + } + else if (m_CollectObjects == CollectObjects.Children) + { + UnityEditor.AI.NavMeshEditorHelpers.CollectSourcesInStage( + transform, m_LayerMask, m_UseGeometry, m_DefaultArea, markups, gameObject.scene, sources); + } + else if (m_CollectObjects == CollectObjects.Volume) + { + Matrix4x4 localToWorld = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one); + var worldBounds = GetWorldBounds(localToWorld, new Bounds(m_Center, m_Size)); + + UnityEditor.AI.NavMeshEditorHelpers.CollectSourcesInStage( + worldBounds, m_LayerMask, m_UseGeometry, m_DefaultArea, markups, gameObject.scene, sources); + } + for (int i = 0; i < NevMeshExtensions.Count; ++i) + { + NevMeshExtensions[i].CollectSources(this, sources, builderState); + } + } + else +#endif + { + if (m_CollectObjects == CollectObjects.All) + { + NavMeshBuilder.CollectSources(null, m_LayerMask, m_UseGeometry, m_DefaultArea, markups, sources); + } + else if (m_CollectObjects == CollectObjects.Children) + { + NavMeshBuilder.CollectSources(transform, m_LayerMask, m_UseGeometry, m_DefaultArea, markups, sources); + } + else if (m_CollectObjects == CollectObjects.Volume) + { + Matrix4x4 localToWorld = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one); + var worldBounds = GetWorldBounds(localToWorld, new Bounds(m_Center, m_Size)); + NavMeshBuilder.CollectSources(worldBounds, m_LayerMask, m_UseGeometry, m_DefaultArea, markups, sources); + } + for (int i = 0; i < NevMeshExtensions.Count; ++i) + { + NevMeshExtensions[i].CollectSources(this, sources, builderState); + } + } + + if (m_IgnoreNavMeshAgent) + sources.RemoveAll((x) => (x.component != null && x.component.gameObject.GetComponent() != null)); + + if (m_IgnoreNavMeshObstacle) + sources.RemoveAll((x) => (x.component != null && x.component.gameObject.GetComponent() != null)); + + AppendModifierVolumes(ref sources); + + return sources; + } + + static Vector3 Abs(Vector3 v) + { + return new Vector3(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z)); + } + + public static Bounds GetWorldBounds(Matrix4x4 mat, Bounds bounds) + { + var absAxisX = Abs(mat.MultiplyVector(Vector3.right)); + var absAxisY = Abs(mat.MultiplyVector(Vector3.up)); + var absAxisZ = Abs(mat.MultiplyVector(Vector3.forward)); + var worldPosition = mat.MultiplyPoint(bounds.center); + var worldSize = absAxisX * bounds.size.x + absAxisY * bounds.size.y + absAxisZ * bounds.size.z; + return new Bounds(worldPosition, worldSize); + } + + public Bounds CalculateWorldBounds(List sources) + { + // Use the unscaled matrix for the NavMeshSurface + Matrix4x4 worldToLocal = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one); + worldToLocal = worldToLocal.inverse; + + var result = new Bounds(); + var builderState = new NavMeshBuilderState() { worldBounds = result, worldToLocal = worldToLocal }; + for (int i = 0; i < NevMeshExtensions.Count; ++i) + { + NevMeshExtensions[i].CalculateWorldBounds(this, sources, builderState); + result.Encapsulate(builderState.worldBounds); + } + foreach (var src in sources) + { + switch (src.shape) + { + case NavMeshBuildSourceShape.Mesh: + { + var m = src.sourceObject as Mesh; + result.Encapsulate(GetWorldBounds(worldToLocal * src.transform, m.bounds)); + break; + } + case NavMeshBuildSourceShape.Terrain: + { +#if IS_TERRAIN_USED + // 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))); +#endif + break; + } + case NavMeshBuildSourceShape.Box: + case NavMeshBuildSourceShape.Sphere: + case NavMeshBuildSourceShape.Capsule: + case NavMeshBuildSourceShape.ModifierBox: + result.Encapsulate(GetWorldBounds(worldToLocal * src.transform, new Bounds(Vector3.zero, src.size))); + break; + } + } + // Inflate the bounds a bit to avoid clipping co-planar sources + result.Expand(0.1f); + return result; + } + + bool HasTransformChanged() + { + if (m_LastPosition != transform.position) return true; + if (m_LastRotation != transform.rotation) return true; + return false; + } + + void UpdateDataIfTransformChanged() + { + if (HasTransformChanged()) + { + RemoveData(); + AddData(); + } + } + +#if UNITY_EDITOR + bool UnshareNavMeshAsset() + { + // Nothing to unshare + if (m_NavMeshData == null) + return false; + + // Prefab parent owns the asset reference + var isInPreviewScene = EditorSceneManager.IsPreviewSceneObject(this); + var isPersistentObject = EditorUtility.IsPersistent(this); + if (isInPreviewScene || isPersistentObject) + return false; + + // An instance can share asset reference only with its prefab parent + var prefab = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(this) as NavMeshSurface; + if (prefab != null && prefab.navMeshData == navMeshData) + return false; + + // Don't allow referencing an asset that's assigned to another surface + for (var i = 0; i < s_NavMeshSurfaces.Count; ++i) + { + var surface = s_NavMeshSurfaces[i]; + if (surface != this && surface.m_NavMeshData == m_NavMeshData) + return true; + } + + // Asset is not referenced by known surfaces + return false; + } + + void OnValidate() + { + if (UnshareNavMeshAsset()) + { + if (!m_HideEditorLogs) Debug.LogWarning("Duplicating NavMeshSurface does not duplicate the referenced navmesh data", this); + m_NavMeshData = null; + } + + var settings = NavMesh.GetSettingsByID(m_AgentTypeID); + if (settings.agentTypeID != -1) + { + // When unchecking the override control, revert to automatic value. + const float kMinVoxelSize = 0.01f; + if (!m_OverrideVoxelSize) + m_VoxelSize = settings.agentRadius / 3.0f; + if (m_VoxelSize < kMinVoxelSize) + m_VoxelSize = kMinVoxelSize; + + // When unchecking the override control, revert to default value. + const int kMinTileSize = 16; + const int kMaxTileSize = 1024; + const int kDefaultTileSize = 256; + + if (!m_OverrideTileSize) + m_TileSize = kDefaultTileSize; + // Make sure tilesize is in sane range. + if (m_TileSize < kMinTileSize) + m_TileSize = kMinTileSize; + if (m_TileSize > kMaxTileSize) + m_TileSize = kMaxTileSize; + } + } +#endif + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshSurface.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshSurface.cs.meta new file mode 100644 index 0000000..dc1d70f --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/NavMeshSurface.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e04976799df50f54ba128eff723155a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 444810ca896903c41adf617b35274dc4, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RootSources2d.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RootSources2d.cs new file mode 100644 index 0000000..d31e62d --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RootSources2d.cs @@ -0,0 +1,32 @@ +using NavMeshPlus.Components; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UnityEngine.AI; + +namespace NavMeshPlus.Extensions +{ + [ExecuteAlways] + [AddComponentMenu("Navigation/Navigation RootSources2d", 30)] + public class RootSources2d: NavMeshExtension + { + [SerializeField] + private List _rootSources; + + public List RootSources { get => _rootSources; set => _rootSources = value; } + + protected override void Awake() + { + Order = -1000; + base.Awake(); + } + + public override void CollectSources(NavMeshSurface surface, List sources, NavMeshBuilderState navNeshState) + { + navNeshState.roots = _rootSources; + } + } +} diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RootSources2d.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RootSources2d.cs.meta new file mode 100644 index 0000000..ac2b190 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RootSources2d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fec7b7904f76c4498a68fd145934563 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d5b0e13ebe59cd64e9f67284457c6868, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentInstantly.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentInstantly.cs new file mode 100644 index 0000000..d6c4022 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentInstantly.cs @@ -0,0 +1,40 @@ +using UnityEngine; +using UnityEngine.AI; + +//*********************************************************************************** +// Contributed by author @Lazy_Sloth from unity forum (https://forum.unity.com/) +//*********************************************************************************** +namespace NavMeshPlus.Extensions +{ + public class RotateAgentInstantly: IAgentOverride + { + + public RotateAgentInstantly(NavMeshAgent agent, AgentOverride2d owner) + { + this.agent = agent; + this.owner = owner; + } + private NavMeshAgent agent; + private AgentOverride2d owner; + private Vector3 nextWaypoint; + + public void UpdateAgent() + { + if (agent.hasPath && agent.path.corners.Length > 1) + { + if (nextWaypoint != agent.path.corners[1]) + { + RotateToPoint(agent.path.corners[1], agent.transform); + nextWaypoint = agent.path.corners[1]; + } + } + } + + private static void RotateToPoint(Vector3 targetPoint, Transform transform) + { + Vector3 targetVector = targetPoint - transform.position; + float angleDifference = Vector2.SignedAngle(transform.up, targetVector); + transform.rotation = Quaternion.Euler(0, 0, transform.localEulerAngles.z + angleDifference); + } + } +} \ No newline at end of file diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentInstantly.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentInstantly.cs.meta new file mode 100644 index 0000000..abd0ec9 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentInstantly.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b304bdab91a28c469562d02b8225df3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: e8142b1daeea8d3419cd0ffbd7b17a37, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentSmoothly.cs b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentSmoothly.cs new file mode 100644 index 0000000..6eeb754 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentSmoothly.cs @@ -0,0 +1,57 @@ +using System.Collections; +using UnityEngine; +using UnityEngine.AI; + +//*********************************************************************************** +// Contributed by author @Lazy_Sloth from unity forum (https://forum.unity.com/) +//*********************************************************************************** +namespace NavMeshPlus.Extensions +{ + public class RotateAgentSmoothly: IAgentOverride + { + public RotateAgentSmoothly(NavMeshAgent agent, AgentOverride2d owner, float rotateSpeed) + { + this.agent = agent; + this.owner = owner; + this.rotateSpeed = rotateSpeed; + } + + private NavMeshAgent agent; + private AgentOverride2d owner; + private Vector2 nextWaypoint; + private float angleDifference; + private float targetAngle; + public float rotateSpeed; + + public void UpdateAgent() + { + if (agent.hasPath && agent.path.corners.Length > 1) + { + if (nextWaypoint != (Vector2)agent.path.corners[1]) + { + owner.StartCoroutine(_RotateCoroutine()); + nextWaypoint = agent.path.corners[1]; + } + } + } + protected IEnumerator _RotateCoroutine() + { + yield return RotateToWaypoints(agent.transform); + } + protected IEnumerator RotateToWaypoints(Transform transform) + { + Vector2 targetVector = agent.path.corners[1] - transform.position; + angleDifference = Vector2.SignedAngle(transform.up, targetVector); + targetAngle = transform.localEulerAngles.z + angleDifference; + + if (targetAngle >= 360) { targetAngle -= 360; } + else if (targetAngle < 0) { targetAngle += 360; } + + while (transform.localEulerAngles.z < targetAngle - 0.1f || transform.localEulerAngles.z > targetAngle + 0.1f) + { + transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 0, targetAngle), rotateSpeed * Time.deltaTime); + yield return null; + } + } + } +} \ No newline at end of file diff --git a/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentSmoothly.cs.meta b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentSmoothly.cs.meta new file mode 100644 index 0000000..ec15bde --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/NavMeshComponents/Scripts/RotateAgentSmoothly.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f8df5c105d35bd4787c3b4ce3e1c56b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: e8142b1daeea8d3419cd0ffbd7b17a37, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/README.md b/Assets/Plugins/NavMeshPlus/README.md new file mode 100644 index 0000000..3d95b20 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/README.md @@ -0,0 +1,70 @@ + +# NavMeshPlus + +NavMeshComponents.Extensions provides you with ability to create navigation meshes that are generated automatically from your Scene +geometry, which allows characters to move intelligently around the game world. + +![NavMesh](https://github.com/h8man/NavMeshPlus/wiki/images/Tittle-01.png) + +# Unity 2D Pathfinding +This repo is fork of Unity NavMeshComponents enhanced with Extensions system for 2d Pathfinding and more. [[link]](https://github.com/Unity-Technologies/NavMeshComponents) + +#### Wiki [[here]](https://github.com/h8man/NavMeshPlus/wiki) +#### How To [[here]](https://github.com/h8man/NavMeshPlus/wiki/HOW-TO). +#### Demo [[github]](https://github.com/h8man/RedHotSweetPepper ). +#### Discuss [[unityforum]](https://forum.unity.com/threads/2d-navmesh-pathfinding.503596/ ). + +# 2D NavMesh + +In repo you will find implementation of NavMeshSurface and 2d Extensions for tilemap, sprites and collider2d top down games. + +To use it in your project: + +1. Copy repo into your Asset folder (or install as a package). +2. Create Empty Object in scene root. +3. Add "Navigation Surface" component to Empty Object and add NavMeshCollecSources2d component after. +4. Click Rotate Surface to XY (to face surface toward standard 2d camera x-90;y0;z0) +5. Add "Navigation Modifier" component to scene objects obstacles, override the area. +6. In "Navigation Surface" hit Bake. + +How does it works: + +1. It uses [NavMeshSurface](https://docs.unity3d.com/Manual/class-NavMeshSurface.html) as base implementation. +2. Implements world bound calculation. +3. Implements source collector of tiles, sprites and 2d colliders +4. Creates walkable mesh box from world bounds. +5. Convert tiles, sprites and 2d colliders to sources as `NavMeshBuilder` would do. + +# Components & Extensions: +- NavMeshLink +- NavMeshModifier +- NavMeshModifierVolume +- NavMeshSurface: + - NavMeshCollectSources2d + - NavMeshCollectRootSources2d + - NavMeshCacheSources2d + +Utilities +- NavMeshExtensionsProvider.cs +- NavMeshBuilder2d.cs +- NavMeshExtension.cs +- NavMeshBuilderState.cs + +# Setup + +You can use this in two different ways: downloading this repository or adding it to your project's Package Manager manifest. [Git](https://git-scm.com/) must be installed and added to your path. +Alternatively, you can pick scripts and place in your project's `Assets` folder. + +#### Method 1. Download +Download or clone this repository into your project in the folder `Packages/com.h8man.2d.navmeshplus`. + +#### Method 2. Package Manager Manifest +The following line needs to be added to your `Packages/manifest.json` file in your Unity Project under the `dependencies` section: +``` +"com.h8man.2d.navmeshplus": "https://github.com/h8man/NavMeshPlus.git#master" +``` +#### Method 3. Add Package form git URL +Go to `Package Manager` click `+` and then select `Add Package form git URL` paste url: +``` +https://github.com/h8man/NavMeshPlus.git +``` diff --git a/Assets/Plugins/NavMeshPlus/README.md.meta b/Assets/Plugins/NavMeshPlus/README.md.meta new file mode 100644 index 0000000..f6b8104 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2f77fe52aa3396942bf2eecff964b4d0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Unity.meta b/Assets/Plugins/NavMeshPlus/Unity.meta new file mode 100644 index 0000000..0844b4b --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2d085361c3a06be448c4127d3d5e22f4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Unity/LICENSE b/Assets/Plugins/NavMeshPlus/Unity/LICENSE new file mode 100644 index 0000000..ea2052f --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Unity/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016, Unity Technologies + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Assets/Plugins/NavMeshPlus/Unity/LICENSE.meta b/Assets/Plugins/NavMeshPlus/Unity/LICENSE.meta new file mode 100644 index 0000000..693f64b --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Unity/LICENSE.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4919e823dd64ccf498a5a5e4da60a79e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/Unity/README.md b/Assets/Plugins/NavMeshPlus/Unity/README.md new file mode 100644 index 0000000..0472ea7 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Unity/README.md @@ -0,0 +1,60 @@ +> Please use the branch matching the version of your Unity editor: [master](../../tree/master) for the latest released version, [2018.3](../../tree/2018.3), [2018.2](../../tree/2018.2), [2018.1](../../tree/2018.1), [2017.2](../../tree/2017.2) for up to 2017.4-LTS, [2017.1](../../tree/2017.1), [5.6](../../tree/5.6). + +# Components for Runtime NavMesh Building + +Here we introduce four components for the navigation system: + +* __NavMeshSurface__ – for building and enabling a NavMesh surface for one agent type. +* __NavMeshModifier__ – affects the NavMesh generation of NavMesh area types, based on the transform hierarchy. +* __NavMeshModifierVolume__ – affects the NavMesh generation of NavMesh area types, based on volume. +* __NavMeshLink__ – connects same or different NavMesh surfaces for one agent type. + +These components comprise the high level controls for building and using NavMeshes at runtime as well as edit time. + +Detailed information can be found in the [Documentation](Documentation) section or in the [NavMesh building components](https://docs.unity3d.com/Manual/NavMesh-BuildingComponents.html) section of the Unity Manual. + +# How To Get Started + +Download and install Unity 5.6 or newer. + +Clone or download this repository and open the project in Unity. +Alternatively, you can copy the contents of `Assets/NavMeshComponents` to an existing project. Make sure to select a branch of the repository that matches the Unity version. + +Additional examples are available in the `Assets/Examples` folder. +The examples are provided "as is". They are neither generic nor robust, but serve as inspiration. + +_Note: During the beta cycle features and API are subject to change.\ +**Make sure to backup an existing project before opening it with a beta build.**_ + +# FAQ + +Q: Can I bake a NavMesh at runtime? +A: Yes. + +Q: Can I use NavMesh'es for more than one agent size? +A: Yes. + +Q: Can I put a NavMesh in a prefab? +A: Yes - with some limitations. + +Q: How do I connect two NavMesh surfaces? +A: Use the NavMeshLink to connect the two sides. + +Q: How do I query the NavMesh for one specific size of agent? +A: Use the NavMeshQuery filter when querying the NavMesh. + +Q: What's the deal with the 'DefaultExecutionOrder' attribute? +A: It gives a way of controlling the order of execution of scripts - specifically it allows us to build a NavMesh before the +(native) NavMeshAgent component is enabled. + +Q: What's the use of the new delegate 'NavMesh.onPreUpdate'? +A: It allows you to hook in to controlling the NavMesh data and links set up before the navigation update loop is called on the native side. + +Q: Can I do moving NavMesh platforms? +A: No - new API is required for consistently moving platforms carrying agents. + +Q: Is OffMeshLink now obsolete? +A: No - you can still use OffMeshLink - however you'll find that NavMeshLink is more flexible and have less overhead. + +Q: What happened to HeightMesh and Auto Generated OffMeshLinks? +A: They're not supported in the new NavMesh building feature. HeightMesh will be added at some point. Auto OffMeshLink generation will possibly be replaced with a solution that allows better control of placement. diff --git a/Assets/Plugins/NavMeshPlus/Unity/README.md.meta b/Assets/Plugins/NavMeshPlus/Unity/README.md.meta new file mode 100644 index 0000000..7902f04 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/Unity/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 32745b071c7e5004f946a98ebaf2fc15 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/navmeshplus.pdf b/Assets/Plugins/NavMeshPlus/navmeshplus.pdf new file mode 100644 index 0000000..9de7627 Binary files /dev/null and b/Assets/Plugins/NavMeshPlus/navmeshplus.pdf differ diff --git a/Assets/Plugins/NavMeshPlus/navmeshplus.pdf.meta b/Assets/Plugins/NavMeshPlus/navmeshplus.pdf.meta new file mode 100644 index 0000000..23e5d13 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/navmeshplus.pdf.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0d419d21003cd354bb186fc0ad3a84fd +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/NavMeshPlus/package.json b/Assets/Plugins/NavMeshPlus/package.json new file mode 100644 index 0000000..f26e2c3 --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/package.json @@ -0,0 +1,12 @@ +{ + + "name": "com.h8man.2d.navmeshplus", + "displayName": "NavMeshPlus", + "version": "0.2.23", + "unity": "2022.3", + "description": "NavMesh building components provide you with ability to create navigation meshes that are generated automatically from your Scene geometry, which allows characters to move intelligently around the game world.", + "keywords": ["2d"], + "category": "2D", + "dependencies": { } + +} diff --git a/Assets/Plugins/NavMeshPlus/package.json.meta b/Assets/Plugins/NavMeshPlus/package.json.meta new file mode 100644 index 0000000..791219b --- /dev/null +++ b/Assets/Plugins/NavMeshPlus/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a11de58dc8c82df4a8a5db73629430c4 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Characters/Enemies/Gobler.prefab b/Assets/Prefabs/Characters/Enemies/Gobler.prefab index 1e80ae8..2a81150 100644 --- a/Assets/Prefabs/Characters/Enemies/Gobler.prefab +++ b/Assets/Prefabs/Characters/Enemies/Gobler.prefab @@ -10,7 +10,7 @@ GameObject: m_Component: - component: {fileID: 1693662441197515017} - component: {fileID: 5093925305183066901} - m_Layer: 0 + m_Layer: 3 m_Name: Shadow m_TagString: Untagged m_Icon: {fileID: 0} @@ -97,7 +97,7 @@ GameObject: m_Component: - component: {fileID: 2045680922754072471} - component: {fileID: 1180914023357243997} - m_Layer: 0 + m_Layer: 3 m_Name: Capsule m_TagString: Untagged m_Icon: {fileID: 0} @@ -164,7 +164,7 @@ SpriteRenderer: m_SortingLayer: 4 m_SortingOrder: 0 m_Sprite: {fileID: -9095717837082945937, guid: 207ee8102dd4143d288186ef0be518ee, type: 3} - m_Color: {r: 1, g: 1, b: 1, a: 1} + m_Color: {r: 1, g: 0.084905505, b: 0.084905505, a: 1} m_FlipX: 0 m_FlipY: 0 m_DrawMode: 0 @@ -174,75 +174,6 @@ SpriteRenderer: m_WasSpriteAssigned: 1 m_MaskInteraction: 0 m_SpriteSortPoint: 0 ---- !u!1 &6288550889223568635 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 8417872790204748578} - - component: {fileID: 5305176699257483480} - m_Layer: 0 - m_Name: HitBox - m_TagString: EnemyHitBox - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &8417872790204748578 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6288550889223568635} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: -0.212, z: 0} - m_LocalScale: {x: 0.62288, y: 0.49601915, z: 0.62288} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 243343966221896818} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!70 &5305176699257483480 -CapsuleCollider2D: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6288550889223568635} - m_Enabled: 1 - serializedVersion: 3 - m_Density: 1 - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_ForceSendLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_ForceReceiveLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_ContactCaptureLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_CallbackLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_IsTrigger: 0 - m_UsedByEffector: 0 - m_CompositeOperation: 0 - m_CompositeOrder: 0 - m_Offset: {x: 0, y: 0} - m_Size: {x: 1, y: 2} - m_Direction: 0 --- !u!1 &6411951171763069002 GameObject: m_ObjectHideFlags: 0 @@ -254,7 +185,8 @@ GameObject: - component: {fileID: 243343966221896818} - component: {fileID: 3140493390153182690} - component: {fileID: 9193586887117248369} - m_Layer: 0 + - component: {fileID: -6727715650573699922} + m_Layer: 3 m_Name: Gobler m_TagString: Untagged m_Icon: {fileID: 0} @@ -276,7 +208,6 @@ Transform: m_Children: - {fileID: 2045680922754072471} - {fileID: 1693662441197515017} - - {fileID: 8417872790204748578} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!70 &3140493390153182690 @@ -313,8 +244,8 @@ CapsuleCollider2D: m_UsedByEffector: 0 m_CompositeOperation: 0 m_CompositeOrder: 0 - m_Offset: {x: -0.00000006812225, y: -0.5714509} - m_Size: {x: 0.8074399, y: 0.49523765} + m_Offset: {x: 0.001541889, y: -0.6988835} + m_Size: {x: 0.56149423, y: 0.24480417} m_Direction: 1 --- !u!50 &9193586887117248369 Rigidbody2D: @@ -324,7 +255,7 @@ Rigidbody2D: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6411951171763069002} - m_BodyType: 0 + m_BodyType: 1 m_Simulated: 1 m_UseFullKinematicContacts: 0 m_UseAutoMass: 0 @@ -338,8 +269,30 @@ Rigidbody2D: m_Bits: 0 m_ExcludeLayers: serializedVersion: 2 - m_Bits: 0 + m_Bits: 8 m_Interpolate: 0 m_SleepingMode: 1 m_CollisionDetection: 1 m_Constraints: 4 +--- !u!195 &-6727715650573699922 +NavMeshAgent: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6411951171763069002} + m_Enabled: 1 + m_AgentTypeID: 0 + m_Radius: 0.5 + m_Speed: 3.5 + m_Acceleration: 30 + avoidancePriority: 50 + m_AngularSpeed: 120 + m_StoppingDistance: 1 + m_AutoTraverseOffMeshLink: 1 + m_AutoBraking: 1 + m_AutoRepath: 1 + m_Height: 2 + m_BaseOffset: 0 + m_WalkableMask: 4294967295 + m_ObstacleAvoidanceType: 2 diff --git a/Assets/Scenes/HomeTown.meta b/Assets/Scenes/HomeTown.meta new file mode 100644 index 0000000..4acce78 --- /dev/null +++ b/Assets/Scenes/HomeTown.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4cbe29b74e7df374e9539d6390b1ff80 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/HomeTown/NavMesh-NavMeshManager.asset b/Assets/Scenes/HomeTown/NavMesh-NavMeshManager.asset new file mode 100644 index 0000000..513399b Binary files /dev/null and b/Assets/Scenes/HomeTown/NavMesh-NavMeshManager.asset differ diff --git a/Assets/Scenes/HomeTown/NavMesh-NavMeshManager.asset.meta b/Assets/Scenes/HomeTown/NavMesh-NavMeshManager.asset.meta new file mode 100644 index 0000000..f37f1fe --- /dev/null +++ b/Assets/Scenes/HomeTown/NavMesh-NavMeshManager.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2fe1d45b05d429942bb729a071517972 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 23800000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Runtime/AI/EnemyManager/GoblerStateManager.cs b/Assets/Scripts/Runtime/AI/EnemyManager/GoblerStateManager.cs index e6b063a..74a2970 100644 --- a/Assets/Scripts/Runtime/AI/EnemyManager/GoblerStateManager.cs +++ b/Assets/Scripts/Runtime/AI/EnemyManager/GoblerStateManager.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Xml.Linq; using UnityEngine; +using UnityEngine.AI; public class GoblerStateManager { [Header("Mechanics Attributes")] @@ -24,14 +25,22 @@ public class GoblerStateManager { private Player Player { get { return Player.Instance; } } private Transform PlayerTransform { get { return Player.transform; } } private Vector2 PlayerPos { get { return PlayerTransform.position; } } + private Vector2 CrystalPos { get { return GameManager.Crystal.transform.position; } } private GameObject Owner; private Transform MyTransform { get { return Owner.transform; } } private Vector2 MyPos { get { return MyTransform.position; } set { MyTransform.position = value; } } + private NavMeshAgent PathAgent; + public GoblerStateManager(GameObject owner) { Owner = owner; + PathAgent = Owner.GetComponent(); + PathAgent.updateRotation = false; + PathAgent.updateUpAxis = false; + PathAgent.speed = Speed; + SetState(State.GoToCrystal); EnemySpawnerManager.UpdateTick += Update; EnemySpawnerManager.GizmoTick += OnDrawGizmos; } @@ -67,6 +76,7 @@ public class GoblerStateManager { IsUpdating = true; DistFromPlayer = Vector2.Distance(MyPos, PlayerPos); + DistFromCrystal = Vector2.Distance(MyPos, CrystalPos); SetPriorityState(); switch (CurrentState) { @@ -75,6 +85,10 @@ public class GoblerStateManager { case State.GoToCrystal: + PathAgent.SetDestination(CrystalPos); + + if (DistFromCrystal < 1) + SetState(State.Die); break; @@ -83,10 +97,11 @@ public class GoblerStateManager { case State.ChasePlayer: - MyPos += (PlayerPos - MyPos).normalized * Speed * Time.deltaTime; + //MyPos += (PlayerPos - MyPos).normalized * Speed * Time.deltaTime; + PathAgent.SetDestination(PlayerPos); - if (DistFromPlayer >= ChaseDistance + ChaseDistanceBuffer) - SetState(State.AttackCrystal); + if (DistFromPlayer > ChaseDistance + ChaseDistanceBuffer) + SetState(State.GoToCrystal); else if (DistFromPlayer < 1) SetState(State.Die); break; diff --git a/Assets/Scripts/Runtime/GameManagement/EnemySpawnerManager.cs b/Assets/Scripts/Runtime/GameManagement/EnemySpawnerManager.cs index 1299834..06dedc1 100644 --- a/Assets/Scripts/Runtime/GameManagement/EnemySpawnerManager.cs +++ b/Assets/Scripts/Runtime/GameManagement/EnemySpawnerManager.cs @@ -6,14 +6,16 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; using UnityEngine.UIElements; +using static EnemySpawnerManager; public class EnemySpawnerManager : MonoBehaviour { public static EnemySpawnerManager Instance; [SerializeField] public GameObject GoblerPreFab; + private GameObjectPool GoblerPool; public static Dictionary Goblers = new Dictionary(); public static Action UpdateTick; public static Action GizmoTick; - public static int MaxGoblers = 1; + public static int MaxGoblers = 100; public class Gobler { public GameObject Object; @@ -27,16 +29,18 @@ public class EnemySpawnerManager : MonoBehaviour { public void Awake() { Instance = this; + Goblers.Clear(); + GoblerPool = new GameObjectPool(GoblerPreFab, 50, 200); } - public static void RemoveGobler(GoblerStateManager goblerManager){ + public static void RemoveGobler(GoblerStateManager goblerManager) { Destroy(Goblers[goblerManager]); Goblers.Remove(goblerManager); } public void Update() { - if (Goblers.Count() < MaxGoblers){ - var gobler = Instantiate(GoblerPreFab, this.transform.position, Quaternion.identity); + while (Goblers.Count() < MaxGoblers) { + var gobler = GoblerPool.Get(transform.position, Quaternion.identity); Goblers.Add(new GoblerStateManager(gobler), gobler); } UpdateTick?.Invoke(); diff --git a/Assets/Scripts/Runtime/GameManagement/GameManager.cs b/Assets/Scripts/Runtime/GameManagement/GameManager.cs index db789e8..f9435a1 100644 --- a/Assets/Scripts/Runtime/GameManagement/GameManager.cs +++ b/Assets/Scripts/Runtime/GameManagement/GameManager.cs @@ -3,23 +3,31 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Unity.VisualScripting; using UnityEngine; -namespace Assets.Scripts.Runtime.GameManagement { - public class GameManager : MonoBehaviour { - public static bool IsPaused { get; private set; } - [SerializeField] private GameObject pauseMenuUI; +public class GameManager : MonoBehaviour { + [SerializeField] private GameObject CrystalRef; + public static GameObject Crystal; - void Update() { - if (Input.GetKeyDown(KeyCode.Escape)) - TogglePause(); - } + public static bool IsPaused { get; private set; } + [SerializeField] private GameObject pauseMenuUI; - public void TogglePause() { - IsPaused = !IsPaused; - Time.timeScale = IsPaused ? 0f : 1f; - AudioListener.pause = IsPaused; - pauseMenuUI.SetActive(IsPaused); - } + private void Awake() { + Crystal = CrystalRef; + + } + + + void Update() { + if (Input.GetKeyDown(KeyCode.Escape)) + TogglePause(); + } + + public void TogglePause() { + IsPaused = !IsPaused; + Time.timeScale = IsPaused ? 0f : 1f; + AudioListener.pause = IsPaused; + pauseMenuUI.SetActive(IsPaused); } } diff --git a/Packages/manifest.json b/Packages/manifest.json index a6c5c87..2aae8d4 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -1,5 +1,6 @@ { "dependencies": { + "com.unity.ai.navigation": "2.0.8", "com.unity.cinemachine": "3.1.4", "com.unity.collab-proxy": "2.8.2", "com.unity.feature.2d": "2.0.1", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index a6e8478..3293be6 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -96,6 +96,15 @@ }, "url": "https://packages.unity.com" }, + "com.unity.ai.navigation": { + "version": "2.0.8", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.modules.ai": "1.0.0" + }, + "url": "https://packages.unity.com" + }, "com.unity.bindings.openimageio": { "version": "1.0.0", "depth": 1, diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset index c165afb..7781eaf 100644 --- a/ProjectSettings/GraphicsSettings.asset +++ b/ProjectSettings/GraphicsSettings.asset @@ -3,7 +3,7 @@ --- !u!30 &1 GraphicsSettings: m_ObjectHideFlags: 0 - serializedVersion: 13 + serializedVersion: 16 m_Deferred: m_Mode: 1 m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} @@ -13,9 +13,6 @@ GraphicsSettings: m_ScreenSpaceShadows: m_Mode: 1 m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} - m_LegacyDeferred: - m_Mode: 1 - m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} m_DepthNormals: m_Mode: 1 m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} @@ -38,16 +35,18 @@ GraphicsSettings: - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0} m_PreloadedShaders: [] + m_PreloadShadersBatchTimeLimit: -1 m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} m_CustomRenderPipeline: {fileID: 0} - m_TransparencySortMode: 0 - m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_TransparencySortMode: 3 + m_TransparencySortAxis: {x: 0, y: 1, z: 0} m_DefaultRenderingPath: 1 m_DefaultMobileRenderingPath: 1 m_TierSettings: [] m_LightmapStripping: 0 m_FogStripping: 0 m_InstancingStripping: 0 + m_BrgStripping: 0 m_LightmapKeepPlain: 1 m_LightmapKeepDirCombined: 1 m_LightmapKeepDynamicPlain: 1 @@ -58,7 +57,10 @@ GraphicsSettings: m_FogKeepExp: 1 m_FogKeepExp2: 1 m_AlbedoSwatchInfos: [] + m_RenderPipelineGlobalSettingsMap: {} m_LightsUseLinearIntensity: 0 m_LightsUseColorTemperature: 0 - m_DefaultRenderingLayerMask: 1 m_LogWhenShaderIsCompiled: 0 + m_LightProbeOutsideHullStrategy: 0 + m_CameraRelativeLightCulling: 0 + m_CameraRelativeShadowCulling: 0 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index e803ba3..d4885b7 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -12,7 +12,7 @@ TagManager: - Default - TransparentFX - Ignore Raycast - - + - Enemy - Water - UI - Structures diff --git a/UserSettings/EditorUserSettings.asset b/UserSettings/EditorUserSettings.asset index d8bce34..968ef0b 100644 --- a/UserSettings/EditorUserSettings.asset +++ b/UserSettings/EditorUserSettings.asset @@ -6,7 +6,7 @@ EditorUserSettings: serializedVersion: 4 m_ConfigSettings: GraphicsSettingsInspector_UserSettings: - value: 18134705175a055722080a3115371d4a0d55006876786860616b0471b8b07a68ffab74f9ee2a3a30300cea1a11320d0beb1a0c25f7060f494b4cdf1b18f3045e38cb5ad8 + value: 18134705175a055722080a3115371d4a0d55006876786860616b0471b8b1646ab4a966f4ab782f352907e3350a3b272afe063d12e60e240a1c0bbf5453dd051a1dd155ec148a02 flags: 0 RecentlyUsedSceneGuid-0: value: 5554570006545b0e590f0d24457a5e444e154a7d752d72687e2a4835bab66039 diff --git a/UserSettings/Layouts/default-6000.dwlt b/UserSettings/Layouts/default-6000.dwlt index 778d4f3..55ff504 100644 --- a/UserSettings/Layouts/default-6000.dwlt +++ b/UserSettings/Layouts/default-6000.dwlt @@ -14,16 +14,16 @@ MonoBehaviour: m_EditorClassIdentifier: m_PixelRect: serializedVersion: 2 - x: 0 - y: 43 - width: 1920 - height: 989 + x: 909.3334 + y: 50 + width: 1643.3334 + height: 1334.6667 m_ShowMode: 4 - m_Title: Project + m_Title: Game m_RootView: {fileID: 2} - m_MinSize: {x: 875, y: 300} + m_MinSize: {x: 875, y: 332} m_MaxSize: {x: 10000, y: 10000} - m_Maximized: 1 + m_Maximized: 0 --- !u!114 &2 MonoBehaviour: m_ObjectHideFlags: 52 @@ -44,8 +44,8 @@ MonoBehaviour: serializedVersion: 2 x: 0 y: 0 - width: 1920 - height: 989 + width: 1643.3334 + height: 1334.6666 m_MinSize: {x: 875, y: 300} m_MaxSize: {x: 10000, y: 10000} m_UseTopView: 1 @@ -69,7 +69,7 @@ MonoBehaviour: serializedVersion: 2 x: 0 y: 0 - width: 1920 + width: 1643.3334 height: 36 m_MinSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0} @@ -90,8 +90,8 @@ MonoBehaviour: m_Position: serializedVersion: 2 x: 0 - y: 969 - width: 1920 + y: 1314.6666 + width: 1643.3334 height: 20 m_MinSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0} @@ -109,17 +109,17 @@ MonoBehaviour: m_EditorClassIdentifier: m_Children: - {fileID: 6} - - {fileID: 11} + - {fileID: 15} m_Position: serializedVersion: 2 x: 0 y: 36 - width: 1920 - height: 933 - m_MinSize: {x: 300, y: 100} - m_MaxSize: {x: 24288, y: 16192} + width: 1643.3334 + height: 1278.6666 + m_MinSize: {x: 300, y: 150} + m_MaxSize: {x: 24288, y: 24288} vertical: 0 - controlID: 73937 + controlID: 179809 draggingID: 0 --- !u!114 &6 MonoBehaviour: @@ -135,17 +135,17 @@ MonoBehaviour: m_EditorClassIdentifier: m_Children: - {fileID: 7} - - {fileID: 10} + - {fileID: 14} m_Position: serializedVersion: 2 x: 0 y: 0 - width: 1372 - height: 933 - m_MinSize: {x: 200, y: 100} - m_MaxSize: {x: 16192, y: 16192} + width: 1252.6666 + height: 1278.6666 + m_MinSize: {x: 200, y: 150} + m_MaxSize: {x: 16192, y: 24288} vertical: 1 - controlID: 73938 + controlID: 179810 draggingID: 0 --- !u!114 &7 MonoBehaviour: @@ -161,19 +161,45 @@ MonoBehaviour: m_EditorClassIdentifier: m_Children: - {fileID: 8} - - {fileID: 9} + - {fileID: 11} m_Position: serializedVersion: 2 x: 0 y: 0 - width: 1372 - height: 499 - m_MinSize: {x: 200, y: 50} - m_MaxSize: {x: 16192, y: 8096} + width: 1252.6666 + height: 877.3333 + m_MinSize: {x: 200, y: 100} + m_MaxSize: {x: 16192, y: 16192} vertical: 0 - controlID: 73914 + controlID: 179811 draggingID: 0 --- !u!114 &8 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 9} + - {fileID: 10} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 283.33334 + height: 877.3333 + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 8096, y: 16192} + vertical: 1 + controlID: 179800 + draggingID: 0 +--- !u!114 &9 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -190,16 +216,68 @@ MonoBehaviour: serializedVersion: 2 x: 0 y: 0 - width: 304 - height: 499 + width: 283.33334 + height: 583.3333 m_MinSize: {x: 201, y: 226} m_MaxSize: {x: 4001, y: 4026} - m_ActualView: {fileID: 13} + m_ActualView: {fileID: 17} m_Panes: - - {fileID: 13} + - {fileID: 17} m_Selected: 0 m_LastSelected: 0 ---- !u!114 &9 +--- !u!114 &10 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: AnimationTesterWindow + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 583.3333 + width: 283.33334 + height: 294 + m_MinSize: {x: 51, y: 76} + m_MaxSize: {x: 4001, y: 4026} + m_ActualView: {fileID: 18} + m_Panes: + - {fileID: 18} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &11 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 12} + - {fileID: 13} + m_Position: + serializedVersion: 2 + x: 283.33334 + y: 0 + width: 969.33325 + height: 877.3333 + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 8096, y: 16192} + vertical: 1 + controlID: 179812 + draggingID: 0 +--- !u!114 &12 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -209,26 +287,52 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: SceneView + m_Name: GameView m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 - x: 304 + x: 0 y: 0 - width: 1068 - height: 499 - m_MinSize: {x: 202, y: 226} + width: 969.33325 + height: 557.3333 + m_MinSize: {x: 52, y: 76} m_MaxSize: {x: 4002, y: 4026} - m_ActualView: {fileID: 14} + m_ActualView: {fileID: 16} m_Panes: - - {fileID: 14} - - {fileID: 12} - - {fileID: 15} + - {fileID: 19} - {fileID: 16} - m_Selected: 0 - m_LastSelected: 1 ---- !u!114 &10 + - {fileID: 20} + m_Selected: 1 + m_LastSelected: 2 +--- !u!114 &13 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: AnimationWindow + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 557.3333 + width: 969.33325 + height: 320 + m_MinSize: {x: 52, y: 76} + m_MaxSize: {x: 4002, y: 4026} + m_ActualView: {fileID: 22} + m_Panes: + - {fileID: 21} + - {fileID: 22} + m_Selected: 1 + m_LastSelected: 0 +--- !u!114 &14 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -244,20 +348,19 @@ MonoBehaviour: m_Position: serializedVersion: 2 x: 0 - y: 499 - width: 1372 - height: 434 + y: 877.3333 + width: 1252.6666 + height: 401.3333 m_MinSize: {x: 231, y: 276} m_MaxSize: {x: 10001, y: 10026} - m_ActualView: {fileID: 17} + m_ActualView: {fileID: 23} m_Panes: - - {fileID: 17} - - {fileID: 18} - - {fileID: 19} - - {fileID: 20} + - {fileID: 23} + - {fileID: 24} + - {fileID: 25} m_Selected: 0 m_LastSelected: 1 ---- !u!114 &11 +--- !u!114 &15 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -272,18 +375,19 @@ MonoBehaviour: m_Children: [] m_Position: serializedVersion: 2 - x: 1372 + x: 1252.6666 y: 0 - width: 548 - height: 933 + width: 390.66675 + height: 1278.6666 m_MinSize: {x: 276, y: 76} m_MaxSize: {x: 4001, y: 4026} - m_ActualView: {fileID: 21} + m_ActualView: {fileID: 26} m_Panes: - - {fileID: 21} + - {fileID: 26} + - {fileID: 27} m_Selected: 0 - m_LastSelected: 0 ---- !u!114 &12 + m_LastSelected: 1 +--- !u!114 &16 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -299,15 +403,15 @@ MonoBehaviour: m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Game - m_Image: {fileID: -6423792434712278376, guid: 0000000000000000d000000000000000, type: 0} + m_Image: {fileID: 4621777727084837110, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_TextWithWhitespace: "Game\u200B" m_Pos: serializedVersion: 2 - x: 304 - y: 79 - width: 1066 - height: 473 + x: 1 + y: 24 + width: 967.33325 + height: 531.3333 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -322,7 +426,7 @@ MonoBehaviour: m_SerializedViewNames: [] m_SerializedViewValues: [] m_PlayModeViewName: GameView - m_ShowGizmos: 1 + m_ShowGizmos: 0 m_TargetDisplay: 0 m_ClearColor: {r: 0, g: 0, b: 0, a: 0} m_TargetSize: {x: 1920, y: 1080} @@ -332,7 +436,7 @@ MonoBehaviour: m_EnterPlayModeBehavior: 0 m_UseMipMap: 0 m_VSyncEnabled: 0 - m_Gizmos: 1 + m_Gizmos: 0 m_Stats: 0 m_SelectedSizes: 03000000000000000000000000000000000000000000000000000000000000000000000000000000 m_ZoomArea: @@ -340,10 +444,10 @@ MonoBehaviour: m_VRangeLocked: 0 hZoomLockedByDefault: 0 vZoomLockedByDefault: 0 - m_HBaseRangeMin: -960 - m_HBaseRangeMax: 960 - m_VBaseRangeMin: -540 - m_VBaseRangeMax: 540 + m_HBaseRangeMin: -640 + m_HBaseRangeMax: 640 + m_VBaseRangeMin: -360 + m_VBaseRangeMax: 360 m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMax: 1 m_VAllowExceedBaseRangeMin: 1 @@ -352,7 +456,7 @@ MonoBehaviour: m_HSlider: 0 m_VSlider: 0 m_IgnoreScrollWheelUntilClicked: 0 - m_EnableMouseInput: 0 + m_EnableMouseInput: 1 m_EnableSliderZoomHorizontal: 0 m_EnableSliderZoomVertical: 0 m_UniformScale: 1 @@ -361,30 +465,30 @@ MonoBehaviour: serializedVersion: 2 x: 0 y: 21 - width: 1066 - height: 452 - m_Scale: {x: 1, y: 1} - m_Translation: {x: 533, y: 225.99997} + width: 967.33325 + height: 513 + m_Scale: {x: 0.7125, y: 0.7125} + m_Translation: {x: 483.66663, y: 256.5} m_MarginLeft: 0 m_MarginRight: 0 m_MarginTop: 0 m_MarginBottom: 0 m_LastShownAreaInsideMargins: serializedVersion: 2 - x: -533 - y: -225.99997 - width: 1066 - height: 452 + x: -678.8304 + y: -360 + width: 1357.6608 + height: 720 m_MinimalGUI: 1 - m_defaultScale: 0.4185185 - m_LastWindowPixelSize: {x: 1066, y: 473} + m_defaultScale: 0.7125 + m_LastWindowPixelSize: {x: 967.33325, y: 534} m_ClearInEditMode: 1 m_NoCameraWarning: 1 m_LowResolutionForAspectRatios: 00000000000000000000 m_XRRenderMode: 0 m_RenderTexture: {fileID: 0} m_showToolbar: 1 ---- !u!114 &13 +--- !u!114 &17 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -400,15 +504,15 @@ MonoBehaviour: m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Hierarchy - m_Image: {fileID: 7966133145522015247, guid: 0000000000000000d000000000000000, type: 0} + m_Image: {fileID: -3734745235275155857, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_TextWithWhitespace: "Hierarchy\u200B" m_Pos: serializedVersion: 2 x: 0 y: 24 - width: 303 - height: 473 + width: 282.33334 + height: 557.3333 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -425,7 +529,7 @@ MonoBehaviour: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 - m_ExpandedIDs: 1eb0f9ff12810100 + m_ExpandedIDs: 1827f5ff1c50f5ff1e50f5ff246af5ffb6b9f5ffc4dcf5ffe6f6f5ff1401f6ffe6d0f7fff0d0f7ff04d1f7ff22d1f7ff2ed1f7ff6cd1f7ff38eef7ff76fdf7ff88fdf7fff800f8ff245dfdff869bfdff20f9ffff38f9ffffcef9fffffaa100004ca200004209020066090200700902008a09020096090200bc090200c0090200c2090200 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -442,7 +546,7 @@ MonoBehaviour: m_OriginalEventType: 11 m_IsRenamingFilename: 0 m_TrimLeadingAndTrailingWhitespace: 0 - m_ClientGUIView: {fileID: 8} + m_ClientGUIView: {fileID: 9} m_SearchString: m_ExpandedScenes: [] m_CurrenRootInstanceID: 0 @@ -450,7 +554,43 @@ MonoBehaviour: m_IsLocked: 0 m_CurrentSortingName: TransformSorting m_WindowGUID: 4c969a2b90040154d917609493e03593 ---- !u!114 &14 +--- !u!114 &18 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bf7b24c075f77344995c29cff2449329, type: 3} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 50, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Animation Tester + m_Image: {fileID: 0} + m_Tooltip: + m_TextWithWhitespace: "Animation Tester\u200B" + m_Pos: + serializedVersion: 2 + x: 0 + y: 607.3333 + width: 282.33334 + height: 268 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_ContainerData: [] + m_OverlaysVisible: 1 +--- !u!114 &19 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -466,15 +606,15 @@ MonoBehaviour: m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Scene - m_Image: {fileID: 2593428753322112591, guid: 0000000000000000d000000000000000, type: 0} + m_Image: {fileID: 8634526014445323508, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_TextWithWhitespace: "Scene\u200B" m_Pos: serializedVersion: 2 - x: 305 - y: 24 - width: 1066 - height: 473 + x: 1198.6667 + y: 86 + width: 967.33325 + height: 534 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -489,11 +629,11 @@ MonoBehaviour: displayed: 0 id: Brush Attributes index: 0 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -556,14 +696,14 @@ MonoBehaviour: sizeOverridden: 0 - dockPosition: 1 containerId: overlay-toolbar__top - displayed: 0 + displayed: 1 id: unity-search-toolbar index: 3 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":0.0},"m_SnapOffsetDelta":{"x":0.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":25.333332061767579},"m_SnapOffsetDelta":{"x":0.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 - snapOffset: {x: 24, y: 0} - snapOffsetDelta: {x: 0, y: 25} + snapOffset: {x: 24, y: 25.333332} + snapOffsetDelta: {x: 0, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -573,11 +713,11 @@ MonoBehaviour: displayed: 0 id: Terrain Tools index: 0 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -587,11 +727,11 @@ MonoBehaviour: displayed: 0 id: Brush Masks index: 1 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -615,11 +755,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Lighting Visualization Colors index: 0 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -657,11 +797,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Open Tile Palette index: 0 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":0.0},"m_SnapOffsetDelta":{"x":0.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":25.333332061767579},"m_SnapOffsetDelta":{"x":0.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 - snapOffset: {x: 24, y: 0} - snapOffsetDelta: {x: 0, y: 25} + snapOffset: {x: 24, y: 25.333332} + snapOffsetDelta: {x: 0, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -671,11 +811,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Tile Palette Clipboard index: 1 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -699,11 +839,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Light Settings index: 3 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -713,11 +853,11 @@ MonoBehaviour: displayed: 0 id: Scene View/PBR Validation Settings index: 4 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -727,11 +867,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Cloth Constraints index: 5 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -741,11 +881,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Cloth Collisions index: 6 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -755,11 +895,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Tile Palette Brush Pick index: 7 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -769,11 +909,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Path index: 8 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -783,11 +923,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Sprite Swap index: 9 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":0.0},"m_SnapOffsetDelta":{"x":0.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":0.0},"m_SnapOffsetDelta":{"x":0.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 24, y: 0} - snapOffsetDelta: {x: 0, y: 25} + snapOffsetDelta: {x: 0, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -811,11 +951,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Physics Debugger index: 10 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -839,11 +979,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Occlusion Culling index: 11 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -853,11 +993,11 @@ MonoBehaviour: displayed: 0 id: Scene View/TrailRenderer index: 12 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":0.0},"m_SnapOffsetDelta":{"x":0.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":0.0},"m_SnapOffsetDelta":{"x":0.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 24, y: 0} - snapOffsetDelta: {x: 0, y: 25} + snapOffsetDelta: {x: 0, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -867,11 +1007,11 @@ MonoBehaviour: displayed: 0 id: Scene View/Scene Visibility index: 13 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":0.0,"y":0.0},"m_SnapOffsetDelta":{"x":24.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 0, y: 0} - snapOffsetDelta: {x: 24, y: 25} + snapOffsetDelta: {x: 24, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -881,11 +1021,11 @@ MonoBehaviour: displayed: 0 id: unity-spline-inspector index: 14 - contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":0.0},"m_SnapOffsetDelta":{"x":0.0,"y":25.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' + contents: '{"m_Layout":4,"m_Collapsed":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":24.0,"y":0.0},"m_SnapOffsetDelta":{"x":0.0,"y":0.0},"m_FloatingSnapCorner":0,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' floating: 0 collapsed: 0 snapOffset: {x: 24, y: 0} - snapOffsetDelta: {x: 0, y: 25} + snapOffsetDelta: {x: 0, y: 0} snapCorner: 0 layout: 4 size: {x: 0, y: 0} @@ -917,9 +1057,9 @@ MonoBehaviour: m_AudioPlay: 0 m_DebugDrawModesUseInteractiveLightBakingData: 0 m_Position: - m_Target: {x: 2.9752567, y: -13.428847, z: -0.047095235} + m_Target: {x: 18.246088, y: -15.302499, z: -0.026065793} speed: 2 - m_Value: {x: -0.32300702, y: -0.52712524, z: -0.0006722954} + m_Value: {x: 18.246088, y: -15.302499, z: -0.026065793} m_RenderMode: 0 m_CameraMode: drawMode: 0 @@ -969,9 +1109,9 @@ MonoBehaviour: speed: 2 m_Value: {x: 0, y: 0, z: 0, w: 1} m_Size: - m_Target: 8.02011 + m_Target: 12.606543 speed: 2 - m_Value: 1.189737 + m_Value: 12.606543 m_Ortho: m_Target: 1 speed: 2 @@ -992,7 +1132,7 @@ MonoBehaviour: m_LastSceneViewRotation: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} m_LastSceneViewOrtho: 0 m_Viewpoint: - m_SceneView: {fileID: 14} + m_SceneView: {fileID: 19} m_CameraOverscanSettings: m_Opacity: 50 m_Scale: 1 @@ -1005,96 +1145,7 @@ MonoBehaviour: name: Mipmaps section: Miscellaneous m_ViewIsLockedToObject: 0 ---- !u!114 &15 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 12914, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_MinSize: {x: 50, y: 50} - m_MaxSize: {x: 4000, y: 4000} - m_TitleContent: - m_Text: Animator - m_Image: {fileID: -1673928668082335149, guid: 0000000000000000d000000000000000, type: 0} - m_Tooltip: - m_TextWithWhitespace: "Animator\u200B" - m_Pos: - serializedVersion: 2 - x: 304 - y: 79 - width: 1066 - height: 473 - m_SerializedDataModeController: - m_DataMode: 0 - m_PreferredDataMode: 0 - m_SupportedDataModes: - isAutomatic: 1 - m_ViewDataDictionary: {fileID: 0} - m_OverlayCanvas: - m_LastAppliedPresetName: Default - m_SaveData: [] - m_ContainerData: [] - m_OverlaysVisible: 1 - m_ViewTransforms: - m_KeySerializationHelper: - - {fileID: -9164159964644277233, guid: 47d96364271d1944c8b2c9ed00c09341, type: 2} - - {fileID: 2322118417064100299, guid: d27cfabcb9360f84fb029e648a54a89e, type: 2} - m_ValueSerializationHelper: - - e00: 1.0064608 - e01: 0 - e02: 0 - e03: 119.83815 - e10: 0 - e11: 1.0064608 - e12: 0 - e13: 112.68998 - e20: 0 - e21: 0 - e22: 1 - e23: 0 - e30: 0 - e31: 0 - e32: 0 - e33: 1 - - e00: 0.78610367 - e01: 0 - e02: 0 - e03: -248.93912 - e10: 0 - e11: 0.78610367 - e12: 0 - e13: 278.5331 - e20: 0 - e21: 0 - e22: 1 - e23: 0 - e30: 0 - e31: 0 - e32: 0 - e33: 1 - m_PreviewAnimator: {fileID: 0} - m_AnimatorController: {fileID: 9100000, guid: d27cfabcb9360f84fb029e648a54a89e, type: 2} - m_BreadCrumbs: - - m_Target: {fileID: 2322118417064100299, guid: d27cfabcb9360f84fb029e648a54a89e, type: 2} - m_ScrollPosition: {x: 0, y: 0} - stateMachineGraph: {fileID: 0} - stateMachineGraphGUI: {fileID: 0} - blendTreeGraph: {fileID: 0} - blendTreeGraphGUI: {fileID: 0} - m_AutoLiveLink: 1 - m_MiniTool: 0 - m_LockTracker: - m_IsLocked: 0 - m_CurrentEditor: 0 - m_LayerEditor: - m_SelectedLayerIndex: 0 ---- !u!114 &16 +--- !u!114 &20 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1115,10 +1166,10 @@ MonoBehaviour: m_TextWithWhitespace: "Recorder\u200B" m_Pos: serializedVersion: 2 - x: 304 - y: 79 - width: 1066 - height: 473 + x: 1198.6667 + y: 86 + width: 967.33325 + height: 534 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1130,7 +1181,135 @@ MonoBehaviour: m_SaveData: [] m_ContainerData: [] m_OverlaysVisible: 1 ---- !u!114 &17 +--- !u!114 &21 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12914, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 50, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Animator + m_Image: {fileID: 1711060831702674872, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_TextWithWhitespace: "Animator\u200B" + m_Pos: + serializedVersion: 2 + x: 1190 + y: 647.3334 + width: 975.3334 + height: 294.6667 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_ContainerData: [] + m_OverlaysVisible: 1 + m_ViewTransforms: + m_KeySerializationHelper: + - {fileID: -2159016584420566100, guid: ba58731883bc8cb40be2ed19cc4be25a, type: 2} + - {fileID: 8178033774095782672, guid: 95f0b268d7716ae4fbf48e1e031c5006, type: 2} + m_ValueSerializationHelper: + - e00: 0.7091452 + e01: 0 + e02: 0 + e03: -77.02728 + e10: 0 + e11: 0.7091452 + e12: 0 + e13: 31.923752 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + - e00: 0.7092281 + e01: 0 + e02: 0 + e03: 12.288605 + e10: 0 + e11: 0.7092281 + e12: 0 + e13: 63.239998 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_PreviewAnimator: {fileID: 0} + m_AnimatorController: {fileID: 9100000, guid: ba58731883bc8cb40be2ed19cc4be25a, type: 2} + m_BreadCrumbs: + - m_Target: {fileID: -2159016584420566100, guid: ba58731883bc8cb40be2ed19cc4be25a, type: 2} + m_ScrollPosition: {x: 0, y: 0} + stateMachineGraph: {fileID: 0} + stateMachineGraphGUI: {fileID: 0} + blendTreeGraph: {fileID: 0} + blendTreeGraphGUI: {fileID: 0} + m_AutoLiveLink: 0 + m_MiniTool: 0 + m_LockTracker: + m_IsLocked: 0 + m_CurrentEditor: 1 + m_LayerEditor: + m_SelectedLayerIndex: 0 +--- !u!114 &22 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12071, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 50, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Animation + m_Image: {fileID: -3237396543322336831, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_TextWithWhitespace: "Animation\u200B" + m_Pos: + serializedVersion: 2 + x: 1 + y: 581.3333 + width: 967.33325 + height: 294 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_ContainerData: [] + m_OverlaysVisible: 1 + m_LockTracker: + m_IsLocked: 0 + m_LastSelectedObjectID: -716692 +--- !u!114 &23 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1146,15 +1325,15 @@ MonoBehaviour: m_MaxSize: {x: 10000, y: 10000} m_TitleContent: m_Text: Project - m_Image: {fileID: -5467254957812901981, guid: 0000000000000000d000000000000000, type: 0} + m_Image: {fileID: -5179483145760003458, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_TextWithWhitespace: "Project\u200B" m_Pos: serializedVersion: 2 x: 0 - y: 523 - width: 1371 - height: 408 + y: 901.3333 + width: 1251.6666 + height: 375.3333 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1187,16 +1366,16 @@ MonoBehaviour: m_ViewMode: 1 m_StartGridSize: 16 m_LastFolders: - - Assets/Prefabs/Characters/Enemies + - Assets/Scripts/Runtime/AI m_LastFoldersGridSize: 16 m_LastProjectPath: C:\Users\Nico\Desktop\Projects\[ Gamedev ]\TowerDefenseGame m_LockTracker: m_IsLocked: 0 m_FolderTreeState: - scrollPos: {x: 0, y: 239} - m_SelectedIDs: 6a190100 - m_LastClickedID: 72042 - m_ExpandedIDs: 00000000eea30000f0a30000f2a30000f4a30000f6a30000f8a30000faa30000fca30000fea3000000a4000002a4000004a4000006a4000008a400000aa400000ca400000ea4000010a4000012a4000014a4000016a4000018a40000 + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 03ca9a3b + m_LastClickedID: 1000000003 + m_ExpandedIDs: 00000000e8a50000eaa50000eca50000eea50000f0a50000f2a50000f4a50000f6a50000f8a50000faa50000fca50000fea5000000a6000002a6000004a6000006a6000008a600000aa600000ca600000ea6000010a6000012a6000014a6000016a6000018a600001aa600001ca600001ea6000020a6000022a6000024a6000026a6000028a600002aa60000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -1213,7 +1392,7 @@ MonoBehaviour: m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_TrimLeadingAndTrailingWhitespace: 0 - m_ClientGUIView: {fileID: 10} + m_ClientGUIView: {fileID: 14} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} @@ -1225,7 +1404,7 @@ MonoBehaviour: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 - m_ExpandedIDs: 00000000eea30000f0a30000f2a30000f4a30000f6a30000f8a30000faa30000fca30000fea3000000a4000002a4000004a4000006a4000008a400000aa400000ca400000ea4000010a4000012a4000014a4000016a4000018a40000 + m_ExpandedIDs: 00000000e8a50000eaa50000eca50000eea50000f0a50000f2a50000f4a50000f6a50000f8a50000faa50000fca50000fea5000000a6000002a6000004a6000006a6000008a600000aa600000ca600000ea6000010a6000012a6000014a6000016a6000018a600001aa600001ca600001ea6000020a6000022a6000024a6000026a6000028a600002aa60000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -1254,7 +1433,7 @@ MonoBehaviour: m_SelectedInstanceIDs: m_LastClickedInstanceID: 0 m_HadKeyboardFocusLastEvent: 1 - m_ExpandedInstanceIDs: c6230000ec950000f8950000da9500007a9f000010a90000000000004cd10000 + m_ExpandedInstanceIDs: c6230000ec950000f8950000da9500007a9f000010a900004cd100003ca30000000000005c2301005269010000680100ec670100f2670100586701007e670100c66701006c6701004a68010014680100cc05020034080200ea040200d4a200007e790200 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -1271,7 +1450,7 @@ MonoBehaviour: m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_TrimLeadingAndTrailingWhitespace: 0 - m_ClientGUIView: {fileID: 10} + m_ClientGUIView: {fileID: 14} m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 @@ -1282,8 +1461,8 @@ MonoBehaviour: m_ScrollPosition: {x: 0, y: 0} m_GridSize: 16 m_SkipHiddenPackages: 0 - m_DirectoriesAreaWidth: 292.33334 ---- !u!114 &18 + m_DirectoriesAreaWidth: 292.3333 +--- !u!114 &24 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1299,15 +1478,15 @@ MonoBehaviour: m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Console - m_Image: {fileID: -4327648978806127646, guid: 0000000000000000d000000000000000, type: 0} + m_Image: {fileID: -4950941429401207979, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_TextWithWhitespace: "Console\u200B" m_Pos: serializedVersion: 2 - x: 0 - y: 578 - width: 1371 - height: 408 + x: 915.3334 + y: 967.3334 + width: 1251.6666 + height: 377.33344 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1319,46 +1498,7 @@ MonoBehaviour: m_SaveData: [] m_ContainerData: [] m_OverlaysVisible: 1 ---- !u!114 &19 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 12071, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_MinSize: {x: 50, y: 50} - m_MaxSize: {x: 4000, y: 4000} - m_TitleContent: - m_Text: Animation - m_Image: {fileID: -8166618308981325432, guid: 0000000000000000d000000000000000, type: 0} - m_Tooltip: - m_TextWithWhitespace: "Animation\u200B" - m_Pos: - serializedVersion: 2 - x: 0 - y: 578 - width: 1371 - height: 408 - m_SerializedDataModeController: - m_DataMode: 0 - m_PreferredDataMode: 0 - m_SupportedDataModes: - isAutomatic: 1 - m_ViewDataDictionary: {fileID: 0} - m_OverlayCanvas: - m_LastAppliedPresetName: Default - m_SaveData: [] - m_ContainerData: [] - m_OverlaysVisible: 1 - m_LockTracker: - m_IsLocked: 0 - m_LastSelectedObjectID: 71318 ---- !u!114 &20 +--- !u!114 &25 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1379,10 +1519,10 @@ MonoBehaviour: m_TextWithWhitespace: "Unity Version Control\u200B" m_Pos: serializedVersion: 2 - x: 0 - y: 578 - width: 1371 - height: 408 + x: 915.3334 + y: 1010 + width: 1250.3334 + height: 334.66675 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1395,7 +1535,7 @@ MonoBehaviour: m_ContainerData: [] m_OverlaysVisible: 1 mForceToReOpen: 0 ---- !u!114 &21 +--- !u!114 &26 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1411,15 +1551,15 @@ MonoBehaviour: m_MaxSize: {x: 4000, y: 4000} m_TitleContent: m_Text: Inspector - m_Image: {fileID: -2667387946076563598, guid: 0000000000000000d000000000000000, type: 0} + m_Image: {fileID: -440750813802333266, guid: 0000000000000000d000000000000000, type: 0} m_Tooltip: m_TextWithWhitespace: "Inspector\u200B" m_Pos: serializedVersion: 2 - x: 1373 + x: 1253.6666 y: 24 - width: 547 - height: 907 + width: 389.66675 + height: 1252.6666 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1438,9 +1578,55 @@ MonoBehaviour: m_ControlHash: -371814159 m_PrefName: Preview_InspectorPreview m_LastInspectedObjectInstanceID: -1 - m_LastVerticalScrollValue: 394 + m_LastVerticalScrollValue: 0 m_GlobalObjectId: m_InspectorMode: 0 m_LockTracker: m_IsLocked: 0 m_PreviewWindow: {fileID: 0} +--- !u!114 &27 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 13961, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 275, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Player + m_Image: {fileID: 7853449062886713960, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: HomeTown/Player + m_TextWithWhitespace: "Player\u200B" + m_Pos: + serializedVersion: 2 + x: 2168 + y: 86 + width: 389.66675 + height: 1258.6667 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_ContainerData: [] + m_OverlaysVisible: 1 + m_ObjectsLockedBeforeSerialization: [] + m_InstanceIDsLockedBeforeSerialization: + m_PreviewResizer: + m_CachedPref: 151 + m_ControlHash: 1412526313 + m_PrefName: Preview_InspectorPreview + m_LastInspectedObjectInstanceID: -536274 + m_LastVerticalScrollValue: 0 + m_GlobalObjectId: GlobalObjectId_V1-2-2cda990e2423bbf4892e6590ba056729-9147163641451663911-2316236105731553357 + m_InspectorMode: 0