From 6eaccc9004c47d97005b327399293c915a72f8df Mon Sep 17 00:00:00 2001 From: Grayson Earle Date: Tue, 6 Nov 2018 12:02:23 -0500 Subject: [PATCH] w9 --- unity-demos/Assets/NavMesh.meta | 8 + unity-demos/Assets/NavMesh/Grey.mat | 76 +++ unity-demos/Assets/NavMesh/Grey.mat.meta | 8 + unity-demos/Assets/NavMesh/NavMesh.meta | 8 + unity-demos/Assets/NavMesh/NavMesh.unity | 258 ++++++++++ unity-demos/Assets/NavMesh/NavMesh.unity.meta | 7 + .../NavMesh/NavMesh/NavMesh-NavMesh.asset | Bin 0 -> 10060 bytes .../NavMesh/NavMesh-NavMesh.asset.meta | 8 + .../Assets/NavMesh/NavMeshComponents.meta | 8 + .../NavMesh/NavMeshComponents/Editor.meta | 10 + .../Editor/NavMeshComponentsGUIUtility.cs | 258 ++++++++++ .../NavMeshComponentsGUIUtility.cs.meta | 13 + .../Editor/NavMeshLinkEditor.cs | 279 ++++++++++ .../Editor/NavMeshLinkEditor.cs.meta | 13 + .../Editor/NavMeshModifierEditor.cs | 49 ++ .../Editor/NavMeshModifierEditor.cs.meta | 13 + .../Editor/NavMeshModifierVolumeEditor.cs | 146 ++++++ .../NavMeshModifierVolumeEditor.cs.meta | 13 + .../Editor/NavMeshSurfaceEditor.cs | 485 ++++++++++++++++++ .../Editor/NavMeshSurfaceEditor.cs.meta | 13 + .../NavMesh/NavMeshComponents/Scripts.meta | 10 + .../NavMeshComponents/Scripts/NavMeshLink.cs | 172 +++++++ .../Scripts/NavMeshLink.cs.meta | 13 + .../Scripts/NavMeshModifier.cs | 54 ++ .../Scripts/NavMeshModifier.cs.meta | 13 + .../Scripts/NavMeshModifierVolume.cs | 54 ++ .../Scripts/NavMeshModifierVolume.cs.meta | 13 + .../Scripts/NavMeshSurface.cs | 426 +++++++++++++++ .../Scripts/NavMeshSurface.cs.meta | 13 + .../Assets/NavMesh/PlayerController.cs | 34 ++ .../Assets/NavMesh/PlayerController.cs.meta | 11 + unity-demos/Assets/NavMesh/Purple.mat | 76 +++ unity-demos/Assets/NavMesh/Purple.mat.meta | 8 + week09/readme.md | 91 ++++ 34 files changed, 2661 insertions(+) create mode 100644 unity-demos/Assets/NavMesh.meta create mode 100644 unity-demos/Assets/NavMesh/Grey.mat create mode 100644 unity-demos/Assets/NavMesh/Grey.mat.meta create mode 100644 unity-demos/Assets/NavMesh/NavMesh.meta create mode 100644 unity-demos/Assets/NavMesh/NavMesh.unity create mode 100644 unity-demos/Assets/NavMesh/NavMesh.unity.meta create mode 100644 unity-demos/Assets/NavMesh/NavMesh/NavMesh-NavMesh.asset create mode 100644 unity-demos/Assets/NavMesh/NavMesh/NavMesh-NavMesh.asset.meta create mode 100644 unity-demos/Assets/NavMesh/NavMeshComponents.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshLinkEditor.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshLinkEditor.cs.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierEditor.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierEditor.cs.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshLink.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshLink.cs.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifier.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifier.cs.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifierVolume.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifierVolume.cs.meta create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshSurface.cs create mode 100755 unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshSurface.cs.meta create mode 100644 unity-demos/Assets/NavMesh/PlayerController.cs create mode 100644 unity-demos/Assets/NavMesh/PlayerController.cs.meta create mode 100644 unity-demos/Assets/NavMesh/Purple.mat create mode 100644 unity-demos/Assets/NavMesh/Purple.mat.meta create mode 100644 week09/readme.md diff --git a/unity-demos/Assets/NavMesh.meta b/unity-demos/Assets/NavMesh.meta new file mode 100644 index 0000000..d8006d7 --- /dev/null +++ b/unity-demos/Assets/NavMesh.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c3908cec6daa94204b9fee51caf71c36 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/Grey.mat b/unity-demos/Assets/NavMesh/Grey.mat new file mode 100644 index 0000000..7d22d98 --- /dev/null +++ b/unity-demos/Assets/NavMesh/Grey.mat @@ -0,0 +1,76 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: Grey + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/unity-demos/Assets/NavMesh/Grey.mat.meta b/unity-demos/Assets/NavMesh/Grey.mat.meta new file mode 100644 index 0000000..27b595d --- /dev/null +++ b/unity-demos/Assets/NavMesh/Grey.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c3bd99f50810446c38afb2793ae0e13e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMesh.meta b/unity-demos/Assets/NavMesh/NavMesh.meta new file mode 100644 index 0000000..6ecb5f4 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMesh.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8d329cc21ef00464cae1725e265a1756 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMesh.unity b/unity-demos/Assets/NavMesh/NavMesh.unity new file mode 100644 index 0000000..0909fb4 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMesh.unity @@ -0,0 +1,258 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &589612585 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 589612587} + - component: {fileID: 589612586} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &589612586 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 589612585} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &589612587 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 589612585} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &802529696 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 802529699} + - component: {fileID: 802529698} + - component: {fileID: 802529697} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &802529697 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 802529696} + m_Enabled: 1 +--- !u!20 &802529698 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 802529696} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &802529699 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 802529696} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/unity-demos/Assets/NavMesh/NavMesh.unity.meta b/unity-demos/Assets/NavMesh/NavMesh.unity.meta new file mode 100644 index 0000000..0f552e1 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMesh.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a3ed31cefb9d4404ba15f3f9857a02ef +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMesh/NavMesh-NavMesh.asset b/unity-demos/Assets/NavMesh/NavMesh/NavMesh-NavMesh.asset new file mode 100644 index 0000000000000000000000000000000000000000..5dc8a092f787318ec1cb19681e7ea861daacc9c0 GIT binary patch literal 10060 zcmbVSYmAiT6@F(gu&xWc3+%$O%C6MPO)d+FSQTbrQM8B%%+_jU8Fpu3WN*&SDqt^D zThZ3mVvT7_VhYikb|8(>kp3~UCT*IS+DjV$l%%a`=ntE;HcgY7UbfG3&U@bPn{TB` zU-;%b=Q-zn-urpa3^>>HkaJ6RIOm$3YdV3qTf3%fVyvmh+423+k;?FvjJTnBJ z&NDOMDYqT`XTZb$vyD_qcv4;H4}zvrI{z%u&EyT_L%@I4-1 zmcaLUe0c)Tdz|Mr-tJM4U!TCg;qjF*oN?fJkFSd1r-7gK`05x=|8pK+lfV%l9Ot1c zfxqSPwK4p6z~0A$ziu7z66I>y=Tjc%Ic`c5*K<7+0gUI4YvAX<;@oWr{*`e9@zT#v zwVMYHo;&XSjRCK57jYgJ!^W6#li;0bwN}<~1#ph*6A65!$8S#Ht37^8z-!!5#Lq6z zf2-geS8YWc-UPhal?0E+;mrZpdAJokoQE`dO5~}kn1^oSlf*0MVGD6Q#CL$h;u~X~ z@@Ra!-}CnbyfVIRBc3KtWqiAhI3D7hPx5mClb z`}s-YCAM4H&mF|m)BAZBaXi+4_LJ+oGvL%*X$<__CwB+DR>p<3lzp;GaE@z6#klTC z;5M$^3EalT`=rT{NBJM~{Cfjl$)8E!#^0O3jsH^t*Li!&&)dDkOPq(wdHXc+bTmJ9 z|K3L&56Al~I5=;e(C-iUOqrh-eg8irILB32F+UF^aO?lR1aAHB3%K%s-}CPecqM-} zfgAsU1aAEO0iP-7@htec0|o@=coqMl$8!PK^Y}7wo=3U2OZ2Zij|b_WCSG|S4+WlT zcOD!zpZS1mT>3R^JV&sHeR3LeZ*l2x0=MxFC2$)r^9bE<%74N0j|99j?u{mJ;~z`l z#{W>jYh>Nu0YB%nAUNlt#yy4j@Gfxtb>lJo6!5++?5qg~9~QsCTgUk-R>yN@SuYxj5p zw|1WhcuLOKI^QnyP?nw9hwsXbAL_{#vu@X}V&Rr;1Nq`;VcU^nZe%<^IGK}BeW`vT+k?D(OswHr~Dk~?s;m>a);%>!QOGGVO=>r7a0 z!VM;DFyTfMHkxpg30)C&;O+|KU4gwT(075~4`$0merRA%u2{^E92`fFKM>9y%#9TH z9v$O+h`c*Hke?V=d3!E@@K90ZJwu~oITg1K<%bWrq1?d1Tu)(i%zF)IkK8#iJl5S` z7#$z)$&VMaBmFryoFCbpJBWGjF66RqI6E?t9om{38rqXTmUI0kD9#BNyl6tUzki~T zE#`I&W&3l(=xN2+dU6LQ4u$~^P~+kbWo5Y9t>Nt0xC^2z=h*0YzK9;VBkrg>=8CyO zA)6oZE3K|vZ)}7}@z&m4p_uQ7Ww`H-kpVAl8J!pzAhZ=7%oQNWW-CJ2IXX~5v!#~^ zCk0b+#N{2{eRmHIvb`Pok;CJzd!jfR1AM!CirE7Bwv7zn(=X9*AFFWffa&xK(vvUb z`elH_eS1bH3jMjz!`-9BtXLjFm0dOus2$q{5(b@{Tzc3`&b`*EXX|o58>92M((gWr z5%1y5_IB^=;r-9Mj)mNHc;@&wb$*AY4Y%||)4 zF8wo^bHW*y@69}S-l0y!qkW@~;qqLZHAY3|6n-U1`d=U z-ZL3zx~bdy1o>>aeEv-NUGbsp-0wxcH}iIo&zA3;G#`ya$`h9vhn)MR)TMl;ynHj; zV$8!^aLUf5r^(8raVsu!KF^fPn`~SrGxmUAc<5uClnkd&6n$v1lNOzC#x9LpwCawH zOM1SDXyG1bp{MR2o~=0_)fgA?x4DI`-Pb2`qpQJZ#NY1b1$Oq1cP)#JUo}G%w^g?F zq1CUDxN{9`^*${A(o@^i*sb?GTi4%Jtu0+6^=T2S`e>9=oWHBEhnF9dE#~WOs~oi- zIo9j0)H{Q>?WNlPsD4(TySc_~!2auSe~`FHyVQvn0DoFm2*SAHP&9FFF;M^aFLyRm3Nbk zk9VQ!%Vm6QKd!U?yajFiT>T}eUn_T0hnzs#>)bU`-~3JI+%JOtN^j>JYyAyCI~?1K z^adGkq}NLfQ~i4QH=t$bmg2Jo>%;nNPxY0e^E_M+`+Tuq<)Z??Sa~(Q;_J^I-ckFf zSMf4)jO&@vd|16KA3l|Kk`Kpo&Uh|r@(K89uFJd6 z`CJrt+~#t*evkJdLtkQx@7OGY_s4PoiX~q9AtGpM_mo>t`;C)RDawbuIp}rpC00 zKYo{x9USNkKtx@nlHX|eu!6)){q)H{oois%iZvaUH9EO%C%=Z7tG-0}RC)(^^4 zKdPVA*WNQvYDkjfPS2jotY`TbWt`!V=f?Bjn2ffA&*n4bH)H&ow`#kZ&$6v}ZVQ|E zvn7-16ZN4JBPI%=f9olC>M@owiVTtIq`M(<9*J{C-Am*8Jjfc?akbPw(5ny zQhpr%)-L@m2d5mx6o)dSR8ztW==7Mv?~UAREVNVpu$ZFXo;9nRQ9=b@jGvilBW@%X z#%5sE@XuTsu)9(iA zWBDuj`F)ptrq}-y-;?!{I(x!g4&WJKuF2hP_mS$%h4nt7UgzzceYI=*%mr0vF4-ve z5%qfUZI7{9VpTp= 0 && areaIndex < areaNames.Length - 2) + areaProperty.intValue = GameObjectUtility.GetNavMeshAreaFromName(areaNames[areaIndex]); + else if (areaIndex == areaNames.Length - 1) + NavMeshEditorHelpers.OpenAreaSettings(); + } + + EditorGUI.EndProperty(); + } + + public static void AgentTypePopup(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) + { + EditorGUILayout.HelpBox("Agent Type invalid.", MessageType.Warning); + } + + var rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); + 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/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs.meta new file mode 100755 index 0000000..8146098 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshComponentsGUIUtility.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 15548e45f29cdba49aea85acca959a91 +timeCreated: 1520502094 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshLinkEditor.cs b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshLinkEditor.cs new file mode 100755 index 0000000..cc4941b --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshLinkEditor.cs @@ -0,0 +1,279 @@ +using UnityEngine; +using UnityEngine.AI; + +namespace UnityEditor.AI +{ + [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; + + NavMeshVisualizationSettings.showNavigation++; + } + + void OnDisable() + { + NavMeshVisualizationSettings.showNavigation--; + } + + 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(); + + NavMeshComponentsGUIUtility.AgentTypePopup("Agent Type", 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); + + NavMeshComponentsGUIUtility.AreaPopup("Area Type", 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.Selected | GizmoType.Active | GizmoType.Pickable)] + static void RenderBoxGizmo(NavMeshLink navLink, GizmoType gizmoType) + { + if (!EditorApplication.isPlaying) + 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 (NavMeshVisualizationSettings.showNavigation > 0) + { + 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/AI/NavMesh Link", false, 2002)] + static public 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/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshLinkEditor.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshLinkEditor.cs.meta new file mode 100755 index 0000000..a6cf2f9 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshLinkEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 2736c3ce72815474a841d00c8558a7a3 +timeCreated: 1520502094 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierEditor.cs b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierEditor.cs new file mode 100755 index 0000000..a2c636c --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierEditor.cs @@ -0,0 +1,49 @@ +using UnityEngine.AI; + +namespace UnityEditor.AI +{ + [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"); + + NavMeshVisualizationSettings.showNavigation++; + } + + void OnDisable() + { + NavMeshVisualizationSettings.showNavigation--; + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_IgnoreFromBuild); + + EditorGUILayout.PropertyField(m_OverrideArea); + if (m_OverrideArea.boolValue) + { + EditorGUI.indentLevel++; + NavMeshComponentsGUIUtility.AreaPopup("Area Type", m_Area); + EditorGUI.indentLevel--; + } + + NavMeshComponentsGUIUtility.AgentMaskPopup("Affected Agents", m_AffectedAgents); + EditorGUILayout.Space(); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierEditor.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierEditor.cs.meta new file mode 100755 index 0000000..eeaa72a --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: a8c4288ef2e341e4bab85c37922622c0 +timeCreated: 1520502095 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs new file mode 100755 index 0000000..c8f1778 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs @@ -0,0 +1,146 @@ +using UnityEditor.IMGUI.Controls; +using UnityEditorInternal; +using UnityEngine.AI; +using UnityEngine; + +namespace UnityEditor.AI +{ + [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"); + + NavMeshVisualizationSettings.showNavigation++; + } + + void OnDisable() + { + NavMeshVisualizationSettings.showNavigation--; + } + + 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); + + NavMeshComponentsGUIUtility.AreaPopup("Area Type", m_Area); + NavMeshComponentsGUIUtility.AgentMaskPopup("Affected Agents", m_AffectedAgents); + EditorGUILayout.Space(); + + serializedObject.ApplyModifiedProperties(); + } + + [DrawGizmo(GizmoType.Selected | 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) + { + if (NavMeshVisualizationSettings.showNavigation > 0) + { + 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/AI/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/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs.meta new file mode 100755 index 0000000..8e98be4 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshModifierVolumeEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 6ce39e93768aa7e4199db30718f1c264 +timeCreated: 1520502095 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs new file mode 100755 index 0000000..ad255de --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs @@ -0,0 +1,485 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor.IMGUI.Controls; +using UnityEditor.SceneManagement; +using UnityEditorInternal; +using UnityEngine.AI; +using UnityEngine; + +namespace UnityEditor.AI +{ + [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; + + class Styles + { + public readonly GUIContent m_LayerMask = new GUIContent("Include Layers"); + + 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"); + } + + struct AsyncBakeOperation + { + public NavMeshSurface surface; + public NavMeshData bakeData; + public AsyncOperation bakeOperation; + } + + static List s_BakeOperations = new List(); + + 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"); + + NavMeshVisualizationSettings.showNavigation++; + } + + void OnDisable() + { + NavMeshVisualizationSettings.showNavigation--; + } + + 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)); + 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); + } + + static NavMeshData GetNavMeshAssetToDelete(NavMeshSurface navSurface) + { + var prefabType = PrefabUtility.GetPrefabType(navSurface); + if (prefabType == PrefabType.PrefabInstance || prefabType == PrefabType.DisconnectedPrefabInstance) + { + // 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; + } + return navSurface.navMeshData; + } + + void ClearSurface(NavMeshSurface navSurface) + { + var assetToDelete = GetNavMeshAssetToDelete(navSurface); + navSurface.RemoveData(); + navSurface.navMeshData = null; + EditorUtility.SetDirty(navSurface); + + if (assetToDelete) + { + AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(assetToDelete)); + EditorSceneManager.MarkSceneDirty(navSurface.gameObject.scene); + } + } + + 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); + } + NavMeshComponentsGUIUtility.AgentTypePopup("Agent Type", 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(); + + EditorGUILayout.Space(); + + m_OverrideVoxelSize.isExpanded = EditorGUILayout.Foldout(m_OverrideVoxelSize.isExpanded, "Advanced"); + if (m_OverrideVoxelSize.isExpanded) + { + EditorGUI.indentLevel++; + + NavMeshComponentsGUIUtility.AreaPopup("Default Area", 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 in overal.", MessageType.None); + } + EditorGUI.indentLevel--; + } + + + // Height mesh + using (new EditorGUI.DisabledScope(true)) + { + EditorGUILayout.PropertyField(m_BuildHeightMesh); + } + + 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(); + + using (new EditorGUI.DisabledScope(Application.isPlaying || m_AgentTypeID.intValue == -1)) + { + GUILayout.BeginHorizontal(); + GUILayout.Space(EditorGUIUtility.labelWidth); + if (GUILayout.Button("Clear")) + { + foreach (NavMeshSurface s in targets) + ClearSurface(s); + SceneView.RepaintAll(); + } + + if (GUILayout.Button("Bake")) + { + // Remove first to avoid double registration of the callback + EditorApplication.update -= UpdateAsyncBuildOperations; + EditorApplication.update += UpdateAsyncBuildOperations; + + foreach (NavMeshSurface surf in targets) + { + var oper = new AsyncBakeOperation(); + + oper.bakeData = InitializeBakeData(surf); + oper.bakeOperation = surf.UpdateNavMesh(oper.bakeData); + oper.surface = surf; + + s_BakeOperations.Add(oper); + } + } + + GUILayout.EndHorizontal(); + } + + // Show progress for the selected targets + for (int i = s_BakeOperations.Count - 1; i >= 0; --i) + { + if (!targets.Contains(s_BakeOperations[i].surface)) + continue; + + var oper = s_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 = s_BakeOperations[i].bakeData; + UnityEngine.AI.NavMeshBuilder.Cancel(bakeData); + s_BakeOperations.RemoveAt(i); + } + + EditorGUI.ProgressBar(EditorGUILayout.GetControlRect(), p, "Baking: " + (int)(100 * p) + "%"); + if (p <= 1) + Repaint(); + + GUILayout.EndHorizontal(); + } + } + + 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); + } + + static void UpdateAsyncBuildOperations() + { + foreach (var oper in s_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(); + surface.navMeshData = oper.bakeData; + if (surface.isActiveAndEnabled) + surface.AddData(); + CreateNavMeshAsset(surface); + EditorSceneManager.MarkSceneDirty(surface.gameObject.scene); + } + } + s_BakeOperations.RemoveAll(o => o.bakeOperation == null || o.bakeOperation.isDone); + if (s_BakeOperations.Count == 0) + EditorApplication.update -= UpdateAsyncBuildOperations; + } + + [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); + } + + 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/AI/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/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs.meta new file mode 100755 index 0000000..4576613 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Editor/NavMeshSurfaceEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: b109366e8e12f3f448cc2f2576df102a +timeCreated: 1520502095 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts.meta new file mode 100755 index 0000000..ce8643c --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ce138f3bd105d8049b1020fee879265f +folderAsset: yes +timeCreated: 1520502094 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshLink.cs b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshLink.cs new file mode 100755 index 0000000..6a92103 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshLink.cs @@ -0,0 +1,172 @@ +using System.Collections.Generic; + +namespace UnityEngine.AI +{ + [ExecuteInEditMode] + [DefaultExecutionOrder(-101)] + [AddComponentMenu("Navigation/NavMeshLink", 33)] + [HelpURL("https://github.com/Unity-Technologies/NavMeshComponents#documentation-draft")] + public class NavMeshLink : MonoBehaviour + { + [SerializeField] + 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] + 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/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshLink.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshLink.cs.meta new file mode 100755 index 0000000..65f8f17 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshLink.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: fd3f0c8df3e6f2f41a45b75127c00b31 +timeCreated: 1520502095 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifier.cs b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifier.cs new file mode 100755 index 0000000..f32e80c --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifier.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; + +namespace UnityEngine.AI +{ + [ExecuteInEditMode] + [AddComponentMenu("Navigation/NavMeshModifier", 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] + 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/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifier.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifier.cs.meta new file mode 100755 index 0000000..1520b9b --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifier.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 6d07ce676d7afda4dabb3b0f7dd5e654 +timeCreated: 1520502095 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifierVolume.cs b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifierVolume.cs new file mode 100755 index 0000000..faa7e63 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifierVolume.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; + +namespace UnityEngine.AI +{ + [ExecuteInEditMode] + [AddComponentMenu("Navigation/NavMeshModifierVolume", 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] + 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/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifierVolume.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifierVolume.cs.meta new file mode 100755 index 0000000..c8aa899 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshModifierVolume.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 2777bba7e4e7c6f4681e3ea77eef5438 +timeCreated: 1520502094 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshSurface.cs b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshSurface.cs new file mode 100755 index 0000000..66377b0 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshSurface.cs @@ -0,0 +1,426 @@ +using System.Collections.Generic; + +namespace UnityEngine.AI +{ + public enum CollectObjects + { + All = 0, + Volume = 1, + Children = 2, + } + + [ExecuteInEditMode] + [DefaultExecutionOrder(-102)] + [AddComponentMenu("Navigation/NavMeshSurface", 30)] + [HelpURL("https://github.com/Unity-Technologies/NavMeshComponents#documentation-draft")] + public class NavMeshSurface : MonoBehaviour + { + [SerializeField] + 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] + 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; } } + + // 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; + + static readonly List s_NavMeshSurfaces = new List(); + + public static List activeSurfaces + { + get { return s_NavMeshSurfaces; } + } + + void OnEnable() + { + Register(this); + AddData(); + } + + void OnDisable() + { + RemoveData(); + Unregister(this); + } + + public void AddData() + { + 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) + { + 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; + } + return buildSettings; + } + + public void BuildNavMesh() + { + var sources = CollectSources(); + + // 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); + } + + 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(); + } + } + + public AsyncOperation UpdateNavMesh(NavMeshData data) + { + var sources = CollectSources(); + + // 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); + + return NavMeshBuilder.UpdateNavMeshDataAsync(data, GetBuildSettings(), sources, sourcesBounds); + } + + static void Register(NavMeshSurface surface) + { + 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) + { + // 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; + 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() + { + 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 (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); + } + + 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)); + } + + 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); + } + + 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(); + 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: + { + // Terrain pivot is lower/left corner - shift bounds accordingly + var t = src.sourceObject as TerrainData; + result.Encapsulate(GetWorldBounds(worldToLocal * src.transform, new Bounds(0.5f * t.size, t.size))); + break; + } + case NavMeshBuildSourceShape.Box: + case NavMeshBuildSourceShape.Sphere: + case NavMeshBuildSourceShape.Capsule: + 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 prefabType = UnityEditor.PrefabUtility.GetPrefabType(this); + if (prefabType == UnityEditor.PrefabType.Prefab) + 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()) + { + 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/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshSurface.cs.meta b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshSurface.cs.meta new file mode 100755 index 0000000..bc0ef77 --- /dev/null +++ b/unity-demos/Assets/NavMesh/NavMeshComponents/Scripts/NavMeshSurface.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 3df27b9289d1e8c4fb82e0df4f4673ba +timeCreated: 1520502095 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/PlayerController.cs b/unity-demos/Assets/NavMesh/PlayerController.cs new file mode 100644 index 0000000..8ab7c54 --- /dev/null +++ b/unity-demos/Assets/NavMesh/PlayerController.cs @@ -0,0 +1,34 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; // note this! + +public class PlayerController : MonoBehaviour { + + // reference the camera + public Camera cam; + + // reference to our player with the agent script attached + public NavMeshAgent agent; + + void Update () { + // right click + if(Input.GetMouseButtonDown(1)) { + // create a ray that fires from camera and intersects with + // GameObjects + Ray ray = cam.ScreenPointToRay(Input.mousePosition); + + RaycastHit hit; // we will store data about what the ray hits here + + // check if our ray hit anything at all first... + // and if it did, execute some more code and store the raycast hit + // data to the "hit" variable we created + if(Physics.Raycast(ray, out hit) == true) { + + // ok, so we hit something and we have data about where the ray hit + // so move the agent + agent.SetDestination(hit.point); + } + } + } +} diff --git a/unity-demos/Assets/NavMesh/PlayerController.cs.meta b/unity-demos/Assets/NavMesh/PlayerController.cs.meta new file mode 100644 index 0000000..9b94e9c --- /dev/null +++ b/unity-demos/Assets/NavMesh/PlayerController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5275bd01f220a416fa30e4aadcf8bf1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity-demos/Assets/NavMesh/Purple.mat b/unity-demos/Assets/NavMesh/Purple.mat new file mode 100644 index 0000000..e0e1cd3 --- /dev/null +++ b/unity-demos/Assets/NavMesh/Purple.mat @@ -0,0 +1,76 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: Purple + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/unity-demos/Assets/NavMesh/Purple.mat.meta b/unity-demos/Assets/NavMesh/Purple.mat.meta new file mode 100644 index 0000000..e6a404e --- /dev/null +++ b/unity-demos/Assets/NavMesh/Purple.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b3c297164de31468785b4410ebd58969 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/week09/readme.md b/week09/readme.md new file mode 100644 index 0000000..1a4b63a --- /dev/null +++ b/week09/readme.md @@ -0,0 +1,91 @@ +# week09 + +## Announcements + +## Tuesday + ++ Show Project 2: World Building + ++ Discuss + + [Ian Cheng's Emissaries](https://www.youtube.com/watch?v=TO6Luilc4Bo) + + How does something like Live Simulation fit into a trajectory of art history? + + In what ways does this differ from painting? In what ways does it differ from Video Art? + + Is it important that it happens live, as opposed to rendering and saving a file of an instance of the simulation? + + + [Humans of Simulated New York](https://spaceandtim.es/projects/hosny/) + + The Founder + ++ NavMesh demo from [Brackeys](https://www.youtube.com/watch?v=CHV1ymlw-P8) + + Create an Empty Gameobject "Level" + + As children to this object, create "Ground" which is the walkable surface, I suggest a Cube rather than Plane + + ...and another Empty Gameobject "Walls" that contain a number of obstacles + + Create a Cylinder and name it "Player", place it exactly on top of your ground + + Create an Empty Gameobject "NavMesh" and reset to 0,0,0 + + Add the NavMeshSurface script to this and click "bake" + + Because the player is considered an obstacle at first, create a layer for the Player that the NavMesh can ignore + + Select Player and in the Inspector, create a new layer called "Player" + + On the NavMesh, disable the layer on the Include Layers portion of the script + + Re-bake the NavMesh + + Note that in the NavMesh, you can either generate the walkable areas by colliders or renderers + + Under NavMesh, click Agent Type->Open Agent Settings + + Click the plus sign to create a new agent type + + Adjust the values, play around, take note of step and slope settings, as well as size + + Let's assume we don't want our walls to be walkable + + Select Walls and add NavMeshModifier script + + Enable "Ignore From Build" and re-bake NavMesh to see the effect (the walls are no longer considered obstacles) + + Disable "Ignore From Build" and instead enable "Override Area" + + Change the Area Type to "Not Walkable" and re-bake NavMesh + + Now we can begin moving the player + + Watch [how Camera Ray Casting works](https://youtu.be/CHV1ymlw-P8?t=337) + + Click the Player Gameobject + + Add NavMeshAgent to Player Gameobject + + Create a PlayerController.cs script and add it to Player (code below) + +PlayerController.cs +```C# +using UnityEngine; +using UnityEngine.AI; // note this! + +public class PlayerController : MonoBehaviour { + + // reference the camera + public Camera cam; + + // reference to our player with the agent script attached + public NavMeshAgent agent; + + void Update () { + // right click + if(Input.GetMouseButtonDown(1)) { + // create a ray that fires from camera and intersects with + // GameObjects + Ray ray = cam.ScreenPointToRay(Input.mousePosition); + + RaycastHit hit; // we will store data about what the ray hits here + + // check if our ray hit anything at all first... + // and if it did, execute some more code and store the raycast hit + // data to the "hit" variable we created + if(Physics.Raycast(ray, out hit) == true) { + + // ok, so we hit something and we have data about where the ray hit + // so move the agent + agent.SetDestination(hit.point); + } + } + } +} +``` + +## Thursday + + + +## Unity Tutorial(s) for this week + ++ [Unity NavMesh Tutorial - Basics](https://www.youtube.com/watch?v=CHV1ymlw-P8) ++ [Unity NavMesh Tutorial - Making it Dynamic](https://www.youtube.com/watch?v=FkLJ45Pt-mY) + +## Homework + ++ Project 2 due Tuesday 11/6