commit
This commit is contained in:
24
.idea/.idea.BABA_YAGA/.idea/workspace.xml
generated
24
.idea/.idea.BABA_YAGA/.idea/workspace.xml
generated
@@ -12,19 +12,17 @@
|
|||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="d308d1cb-09fc-4331-ba20-00f7b43d1576" name="Changes" comment="">
|
<list default="true" id="d308d1cb-09fc-4331-ba20-00f7b43d1576" name="Changes" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/HallDoubleRoom Extend.prefab" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/HallDoubleRoom Extend.prefab" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Materials/Red.mat" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Materials/Red.mat" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/MazeRework.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/MazeRework.asset" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Materials/Separator.mat" beforeDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/Turn.prefab" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/Turn.prefab" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Materials/Separator.mat.meta" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Materials/Transparency.mat" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Materials/Transparency.mat.meta" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/MazeRework.asset" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/MazeRework.asset.meta" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkConfig.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkConfig.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkGenerator.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkGenerator.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkManager.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkManager.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkManager.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkManager.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkSpawner.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkSpawner.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkSpawner.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkSpawner.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/Network/BasicSpawner.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/Network/BasicSpawner.cs" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/Opsive/UltimateCharacterController/Demo.meta" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/Opsive/UltimateCharacterController/Editor.meta" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/Opsive/UltimateCharacterController/Materials.meta" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/Opsive/UltimateCharacterController/Scripts.meta" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/Opsive/UltimateCharacterController/Shaders.meta" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/UltimateCharacterController_Documentation.pdf" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/UltimateCharacterController_Documentation.pdf.meta" beforeDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -48,6 +46,10 @@
|
|||||||
<setting file="file://$PROJECT_DIR$/Library/PackageCache/com.wooshii.foldericons@201a18f355d3/FolderIcons/Editor/FolderIcons.cs" root0="SKIP_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Library/PackageCache/com.wooshii.foldericons@201a18f355d3/FolderIcons/Editor/FolderIcons.cs" root0="SKIP_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Library/PackageCache/com.wooshii.foldericons@201a18f355d3/FolderIcons/Editor/FolderIconsEditor.asmdef" root0="SKIP_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Library/PackageCache/com.wooshii.foldericons@201a18f355d3/FolderIcons/Editor/FolderIconsEditor.asmdef" root0="SKIP_HIGHLIGHTING" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="KubernetesApiPersistence"><![CDATA[{}]]></component>
|
||||||
|
<component name="KubernetesApiProvider"><![CDATA[{
|
||||||
|
"isMigrated": true
|
||||||
|
}]]></component>
|
||||||
<component name="McpProjectServerCommands">
|
<component name="McpProjectServerCommands">
|
||||||
<commands />
|
<commands />
|
||||||
<urls />
|
<urls />
|
||||||
|
|||||||
@@ -7,22 +7,27 @@ Material:
|
|||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_Name: Transparency
|
m_Name: Red 1
|
||||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _ALPHAPREMULTIPLY_ON
|
||||||
|
- _EMISSION
|
||||||
- _ENVIRONMENTREFLECTIONS_OFF
|
- _ENVIRONMENTREFLECTIONS_OFF
|
||||||
|
- _SURFACE_TYPE_TRANSPARENT
|
||||||
m_InvalidKeywords:
|
m_InvalidKeywords:
|
||||||
- _GLOSSYREFLECTIONS_OFF
|
- _GLOSSYREFLECTIONS_OFF
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 1
|
||||||
m_EnableInstancingVariants: 1
|
m_EnableInstancingVariants: 1
|
||||||
m_DoubleSidedGI: 0
|
m_DoubleSidedGI: 0
|
||||||
m_CustomRenderQueue: 2000
|
m_CustomRenderQueue: 3000
|
||||||
stringTagMap:
|
stringTagMap:
|
||||||
RenderType: Opaque
|
RenderType: Transparent
|
||||||
disabledShaderPasses:
|
disabledShaderPasses:
|
||||||
- MOTIONVECTORS
|
- MOTIONVECTORS
|
||||||
|
- DepthOnly
|
||||||
|
- SHADOWCASTER
|
||||||
m_LockedProperties:
|
m_LockedProperties:
|
||||||
m_SavedProperties:
|
m_SavedProperties:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
@@ -97,36 +102,36 @@ Material:
|
|||||||
- _Cutoff: 0.5
|
- _Cutoff: 0.5
|
||||||
- _DetailAlbedoMapScale: 1
|
- _DetailAlbedoMapScale: 1
|
||||||
- _DetailNormalMapScale: 1
|
- _DetailNormalMapScale: 1
|
||||||
- _DstBlend: 0
|
- _DstBlend: 10
|
||||||
- _DstBlendAlpha: 0
|
- _DstBlendAlpha: 10
|
||||||
- _EnvironmentReflections: 0
|
- _EnvironmentReflections: 0
|
||||||
- _GlossMapScale: 0
|
- _GlossMapScale: 0
|
||||||
- _Glossiness: 0
|
- _Glossiness: 0
|
||||||
- _GlossyReflections: 0
|
- _GlossyReflections: 0
|
||||||
- _Metallic: 0
|
- _Metallic: 1
|
||||||
- _Mode: 0
|
- _Mode: 0
|
||||||
- _OcclusionStrength: 1
|
- _OcclusionStrength: 1
|
||||||
- _Parallax: 0.005
|
- _Parallax: 0.005
|
||||||
- _QueueOffset: 0
|
- _QueueOffset: 0
|
||||||
- _ReceiveShadows: 1
|
- _ReceiveShadows: 1
|
||||||
- _Smoothness: 0
|
- _Smoothness: 0.485
|
||||||
- _SmoothnessTextureChannel: 0
|
- _SmoothnessTextureChannel: 0
|
||||||
- _SpecularHighlights: 1
|
- _SpecularHighlights: 1
|
||||||
- _SrcBlend: 1
|
- _SrcBlend: 1
|
||||||
- _SrcBlendAlpha: 1
|
- _SrcBlendAlpha: 1
|
||||||
- _Surface: 0
|
- _Surface: 1
|
||||||
- _UVSec: 0
|
- _UVSec: 0
|
||||||
- _WorkflowMode: 1
|
- _WorkflowMode: 1
|
||||||
- _XRMotionVectorsPass: 1
|
- _XRMotionVectorsPass: 1
|
||||||
- _ZWrite: 1
|
- _ZWrite: 0
|
||||||
m_Colors:
|
m_Colors:
|
||||||
- _BaseColor: {r: 0.6462264, g: 1, b: 0.90943396, a: 1}
|
- _BaseColor: {r: 1, g: 0, b: 0, a: 0.54509807}
|
||||||
- _Color: {r: 0.6462264, g: 1, b: 0.90943396, a: 1}
|
- _Color: {r: 1, g: 0, b: 0, a: 0.54509807}
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
- _EmissionColor: {r: 0.4433962, g: 0, b: 0.035386458, a: 1}
|
||||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||||
m_BuildTextureStacks: []
|
m_BuildTextureStacks: []
|
||||||
m_AllowLocking: 1
|
m_AllowLocking: 1
|
||||||
--- !u!114 &7323331776208790253
|
--- !u!114 &4579113440628220621
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 11
|
m_ObjectHideFlags: 11
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: b0a84576fc378a24cbb3bfc7be45a02e
|
guid: 4e2761c702df38044a3b33cb36bdabf4
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 2100000
|
mainObjectFileID: 2100000
|
||||||
@@ -7,21 +7,26 @@ Material:
|
|||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_Name: Separator
|
m_Name: Red 2
|
||||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords: []
|
m_ValidKeywords:
|
||||||
|
- _ALPHAPREMULTIPLY_ON
|
||||||
|
- _EMISSION
|
||||||
|
- _ENVIRONMENTREFLECTIONS_OFF
|
||||||
|
- _SURFACE_TYPE_TRANSPARENT
|
||||||
m_InvalidKeywords:
|
m_InvalidKeywords:
|
||||||
- _GLOSSYREFLECTIONS_OFF
|
- _GLOSSYREFLECTIONS_OFF
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 1
|
||||||
m_EnableInstancingVariants: 1
|
m_EnableInstancingVariants: 1
|
||||||
m_DoubleSidedGI: 0
|
m_DoubleSidedGI: 0
|
||||||
m_CustomRenderQueue: 2000
|
m_CustomRenderQueue: 3000
|
||||||
stringTagMap:
|
stringTagMap:
|
||||||
RenderType: Opaque
|
RenderType: Transparent
|
||||||
disabledShaderPasses:
|
disabledShaderPasses:
|
||||||
- MOTIONVECTORS
|
- MOTIONVECTORS
|
||||||
|
- DepthOnly
|
||||||
- SHADOWCASTER
|
- SHADOWCASTER
|
||||||
m_LockedProperties:
|
m_LockedProperties:
|
||||||
m_SavedProperties:
|
m_SavedProperties:
|
||||||
@@ -97,36 +102,36 @@ Material:
|
|||||||
- _Cutoff: 0.5
|
- _Cutoff: 0.5
|
||||||
- _DetailAlbedoMapScale: 1
|
- _DetailAlbedoMapScale: 1
|
||||||
- _DetailNormalMapScale: 1
|
- _DetailNormalMapScale: 1
|
||||||
- _DstBlend: 0
|
- _DstBlend: 10
|
||||||
- _DstBlendAlpha: 0
|
- _DstBlendAlpha: 10
|
||||||
- _EnvironmentReflections: 0
|
- _EnvironmentReflections: 0
|
||||||
- _GlossMapScale: 0
|
- _GlossMapScale: 0
|
||||||
- _Glossiness: 0
|
- _Glossiness: 0
|
||||||
- _GlossyReflections: 0
|
- _GlossyReflections: 0
|
||||||
- _Metallic: 0
|
- _Metallic: 1
|
||||||
- _Mode: 0
|
- _Mode: 0
|
||||||
- _OcclusionStrength: 1
|
- _OcclusionStrength: 1
|
||||||
- _Parallax: 0.005
|
- _Parallax: 0.005
|
||||||
- _QueueOffset: 0
|
- _QueueOffset: 0
|
||||||
- _ReceiveShadows: 1
|
- _ReceiveShadows: 1
|
||||||
- _Smoothness: 0
|
- _Smoothness: 0.485
|
||||||
- _SmoothnessTextureChannel: 0
|
- _SmoothnessTextureChannel: 0
|
||||||
- _SpecularHighlights: 1
|
- _SpecularHighlights: 1
|
||||||
- _SrcBlend: 1
|
- _SrcBlend: 1
|
||||||
- _SrcBlendAlpha: 1
|
- _SrcBlendAlpha: 1
|
||||||
- _Surface: 0
|
- _Surface: 1
|
||||||
- _UVSec: 0
|
- _UVSec: 0
|
||||||
- _WorkflowMode: 1
|
- _WorkflowMode: 1
|
||||||
- _XRMotionVectorsPass: 1
|
- _XRMotionVectorsPass: 1
|
||||||
- _ZWrite: 1
|
- _ZWrite: 0
|
||||||
m_Colors:
|
m_Colors:
|
||||||
- _BaseColor: {r: 1, g: 0, b: 0, a: 0.5686275}
|
- _BaseColor: {r: 1, g: 0, b: 0, a: 0.54509807}
|
||||||
- _Color: {r: 1, g: 0, b: 0, a: 0.5686275}
|
- _Color: {r: 1, g: 0, b: 0, a: 0.54509807}
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
- _EmissionColor: {r: 0.4433962, g: 0, b: 0.035386458, a: 1}
|
||||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||||
m_BuildTextureStacks: []
|
m_BuildTextureStacks: []
|
||||||
m_AllowLocking: 1
|
m_AllowLocking: 1
|
||||||
--- !u!114 &9152226916650191239
|
--- !u!114 &4579113440628220621
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 11
|
m_ObjectHideFlags: 11
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: d7e691e02b41b9a47b417cc138d6f1bc
|
guid: c2de57284d214404394d08e4b5f50372
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 2100000
|
mainObjectFileID: 2100000
|
||||||
@@ -11,17 +11,23 @@ Material:
|
|||||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords: []
|
m_ValidKeywords:
|
||||||
|
- _ALPHAPREMULTIPLY_ON
|
||||||
|
- _EMISSION
|
||||||
|
- _ENVIRONMENTREFLECTIONS_OFF
|
||||||
|
- _SURFACE_TYPE_TRANSPARENT
|
||||||
m_InvalidKeywords:
|
m_InvalidKeywords:
|
||||||
- _GLOSSYREFLECTIONS_OFF
|
- _GLOSSYREFLECTIONS_OFF
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 1
|
||||||
m_EnableInstancingVariants: 1
|
m_EnableInstancingVariants: 1
|
||||||
m_DoubleSidedGI: 0
|
m_DoubleSidedGI: 0
|
||||||
m_CustomRenderQueue: -1
|
m_CustomRenderQueue: 3000
|
||||||
stringTagMap:
|
stringTagMap:
|
||||||
RenderType: Opaque
|
RenderType: Transparent
|
||||||
disabledShaderPasses:
|
disabledShaderPasses:
|
||||||
- MOTIONVECTORS
|
- MOTIONVECTORS
|
||||||
|
- DepthOnly
|
||||||
|
- SHADOWCASTER
|
||||||
m_LockedProperties:
|
m_LockedProperties:
|
||||||
m_SavedProperties:
|
m_SavedProperties:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
@@ -96,32 +102,32 @@ Material:
|
|||||||
- _Cutoff: 0.5
|
- _Cutoff: 0.5
|
||||||
- _DetailAlbedoMapScale: 1
|
- _DetailAlbedoMapScale: 1
|
||||||
- _DetailNormalMapScale: 1
|
- _DetailNormalMapScale: 1
|
||||||
- _DstBlend: 0
|
- _DstBlend: 10
|
||||||
- _DstBlendAlpha: 0
|
- _DstBlendAlpha: 10
|
||||||
- _EnvironmentReflections: 0
|
- _EnvironmentReflections: 0
|
||||||
- _GlossMapScale: 0
|
- _GlossMapScale: 0
|
||||||
- _Glossiness: 0
|
- _Glossiness: 0
|
||||||
- _GlossyReflections: 0
|
- _GlossyReflections: 0
|
||||||
- _Metallic: 0
|
- _Metallic: 1
|
||||||
- _Mode: 0
|
- _Mode: 0
|
||||||
- _OcclusionStrength: 1
|
- _OcclusionStrength: 1
|
||||||
- _Parallax: 0.005
|
- _Parallax: 0.005
|
||||||
- _QueueOffset: 0
|
- _QueueOffset: 0
|
||||||
- _ReceiveShadows: 1
|
- _ReceiveShadows: 1
|
||||||
- _Smoothness: 0
|
- _Smoothness: 0.485
|
||||||
- _SmoothnessTextureChannel: 0
|
- _SmoothnessTextureChannel: 0
|
||||||
- _SpecularHighlights: 1
|
- _SpecularHighlights: 1
|
||||||
- _SrcBlend: 1
|
- _SrcBlend: 1
|
||||||
- _SrcBlendAlpha: 1
|
- _SrcBlendAlpha: 1
|
||||||
- _Surface: 0
|
- _Surface: 1
|
||||||
- _UVSec: 0
|
- _UVSec: 0
|
||||||
- _WorkflowMode: 1
|
- _WorkflowMode: 1
|
||||||
- _XRMotionVectorsPass: 1
|
- _XRMotionVectorsPass: 1
|
||||||
- _ZWrite: 1
|
- _ZWrite: 0
|
||||||
m_Colors:
|
m_Colors:
|
||||||
- _BaseColor: {r: 1, g: 0, b: 0, a: 1}
|
- _BaseColor: {r: 1, g: 0, b: 0, a: 0.54509807}
|
||||||
- _Color: {r: 1, g: 0, b: 0, a: 1}
|
- _Color: {r: 1, g: 0, b: 0, a: 0.54509807}
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
- _EmissionColor: {r: 0.4433962, g: 0, b: 0.035386458, a: 1}
|
||||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||||
m_BuildTextureStacks: []
|
m_BuildTextureStacks: []
|
||||||
m_AllowLocking: 1
|
m_AllowLocking: 1
|
||||||
|
|||||||
63
Assets/Prefabs/Environment/Hall/MazeVisualize 1 1.prefab
Normal file
63
Assets/Prefabs/Environment/Hall/MazeVisualize 1 1.prefab
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1001 &8524974212353532561
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3172752473709046689, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3276807805808399797, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: 'm_Materials.Array.data[0]'
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 2100000, guid: c2de57284d214404394d08e4b5f50372, type: 2}
|
||||||
|
- target: {fileID: 7410088413158269499, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: MazeVisualize 1 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: 17f01b6b44475394da68b1ca1d8d7eb4, type: 3}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c39adeeb3a17d824392cc018d65aedc4
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
63
Assets/Prefabs/Environment/Hall/MazeVisualize 1.prefab
Normal file
63
Assets/Prefabs/Environment/Hall/MazeVisualize 1.prefab
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1001 &4042319629769208918
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1449831261723959287, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 1540436817844937187, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: 'm_Materials.Array.data[0]'
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 2100000, guid: 4e2761c702df38044a3b33cb36bdabf4, type: 2}
|
||||||
|
- target: {fileID: 6831072708289238637, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: MazeVisualize 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: 085ffdfee17437a4f8e0d3c365edcc24, type: 3}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 17f01b6b44475394da68b1ca1d8d7eb4
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
114
Assets/Prefabs/Environment/Hall/MazeVisualize.prefab
Normal file
114
Assets/Prefabs/Environment/Hall/MazeVisualize.prefab
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &6831072708289238637
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1449831261723959287}
|
||||||
|
- component: {fileID: 7162882105187371053}
|
||||||
|
- component: {fileID: 1540436817844937187}
|
||||||
|
- component: {fileID: 1186626314013191963}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: MazeVisualize
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &1449831261723959287
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6831072708289238637}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 111.06352, y: 0.99998, z: 75.67667}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!33 &7162882105187371053
|
||||||
|
MeshFilter:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6831072708289238637}
|
||||||
|
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
--- !u!23 &1540436817844937187
|
||||||
|
MeshRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6831072708289238637}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_CastShadows: 1
|
||||||
|
m_ReceiveShadows: 1
|
||||||
|
m_DynamicOccludee: 1
|
||||||
|
m_StaticShadowCaster: 0
|
||||||
|
m_MotionVectors: 1
|
||||||
|
m_LightProbeUsage: 1
|
||||||
|
m_ReflectionProbeUsage: 1
|
||||||
|
m_RayTracingMode: 2
|
||||||
|
m_RayTraceProcedural: 0
|
||||||
|
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||||
|
m_RayTracingAccelStructBuildFlags: 1
|
||||||
|
m_SmallMeshCulling: 1
|
||||||
|
m_ForceMeshLod: -1
|
||||||
|
m_MeshLodSelectionBias: 0
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 2100000, guid: 9193f4635bbf98d46be9a6357461aa10, type: 2}
|
||||||
|
m_StaticBatchInfo:
|
||||||
|
firstSubMesh: 0
|
||||||
|
subMeshCount: 0
|
||||||
|
m_StaticBatchRoot: {fileID: 0}
|
||||||
|
m_ProbeAnchor: {fileID: 0}
|
||||||
|
m_LightProbeVolumeOverride: {fileID: 0}
|
||||||
|
m_ScaleInLightmap: 1
|
||||||
|
m_ReceiveGI: 1
|
||||||
|
m_PreserveUVs: 0
|
||||||
|
m_IgnoreNormalsForChartDetection: 0
|
||||||
|
m_ImportantGI: 0
|
||||||
|
m_StitchLightmapSeams: 1
|
||||||
|
m_SelectedEditorRenderState: 3
|
||||||
|
m_MinimumChartSize: 4
|
||||||
|
m_AutoUVMaxDistance: 0.5
|
||||||
|
m_AutoUVMaxAngle: 89
|
||||||
|
m_LightmapParameters: {fileID: 0}
|
||||||
|
m_GlobalIlluminationMeshLod: 0
|
||||||
|
m_SortingLayerID: 0
|
||||||
|
m_SortingLayer: 0
|
||||||
|
m_SortingOrder: 0
|
||||||
|
m_MaskInteraction: 0
|
||||||
|
m_AdditionalVertexStreams: {fileID: 0}
|
||||||
|
--- !u!65 &1186626314013191963
|
||||||
|
BoxCollider:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6831072708289238637}
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_IncludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_ExcludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_LayerOverridePriority: 0
|
||||||
|
m_IsTrigger: 0
|
||||||
|
m_ProvidesContacts: 0
|
||||||
|
m_Enabled: 0
|
||||||
|
serializedVersion: 3
|
||||||
|
m_Size: {x: 1, y: 1, z: 1}
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 085ffdfee17437a4f8e0d3c365edcc24
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -12,13 +12,14 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 30892b1102feb6841a9288ddb11ef50d, type: 3}
|
m_Script: {fileID: 11500000, guid: 30892b1102feb6841a9288ddb11ef50d, type: 3}
|
||||||
m_Name: MazeRework
|
m_Name: MazeRework
|
||||||
m_EditorClassIdentifier: Assembly-CSharp::Baba_yaga.GameSetup.MazeRework.MazeReworkConfig
|
m_EditorClassIdentifier: Assembly-CSharp::Baba_yaga.GameSetup.MazeRework.MazeReworkConfig
|
||||||
width: 15
|
algorithm: 3
|
||||||
depth: 15
|
width: 21
|
||||||
|
depth: 21
|
||||||
useRandomSeed: 1
|
useRandomSeed: 1
|
||||||
seed: 1337
|
seed: 1337
|
||||||
startLocation: {x: 1, y: 1}
|
startLocation: {x: 1, y: 1}
|
||||||
generateRooms: 0
|
generateRooms: 0
|
||||||
roomCount: 207
|
roomCount: 378
|
||||||
minRoomSize: {x: 3, y: 3}
|
minRoomSize: {x: 3, y: 3}
|
||||||
maxRoomSize: {x: 5, y: 5}
|
maxRoomSize: {x: 5, y: 5}
|
||||||
extraRoomDoorChance: 0.3
|
extraRoomDoorChance: 0.3
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1207eeec52bcfcf4a9a97e054680d844
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Algorithms
|
||||||
|
{
|
||||||
|
public class DFSIterative : IMazeReworkAlgorithm
|
||||||
|
{
|
||||||
|
public void Carve(
|
||||||
|
MazeReworkCellType[,] grid,
|
||||||
|
bool[,] visited,
|
||||||
|
int startX, int startZ,
|
||||||
|
int width, int depth,
|
||||||
|
System.Random rng,
|
||||||
|
System.Action<int, int, MazeReworkCellType, Animation.MazeCellHighlight> onCellChanged = null)
|
||||||
|
{
|
||||||
|
Stack<Vector2Int> stack = new Stack<Vector2Int>();
|
||||||
|
stack.Push(new Vector2Int(startX, startZ));
|
||||||
|
onCellChanged?.Invoke(startX, startZ, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
|
||||||
|
int[] dx = { 2, -2, 0, 0 };
|
||||||
|
int[] dz = { 0, 0, 2, -2 };
|
||||||
|
|
||||||
|
while (stack.Count > 0)
|
||||||
|
{
|
||||||
|
Vector2Int current = stack.Peek();
|
||||||
|
|
||||||
|
List<int> candidates = new List<int>(4);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
int nx = current.x + dx[i];
|
||||||
|
int nz = current.y + dz[i];
|
||||||
|
if (nx > 0 && nx < width - 1 && nz > 0 && nz < depth - 1 && !visited[nx, nz])
|
||||||
|
candidates.Add(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (candidates.Count > 0)
|
||||||
|
{
|
||||||
|
int pick = candidates[rng.Next(candidates.Count)];
|
||||||
|
int nx2 = current.x + dx[pick];
|
||||||
|
int nz2 = current.y + dz[pick];
|
||||||
|
int wx = current.x + dx[pick] / 2;
|
||||||
|
int wz = current.y + dz[pick] / 2;
|
||||||
|
|
||||||
|
grid[wx, wz] = MazeReworkCellType.Corridor;
|
||||||
|
grid[nx2, nz2] = MazeReworkCellType.Corridor;
|
||||||
|
visited[wx, wz] = true;
|
||||||
|
visited[nx2, nz2] = true;
|
||||||
|
|
||||||
|
// Move head off current cell
|
||||||
|
onCellChanged?.Invoke(current.x, current.y, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
|
||||||
|
// Show breaking intermediate wall with head
|
||||||
|
onCellChanged?.Invoke(wx, wz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
onCellChanged?.Invoke(wx, wz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
|
||||||
|
// Move head to new cell
|
||||||
|
onCellChanged?.Invoke(nx2, nz2, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
|
||||||
|
stack.Push(new Vector2Int(nx2, nz2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stack.Pop();
|
||||||
|
// Clear head from popped cell
|
||||||
|
onCellChanged?.Invoke(current.x, current.y, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
// Restore head to new top of stack
|
||||||
|
if (stack.Count > 0)
|
||||||
|
{
|
||||||
|
var nextCurrent = stack.Peek();
|
||||||
|
onCellChanged?.Invoke(nextCurrent.x, nextCurrent.y, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cdda5d3deb881154481ad5f60c4bdc0a
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Algorithms
|
||||||
|
{
|
||||||
|
public class DFSRecursive : IMazeReworkAlgorithm
|
||||||
|
{
|
||||||
|
public void Carve(
|
||||||
|
MazeReworkCellType[,] grid,
|
||||||
|
bool[,] visited,
|
||||||
|
int startX, int startZ,
|
||||||
|
int width, int depth,
|
||||||
|
System.Random rng,
|
||||||
|
System.Action<int, int, MazeReworkCellType, Animation.MazeCellHighlight> onCellChanged = null)
|
||||||
|
{
|
||||||
|
CarveFrom(startX, startZ, grid, visited, rng, width, depth, onCellChanged);
|
||||||
|
// Clear final head position when completely done
|
||||||
|
onCellChanged?.Invoke(startX, startZ, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CarveFrom(int cx, int cz, MazeReworkCellType[,] grid, bool[,] visited,
|
||||||
|
System.Random rng, int width, int depth,
|
||||||
|
System.Action<int, int, MazeReworkCellType, Animation.MazeCellHighlight> onCellChanged)
|
||||||
|
{
|
||||||
|
onCellChanged?.Invoke(cx, cz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
|
||||||
|
int[] dx = { 2, -2, 0, 0 };
|
||||||
|
int[] dz = { 0, 0, 2, -2 };
|
||||||
|
|
||||||
|
int[] order = { 0, 1, 2, 3 };
|
||||||
|
for (int i = 3; i > 0; i--)
|
||||||
|
{
|
||||||
|
int j = rng.Next(i + 1);
|
||||||
|
int tmp = order[i]; order[i] = order[j]; order[j] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
int nx = cx + dx[order[i]];
|
||||||
|
int nz = cz + dz[order[i]];
|
||||||
|
int wx = cx + dx[order[i]] / 2;
|
||||||
|
int wz = cz + dz[order[i]] / 2;
|
||||||
|
|
||||||
|
if (nx > 0 && nx < width - 1 && nz > 0 && nz < depth - 1 && !visited[nx, nz])
|
||||||
|
{
|
||||||
|
grid[wx, wz] = MazeReworkCellType.Corridor;
|
||||||
|
grid[nx, nz] = MazeReworkCellType.Corridor;
|
||||||
|
visited[wx, wz] = true;
|
||||||
|
visited[nx, nz] = true;
|
||||||
|
|
||||||
|
// Move head off current cell
|
||||||
|
onCellChanged?.Invoke(cx, cz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
|
||||||
|
// Show intermediate wall breaking with head
|
||||||
|
onCellChanged?.Invoke(wx, wz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
onCellChanged?.Invoke(wx, wz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
|
||||||
|
CarveFrom(nx, nz, grid, visited, rng, width, depth, onCellChanged);
|
||||||
|
|
||||||
|
// Clear head from the child cell and restore it here
|
||||||
|
onCellChanged?.Invoke(nx, nz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
onCellChanged?.Invoke(cx, cz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f20ddc35c8bf6604b84a0102bdad1821
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Algorithms
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contract that all maze carving algorithms must fulfill.
|
||||||
|
/// The algorithm is only responsible for carving corridors.
|
||||||
|
/// Rooms, loops, Start/End placement, and connectivity repair are handled externally.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMazeReworkAlgorithm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Carves corridors into the grid starting from (startX, startZ).
|
||||||
|
/// All cells begin as Wall. The algorithm sets reachable cells to Corridor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="grid">The 2D cell array to carve into.</param>
|
||||||
|
/// <param name="visited">Shared visited map. Pre-marked cells (e.g. rooms) are already true.</param>
|
||||||
|
/// <param name="startX">X coordinate of the first cell to carve (must be odd).</param>
|
||||||
|
/// <param name="startZ">Z coordinate of the first cell to carve (must be odd).</param>
|
||||||
|
/// <param name="width">Grid width.</param>
|
||||||
|
/// <param name="depth">Grid depth.</param>
|
||||||
|
/// <param name="rng">Seeded random number generator.</param>
|
||||||
|
/// <param name="onCellChanged">
|
||||||
|
/// Optional callback fired every time a cell is carved or evaluated.
|
||||||
|
/// Signature: (x, z, newType, highlight). Pass null in non-animated mode.
|
||||||
|
/// </param>
|
||||||
|
void Carve(
|
||||||
|
MazeReworkCellType[,] grid,
|
||||||
|
bool[,] visited,
|
||||||
|
int startX,
|
||||||
|
int startZ,
|
||||||
|
int width,
|
||||||
|
int depth,
|
||||||
|
System.Random rng,
|
||||||
|
System.Action<int, int, MazeReworkCellType, Animation.MazeCellHighlight> onCellChanged = null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f8ba54b75b8f8344aa7ccb03b8779c03
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Algorithms
|
||||||
|
{
|
||||||
|
public class Kruskals : IMazeReworkAlgorithm
|
||||||
|
{
|
||||||
|
public void Carve(
|
||||||
|
MazeReworkCellType[,] grid,
|
||||||
|
bool[,] visited,
|
||||||
|
int startX, int startZ,
|
||||||
|
int width, int depth,
|
||||||
|
System.Random rng,
|
||||||
|
System.Action<int, int, MazeReworkCellType, Animation.MazeCellHighlight> onCellChanged = null)
|
||||||
|
{
|
||||||
|
// Assign unique ID to every odd-coordinate (node) cell
|
||||||
|
int[,] cellId = new int[width, depth];
|
||||||
|
int idCounter = 0;
|
||||||
|
for (int z = 1; z < depth - 1; z += 2)
|
||||||
|
for (int x = 1; x < width - 1; x += 2)
|
||||||
|
cellId[x, z] = idCounter++;
|
||||||
|
|
||||||
|
UnionFind uf = new UnionFind(idCounter);
|
||||||
|
|
||||||
|
// Collect all internal walls
|
||||||
|
List<Vector2Int> walls = new List<Vector2Int>();
|
||||||
|
for (int z = 1; z < depth - 1; z++)
|
||||||
|
for (int x = 1; x < width - 1; x++)
|
||||||
|
if ((x % 2 == 0 && z % 2 == 1) || (x % 2 == 1 && z % 2 == 0))
|
||||||
|
walls.Add(new Vector2Int(x, z));
|
||||||
|
|
||||||
|
// Shuffle walls
|
||||||
|
for (int i = walls.Count - 1; i > 0; i--)
|
||||||
|
{
|
||||||
|
int j = rng.Next(i + 1);
|
||||||
|
var tmp = walls[i]; walls[i] = walls[j]; walls[j] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var wall in walls)
|
||||||
|
{
|
||||||
|
int wx = wall.x, wz = wall.y;
|
||||||
|
int ax, az, bx, bz;
|
||||||
|
|
||||||
|
if (wx % 2 == 0) { ax = wx - 1; az = wz; bx = wx + 1; bz = wz; }
|
||||||
|
else { ax = wx; az = wz - 1; bx = wx; bz = wz + 1; }
|
||||||
|
|
||||||
|
if (ax < 1 || ax >= width - 1 || az < 1 || az >= depth - 1) continue;
|
||||||
|
if (bx < 1 || bx >= width - 1 || bz < 1 || bz >= depth - 1) continue;
|
||||||
|
|
||||||
|
// Show evaluating highlight
|
||||||
|
onCellChanged?.Invoke(wx, wz, grid[wx, wz], Animation.MazeCellHighlight.Evaluating);
|
||||||
|
|
||||||
|
if (uf.Find(cellId[ax, az]) != uf.Find(cellId[bx, bz]))
|
||||||
|
{
|
||||||
|
grid[wx, wz] = MazeReworkCellType.Corridor;
|
||||||
|
grid[ax, az] = MazeReworkCellType.Corridor;
|
||||||
|
grid[bx, bz] = MazeReworkCellType.Corridor;
|
||||||
|
visited[wx, wz] = visited[ax, az] = visited[bx, bz] = true;
|
||||||
|
|
||||||
|
onCellChanged?.Invoke(ax, az, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
onCellChanged?.Invoke(wx, wz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
onCellChanged?.Invoke(bx, bz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
|
||||||
|
uf.Union(cellId[ax, az], cellId[bx, bz]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clear evaluate highlight
|
||||||
|
onCellChanged?.Invoke(wx, wz, grid[wx, wz], Animation.MazeCellHighlight.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UnionFind
|
||||||
|
{
|
||||||
|
private readonly int[] _parent, _rank;
|
||||||
|
public UnionFind(int count) { _parent = new int[count]; _rank = new int[count]; for (int i = 0; i < count; i++) _parent[i] = i; }
|
||||||
|
public int Find(int x) { if (_parent[x] != x) _parent[x] = Find(_parent[x]); return _parent[x]; }
|
||||||
|
public void Union(int a, int b) { int ra = Find(a), rb = Find(b); if (ra == rb) return; if (_rank[ra] < _rank[rb]) _parent[ra] = rb; else if (_rank[ra] > _rank[rb]) _parent[rb] = ra; else { _parent[rb] = ra; _rank[ra]++; } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7574ba4325993ac46a12a7861b70031f
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Algorithms
|
||||||
|
{
|
||||||
|
public class Prims : IMazeReworkAlgorithm
|
||||||
|
{
|
||||||
|
public void Carve(
|
||||||
|
MazeReworkCellType[,] grid,
|
||||||
|
bool[,] visited,
|
||||||
|
int startX, int startZ,
|
||||||
|
int width, int depth,
|
||||||
|
System.Random rng,
|
||||||
|
System.Action<int, int, MazeReworkCellType, Animation.MazeCellHighlight> onCellChanged = null)
|
||||||
|
{
|
||||||
|
grid[startX, startZ] = MazeReworkCellType.Corridor;
|
||||||
|
visited[startX, startZ] = true;
|
||||||
|
onCellChanged?.Invoke(startX, startZ, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
|
||||||
|
List<(int nx, int nz, int wx, int wz)> frontier = new List<(int, int, int, int)>();
|
||||||
|
AddFrontier(startX, startZ, frontier, visited, width, depth, grid, onCellChanged);
|
||||||
|
|
||||||
|
while (frontier.Count > 0)
|
||||||
|
{
|
||||||
|
int pick = rng.Next(frontier.Count);
|
||||||
|
var (nx, nz, wx, wz) = frontier[pick];
|
||||||
|
|
||||||
|
// Swap-remove O(1)
|
||||||
|
frontier[pick] = frontier[frontier.Count - 1];
|
||||||
|
frontier.RemoveAt(frontier.Count - 1);
|
||||||
|
|
||||||
|
if (visited[nx, nz])
|
||||||
|
{
|
||||||
|
// Clear the frontier highlight if this cell was already visited by another path
|
||||||
|
onCellChanged?.Invoke(nx, nz, grid[nx, nz], Animation.MazeCellHighlight.None);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
grid[wx, wz] = MazeReworkCellType.Corridor;
|
||||||
|
grid[nx, nz] = MazeReworkCellType.Corridor;
|
||||||
|
visited[wx, wz] = true;
|
||||||
|
visited[nx, nz] = true;
|
||||||
|
|
||||||
|
onCellChanged?.Invoke(wx, wz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
onCellChanged?.Invoke(wx, wz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
|
||||||
|
onCellChanged?.Invoke(nx, nz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.SearchHead);
|
||||||
|
onCellChanged?.Invoke(nx, nz, MazeReworkCellType.Corridor, Animation.MazeCellHighlight.None);
|
||||||
|
|
||||||
|
AddFrontier(nx, nz, frontier, visited, width, depth, grid, onCellChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddFrontier(int cx, int cz,
|
||||||
|
List<(int nx, int nz, int wx, int wz)> frontier,
|
||||||
|
bool[,] visited, int width, int depth, MazeReworkCellType[,] grid,
|
||||||
|
System.Action<int, int, MazeReworkCellType, Animation.MazeCellHighlight> onCellChanged)
|
||||||
|
{
|
||||||
|
int[] dx = { 2, -2, 0, 0 };
|
||||||
|
int[] dz = { 0, 0, 2, -2 };
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
int nx = cx + dx[i], nz = cz + dz[i];
|
||||||
|
int wx = cx + dx[i] / 2, wz = cz + dz[i] / 2;
|
||||||
|
if (nx > 0 && nx < width - 1 && nz > 0 && nz < depth - 1 && !visited[nx, nz])
|
||||||
|
{
|
||||||
|
frontier.Add((nx, nz, wx, wz));
|
||||||
|
onCellChanged?.Invoke(nx, nz, grid[nx, nz], Animation.MazeCellHighlight.Frontier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 321151d3d7c655047b73b6bd981800e6
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 92ea88f252068ee47ad6145db600314b
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Animation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Labels each recorded cell change with which generation phase produced it.
|
||||||
|
/// Used to color-code or group changes during animated playback.
|
||||||
|
/// </summary>
|
||||||
|
public enum MazeAnimationPhase
|
||||||
|
{
|
||||||
|
RoomPlacement, // Rooms being stamped onto the grid
|
||||||
|
Carving, // Algorithm carving corridors
|
||||||
|
Connecting, // Hunt-and-Kill fixing isolated pockets
|
||||||
|
Loops, // Extra walls removed to create shortcuts
|
||||||
|
StartEnd // Start and End cells placed
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 45bda90d4b2d42245a8d9f06543053ee
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Animation
|
||||||
|
{
|
||||||
|
public class MazeAnimator : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Animation Settings")]
|
||||||
|
[Tooltip("How many cell changes to process in a single frame. Higher = faster generation.")]
|
||||||
|
[Min(1)]
|
||||||
|
public int cellsPerFrame = 5;
|
||||||
|
|
||||||
|
[Tooltip("Extra delay (in seconds) between major generation phases (like switching from Rooms to Carving).")]
|
||||||
|
public float delayBetweenPhases = 0.5f;
|
||||||
|
|
||||||
|
private Coroutine _animationRoutine;
|
||||||
|
|
||||||
|
public void AnimateGeneration(
|
||||||
|
List<MazeCellChange> history,
|
||||||
|
MazeReworkCellType[,] grid,
|
||||||
|
MazeReworkSpawner spawner,
|
||||||
|
float yOffset,
|
||||||
|
Transform container,
|
||||||
|
System.Action onComplete = null)
|
||||||
|
{
|
||||||
|
if (_animationRoutine != null)
|
||||||
|
StopCoroutine(_animationRoutine);
|
||||||
|
|
||||||
|
_animationRoutine = StartCoroutine(AnimateRoutine(history, grid, spawner, yOffset, container, onComplete));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopAnimation()
|
||||||
|
{
|
||||||
|
if (_animationRoutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(_animationRoutine);
|
||||||
|
_animationRoutine = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator AnimateRoutine(
|
||||||
|
List<MazeCellChange> history,
|
||||||
|
MazeReworkCellType[,] finalGrid,
|
||||||
|
MazeReworkSpawner spawner,
|
||||||
|
float yOffset,
|
||||||
|
Transform container,
|
||||||
|
System.Action onComplete)
|
||||||
|
{
|
||||||
|
int width = finalGrid.GetLength(0);
|
||||||
|
int depth = finalGrid.GetLength(1);
|
||||||
|
|
||||||
|
// Create a working grid starting fully as walls (like the generator does)
|
||||||
|
MazeReworkCellType[,] workingGrid = new MazeReworkCellType[width, depth];
|
||||||
|
MazeCellHighlight[,] workingHighlights = new MazeCellHighlight[width, depth];
|
||||||
|
for (int z = 0; z < depth; z++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
workingGrid[x, z] = MazeReworkCellType.Wall;
|
||||||
|
workingHighlights[x, z] = MazeCellHighlight.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spawner.Clear();
|
||||||
|
|
||||||
|
MazeAnimationPhase currentPhase = MazeAnimationPhase.RoomPlacement;
|
||||||
|
int processedThisFrame = 0;
|
||||||
|
|
||||||
|
foreach (var change in history)
|
||||||
|
{
|
||||||
|
if (change.Phase != currentPhase)
|
||||||
|
{
|
||||||
|
currentPhase = change.Phase;
|
||||||
|
if (delayBetweenPhases > 0f)
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(delayBetweenPhases);
|
||||||
|
processedThisFrame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
workingGrid[change.X, change.Z] = change.Type;
|
||||||
|
workingHighlights[change.X, change.Z] = change.Highlight;
|
||||||
|
|
||||||
|
// Refresh the cell and its neighbors in the spawner
|
||||||
|
spawner.RefreshCell(workingGrid, workingHighlights, change.X, change.Z, yOffset, container);
|
||||||
|
|
||||||
|
processedThisFrame++;
|
||||||
|
if (processedThisFrame >= cellsPerFrame)
|
||||||
|
{
|
||||||
|
yield return null; // Wait for next frame
|
||||||
|
processedThisFrame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait a moment at the end before finalizing
|
||||||
|
if (delayBetweenPhases > 0f)
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(delayBetweenPhases);
|
||||||
|
}
|
||||||
|
|
||||||
|
// One final sync with finalGrid just to be absolutely safe
|
||||||
|
for (int z = 0; z < depth; z++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
bool gridChanged = workingGrid[x, z] != finalGrid[x, z];
|
||||||
|
bool highlightChanged = workingHighlights[x, z] != MazeCellHighlight.None;
|
||||||
|
|
||||||
|
if (gridChanged || highlightChanged)
|
||||||
|
{
|
||||||
|
workingGrid[x, z] = finalGrid[x, z];
|
||||||
|
workingHighlights[x, z] = MazeCellHighlight.None;
|
||||||
|
spawner.RefreshCell(workingGrid, workingHighlights, x, z, yOffset, container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_animationRoutine = null;
|
||||||
|
onComplete?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 209db07e0fcae2e4e9e8b9e2fb822e31
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Animation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A single recorded cell change captured during maze generation.
|
||||||
|
/// The animator drains this list to replay generation visually.
|
||||||
|
/// </summary>
|
||||||
|
public readonly struct MazeCellChange
|
||||||
|
{
|
||||||
|
public readonly int X;
|
||||||
|
public readonly int Z;
|
||||||
|
public readonly MazeReworkCellType Type;
|
||||||
|
public readonly MazeCellHighlight Highlight;
|
||||||
|
public readonly MazeAnimationPhase Phase;
|
||||||
|
|
||||||
|
public MazeCellChange(int x, int z, MazeReworkCellType type, MazeCellHighlight highlight, MazeAnimationPhase phase)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Z = z;
|
||||||
|
Type = type;
|
||||||
|
Highlight = highlight;
|
||||||
|
Phase = phase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6f6a93f9b414a3f4a83c74ee28fb441b
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Baba_yaga.GameSetup.MazeRework.Animation
|
||||||
|
{
|
||||||
|
public enum MazeCellHighlight
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
SearchHead, // Current cell being evaluated (DFS, Prim's)
|
||||||
|
Frontier, // Known candidate cells (Prim's)
|
||||||
|
Evaluating // Walls currently being considered (Kruskal's)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6bff934558bb70343ad947b2c9e4da45
|
||||||
@@ -1,13 +1,29 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Baba_yaga.GameSetup.MazeRework.Algorithms;
|
||||||
|
|
||||||
namespace Baba_yaga.GameSetup.MazeRework
|
namespace Baba_yaga.GameSetup.MazeRework
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines which carving algorithm the generator will use.
|
||||||
|
/// </summary>
|
||||||
|
public enum MazeAlgorithmType
|
||||||
|
{
|
||||||
|
DFSRecursive, // Long winding corridors. May stack overflow on huge grids.
|
||||||
|
DFSIterative, // Same result as recursive but safe for large grids.
|
||||||
|
Kruskals, // Short branchy corridors, open feel, no directional bias.
|
||||||
|
Prims, // Organic cave-like layout, radiates outward from start.
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configuration asset containing parameters for the reworked maze generation.
|
/// Configuration asset containing parameters for the reworked maze generation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CreateAssetMenu(fileName = "MazeReworkConfig", menuName = "BABA_YAGA/GameSetup/MazeRework")]
|
[CreateAssetMenu(fileName = "MazeReworkConfig", menuName = "BABA_YAGA/MazeRework/Config")]
|
||||||
public class MazeReworkConfig : ScriptableObject
|
public class MazeReworkConfig : ScriptableObject
|
||||||
{
|
{
|
||||||
|
[Header("Algorithm")]
|
||||||
|
[Tooltip("Which carving algorithm to use for generating the maze corridors.")]
|
||||||
|
public MazeAlgorithmType algorithm = MazeAlgorithmType.DFSRecursive;
|
||||||
|
|
||||||
[Header("Grid Dimensions")]
|
[Header("Grid Dimensions")]
|
||||||
[Tooltip("Width of the maze grid. Best if odd to align with wall-corridor-wall patterning.")]
|
[Tooltip("Width of the maze grid. Best if odd to align with wall-corridor-wall patterning.")]
|
||||||
[Min(5)]
|
[Min(5)]
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Baba_yaga.GameSetup.MazeRework.Algorithms;
|
||||||
|
using Baba_yaga.GameSetup.MazeRework.Animation;
|
||||||
|
|
||||||
namespace Baba_yaga.GameSetup.MazeRework
|
namespace Baba_yaga.GameSetup.MazeRework
|
||||||
{
|
{
|
||||||
@@ -97,10 +99,11 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
int startZ = _config.startLocation.y;
|
int startZ = _config.startLocation.y;
|
||||||
EnsureValidOddCoordinates(width, depth, ref startX, ref startZ);
|
EnsureValidOddCoordinates(width, depth, ref startX, ref startZ);
|
||||||
|
|
||||||
// 5. Carve Corridors recursively using Step-by-2 Recursive Backtracking
|
// 5. Carve Corridors using the selected algorithm
|
||||||
visited[startX, startZ] = true;
|
visited[startX, startZ] = true;
|
||||||
grid[startX, startZ] = MazeReworkCellType.Corridor;
|
grid[startX, startZ] = MazeReworkCellType.Corridor;
|
||||||
CarveFrom(startX, startZ, grid, visited, rooms, rng, width, depth);
|
IMazeReworkAlgorithm algorithm = GetAlgorithm();
|
||||||
|
algorithm.Carve(grid, visited, startX, startZ, width, depth, rng);
|
||||||
|
|
||||||
// 6. Hunt & Kill scan to connect isolated rooms/corridors
|
// 6. Hunt & Kill scan to connect isolated rooms/corridors
|
||||||
EnsureAllConnected(grid, visited, rooms, rng, width, depth);
|
EnsureAllConnected(grid, visited, rooms, rng, width, depth);
|
||||||
@@ -114,9 +117,86 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Animated Generation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates the maze and records every cell change with its phase label.
|
||||||
|
/// Returns the final grid AND the ordered history list for the animator to replay.
|
||||||
|
/// </summary>
|
||||||
|
public (MazeReworkCellType[,] grid, List<MazeCellChange> history) GenerateAnimated()
|
||||||
|
{
|
||||||
|
if (_config == null) return (null, null);
|
||||||
|
int seed = _config.useRandomSeed
|
||||||
|
? System.DateTime.Now.Millisecond + System.Threading.Thread.CurrentThread.ManagedThreadId
|
||||||
|
: _config.seed;
|
||||||
|
return GenerateAnimated(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public (MazeReworkCellType[,] grid, List<MazeCellChange> history) GenerateAnimated(int seed)
|
||||||
|
{
|
||||||
|
if (_config == null) return (null, null);
|
||||||
|
|
||||||
|
int width = _config.width;
|
||||||
|
int depth = _config.depth;
|
||||||
|
var grid = new MazeReworkCellType[width, depth];
|
||||||
|
var history = new List<MazeCellChange>(width * depth * 2);
|
||||||
|
|
||||||
|
// Helper: record a cell change tagged with a phase
|
||||||
|
var currentPhase = MazeAnimationPhase.RoomPlacement;
|
||||||
|
Action<int, int, MazeReworkCellType, MazeCellHighlight> record =
|
||||||
|
(x, z, t, h) => history.Add(new MazeCellChange(x, z, t, h, currentPhase));
|
||||||
|
|
||||||
|
Action<int, int, MazeReworkCellType> recordNoHighlight =
|
||||||
|
(x, z, t) => record(x, z, t, MazeCellHighlight.None);
|
||||||
|
|
||||||
|
// 1. Initialize all cells as Wall (no recording — start state is all-Wall)
|
||||||
|
for (int z = 0; z < depth; z++)
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
grid[x, z] = MazeReworkCellType.Wall;
|
||||||
|
|
||||||
|
System.Random rng = new System.Random(seed);
|
||||||
|
|
||||||
|
// 2. Generate Rooms — record each Room cell
|
||||||
|
currentPhase = MazeAnimationPhase.RoomPlacement;
|
||||||
|
List<Room> rooms = GenerateRooms(grid, width, depth, rng, recordNoHighlight);
|
||||||
|
|
||||||
|
// 3. Setup visited map
|
||||||
|
bool[,] visited = new bool[width, depth];
|
||||||
|
InitializeVisitedMap(grid, visited, rooms, width, depth);
|
||||||
|
|
||||||
|
// 4. Starting coordinates
|
||||||
|
int startX = _config.startLocation.x;
|
||||||
|
int startZ = _config.startLocation.y;
|
||||||
|
EnsureValidOddCoordinates(width, depth, ref startX, ref startZ);
|
||||||
|
|
||||||
|
// 5. Carve Corridors — algorithm fires back through the record callback
|
||||||
|
currentPhase = MazeAnimationPhase.Carving;
|
||||||
|
visited[startX, startZ] = true;
|
||||||
|
grid[startX, startZ] = MazeReworkCellType.Corridor;
|
||||||
|
record(startX, startZ, MazeReworkCellType.Corridor, MazeCellHighlight.None); // DFS will highlight itself
|
||||||
|
GetAlgorithm().Carve(grid, visited, startX, startZ, width, depth, rng, record);
|
||||||
|
|
||||||
|
// 6. Hunt & Kill connecting pass
|
||||||
|
currentPhase = MazeAnimationPhase.Connecting;
|
||||||
|
EnsureAllConnected(grid, visited, rooms, rng, width, depth, recordNoHighlight);
|
||||||
|
|
||||||
|
// 7. Loop carving
|
||||||
|
currentPhase = MazeAnimationPhase.Loops;
|
||||||
|
CarveLoops(grid, rng, width, depth, recordNoHighlight);
|
||||||
|
|
||||||
|
// 8. Start & End placement
|
||||||
|
currentPhase = MazeAnimationPhase.StartEnd;
|
||||||
|
PlaceStartAndEnd(grid, rooms, width, depth, recordNoHighlight);
|
||||||
|
|
||||||
|
return (grid, history);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Internal Generation Logic
|
#region Internal Generation Logic
|
||||||
|
|
||||||
private List<Room> GenerateRooms(MazeReworkCellType[,] grid, int width, int depth, System.Random rng)
|
private List<Room> GenerateRooms(MazeReworkCellType[,] grid, int width, int depth, System.Random rng,
|
||||||
|
Action<int, int, MazeReworkCellType> onCellChanged = null)
|
||||||
{
|
{
|
||||||
List<Room> rooms = new List<Room>();
|
List<Room> rooms = new List<Room>();
|
||||||
if (!_config.generateRooms) return rooms;
|
if (!_config.generateRooms) return rooms;
|
||||||
@@ -144,22 +224,18 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
bool overlaps = false;
|
bool overlaps = false;
|
||||||
foreach (var r in rooms)
|
foreach (var r in rooms)
|
||||||
{
|
{
|
||||||
if (newRoom.Overlaps(r, 1))
|
if (newRoom.Overlaps(r, 1)) { overlaps = true; break; }
|
||||||
{
|
|
||||||
overlaps = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlaps)
|
if (!overlaps)
|
||||||
{
|
{
|
||||||
rooms.Add(newRoom);
|
rooms.Add(newRoom);
|
||||||
// Carve room cells
|
|
||||||
for (int z = rz; z < rz + rh; z++)
|
for (int z = rz; z < rz + rh; z++)
|
||||||
{
|
{
|
||||||
for (int x = rx; x < rx + rw; x++)
|
for (int x = rx; x < rx + rw; x++)
|
||||||
{
|
{
|
||||||
grid[x, z] = MazeReworkCellType.Room;
|
grid[x, z] = MazeReworkCellType.Room;
|
||||||
|
onCellChanged?.Invoke(x, z, MazeReworkCellType.Room);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +258,26 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CarveFrom(int cx, int cz, MazeReworkCellType[,] grid, bool[,] visited, List<Room> rooms, System.Random rng, int width, int depth)
|
/// <summary>
|
||||||
|
/// Factory that returns the correct algorithm based on config selection.
|
||||||
|
/// </summary>
|
||||||
|
private IMazeReworkAlgorithm GetAlgorithm()
|
||||||
|
{
|
||||||
|
return _config.algorithm switch
|
||||||
|
{
|
||||||
|
MazeAlgorithmType.DFSRecursive => new DFSRecursive(),
|
||||||
|
MazeAlgorithmType.DFSIterative => new DFSIterative(),
|
||||||
|
MazeAlgorithmType.Kruskals => new Kruskals(),
|
||||||
|
MazeAlgorithmType.Prims => new Prims(),
|
||||||
|
_ => new DFSIterative()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// After corridor carving, connects room cells to the corridor network
|
||||||
|
/// by carving doorway walls between corridors and rooms.
|
||||||
|
/// </summary>
|
||||||
|
private void ConnectRoomsFrom(int cx, int cz, MazeReworkCellType[,] grid, bool[,] visited, List<Room> rooms, System.Random rng, int width, int depth)
|
||||||
{
|
{
|
||||||
Vector2Int[] dirs = new Vector2Int[4]
|
Vector2Int[] dirs = new Vector2Int[4]
|
||||||
{
|
{
|
||||||
@@ -215,7 +310,7 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
grid[nx, nz] = MazeReworkCellType.Corridor;
|
grid[nx, nz] = MazeReworkCellType.Corridor;
|
||||||
visited[wx, wz] = true;
|
visited[wx, wz] = true;
|
||||||
visited[nx, nz] = true;
|
visited[nx, nz] = true;
|
||||||
CarveFrom(nx, nz, grid, visited, rooms, rng, width, depth);
|
ConnectRoomsFrom(nx, nz, grid, visited, rooms, rng, width, depth);
|
||||||
}
|
}
|
||||||
else if (grid[nx, nz] == MazeReworkCellType.Room)
|
else if (grid[nx, nz] == MazeReworkCellType.Room)
|
||||||
{
|
{
|
||||||
@@ -244,7 +339,9 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnsureAllConnected(MazeReworkCellType[,] grid, bool[,] visited, List<Room> rooms, System.Random rng, int width, int depth)
|
private void EnsureAllConnected(MazeReworkCellType[,] grid, bool[,] visited, List<Room> rooms,
|
||||||
|
System.Random rng, int width, int depth,
|
||||||
|
Action<int, int, MazeReworkCellType> onCellChanged = null)
|
||||||
{
|
{
|
||||||
for (int z = 1; z < depth - 1; z += 2)
|
for (int z = 1; z < depth - 1; z += 2)
|
||||||
{
|
{
|
||||||
@@ -254,50 +351,30 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
{
|
{
|
||||||
Vector2Int[] dirs = new Vector2Int[4]
|
Vector2Int[] dirs = new Vector2Int[4]
|
||||||
{
|
{
|
||||||
new Vector2Int(2, 0),
|
new Vector2Int(2, 0), new Vector2Int(-2, 0),
|
||||||
new Vector2Int(-2, 0),
|
new Vector2Int(0, 2), new Vector2Int(0, -2)
|
||||||
new Vector2Int(0, 2),
|
|
||||||
new Vector2Int(0, -2)
|
|
||||||
};
|
};
|
||||||
|
for (int i = 3; i > 0; i--) { int j = rng.Next(i + 1); var t = dirs[i]; dirs[i] = dirs[j]; dirs[j] = t; }
|
||||||
for (int i = 3; i > 0; i--)
|
|
||||||
{
|
|
||||||
int j = rng.Next(i + 1);
|
|
||||||
var temp = dirs[i];
|
|
||||||
dirs[i] = dirs[j];
|
|
||||||
dirs[j] = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
int nx = x + dirs[i].x;
|
int nx = x + dirs[i].x, nz = z + dirs[i].y;
|
||||||
int nz = z + dirs[i].y;
|
int wx = x + dirs[i].x / 2, wz = z + dirs[i].y / 2;
|
||||||
int wx = x + dirs[i].x / 2;
|
if (nx > 0 && nx < width - 1 && nz > 0 && nz < depth - 1 && visited[nx, nz])
|
||||||
int wz = z + dirs[i].y / 2;
|
|
||||||
|
|
||||||
if (nx > 0 && nx < width - 1 && nz > 0 && nz < depth - 1)
|
|
||||||
{
|
|
||||||
if (visited[nx, nz])
|
|
||||||
{
|
{
|
||||||
grid[wx, wz] = MazeReworkCellType.Corridor;
|
grid[wx, wz] = MazeReworkCellType.Corridor;
|
||||||
grid[x, z] = MazeReworkCellType.Corridor;
|
grid[x, z] = MazeReworkCellType.Corridor;
|
||||||
visited[wx, wz] = true;
|
visited[wx, wz] = visited[x, z] = true;
|
||||||
visited[x, z] = true;
|
onCellChanged?.Invoke(wx, wz, MazeReworkCellType.Corridor);
|
||||||
|
onCellChanged?.Invoke(x, z, MazeReworkCellType.Corridor);
|
||||||
connected = true;
|
connected = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (connected)
|
ConnectRoomsFrom(x, z, grid, visited, rooms, rng, width, depth);
|
||||||
{
|
_ = connected; // suppress unused warning
|
||||||
CarveFrom(x, z, grid, visited, rooms, rng, width, depth);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CarveFrom(x, z, grid, visited, rooms, rng, width, depth);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,74 +384,31 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
var room = rooms[i];
|
var room = rooms[i];
|
||||||
if (!room.isConnected)
|
if (!room.isConnected)
|
||||||
{
|
{
|
||||||
ForceConnectRoom(grid, room, visited, rng, width, depth);
|
ForceConnectRoom(grid, room, visited, rng, width, depth, onCellChanged);
|
||||||
room.isConnected = true;
|
room.isConnected = true;
|
||||||
rooms[i] = room;
|
rooms[i] = room;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ForceConnectRoom(MazeReworkCellType[,] grid, Room room, bool[,] visited, System.Random rng, int width, int depth)
|
private void ForceConnectRoom(MazeReworkCellType[,] grid, Room room, bool[,] visited,
|
||||||
|
System.Random rng, int width, int depth,
|
||||||
|
Action<int, int, MazeReworkCellType> onCellChanged = null)
|
||||||
{
|
{
|
||||||
int[] sides = new int[] { 0, 1, 2, 3 };
|
int[] sides = new int[] { 0, 1, 2, 3 };
|
||||||
for (int i = 3; i > 0; i--)
|
for (int i = 3; i > 0; i--) { int j = rng.Next(i + 1); int t = sides[i]; sides[i] = sides[j]; sides[j] = t; }
|
||||||
{
|
|
||||||
int j = rng.Next(i + 1);
|
|
||||||
int temp = sides[i];
|
|
||||||
sides[i] = sides[j];
|
|
||||||
sides[j] = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (int side in sides)
|
foreach (int side in sides)
|
||||||
{
|
{
|
||||||
if (side == 0)
|
if (side == 0) { int z = room.z + room.depth - 1; if (z + 2 < depth - 1) { int x = room.x + 2 * rng.Next(0, room.width / 2); grid[x, z + 1] = MazeReworkCellType.Corridor; visited[x, z + 1] = true; onCellChanged?.Invoke(x, z + 1, MazeReworkCellType.Corridor); return; } }
|
||||||
{
|
else if (side == 1) { int z = room.z; if (z - 2 > 0) { int x = room.x + 2 * rng.Next(0, room.width / 2); grid[x, z - 1] = MazeReworkCellType.Corridor; visited[x, z - 1] = true; onCellChanged?.Invoke(x, z - 1, MazeReworkCellType.Corridor); return; } }
|
||||||
int z = room.z + room.depth - 1;
|
else if (side == 2) { int x = room.x; if (x - 2 > 0) { int z = room.z + 2 * rng.Next(0, room.depth / 2); grid[x - 1, z] = MazeReworkCellType.Corridor; visited[x - 1, z] = true; onCellChanged?.Invoke(x - 1, z, MazeReworkCellType.Corridor); return; } }
|
||||||
if (z + 2 < depth - 1)
|
else if (side == 3) { int x = room.x + room.width - 1; if (x + 2 < width - 1) { int z = room.z + 2 * rng.Next(0, room.depth / 2); grid[x + 1, z] = MazeReworkCellType.Corridor; visited[x + 1, z] = true; onCellChanged?.Invoke(x + 1, z, MazeReworkCellType.Corridor); return; } }
|
||||||
{
|
|
||||||
int x = room.x + 2 * rng.Next(0, room.width / 2);
|
|
||||||
grid[x, z + 1] = MazeReworkCellType.Corridor;
|
|
||||||
visited[x, z + 1] = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (side == 1)
|
|
||||||
{
|
|
||||||
int z = room.z;
|
|
||||||
if (z - 2 > 0)
|
|
||||||
{
|
|
||||||
int x = room.x + 2 * rng.Next(0, room.width / 2);
|
|
||||||
grid[x, z - 1] = MazeReworkCellType.Corridor;
|
|
||||||
visited[x, z - 1] = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (side == 2)
|
|
||||||
{
|
|
||||||
int x = room.x;
|
|
||||||
if (x - 2 > 0)
|
|
||||||
{
|
|
||||||
int z = room.z + 2 * rng.Next(0, room.depth / 2);
|
|
||||||
grid[x - 1, z] = MazeReworkCellType.Corridor;
|
|
||||||
visited[x - 1, z] = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (side == 3)
|
|
||||||
{
|
|
||||||
int x = room.x + room.width - 1;
|
|
||||||
if (x + 2 < width - 1)
|
|
||||||
{
|
|
||||||
int z = room.z + 2 * rng.Next(0, room.depth / 2);
|
|
||||||
grid[x + 1, z] = MazeReworkCellType.Corridor;
|
|
||||||
visited[x + 1, z] = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CarveLoops(MazeReworkCellType[,] grid, System.Random rng, int width, int depth)
|
private void CarveLoops(MazeReworkCellType[,] grid, System.Random rng, int width, int depth,
|
||||||
|
Action<int, int, MazeReworkCellType> onCellChanged = null)
|
||||||
{
|
{
|
||||||
if (_config.loopChance <= 0f) return;
|
if (_config.loopChance <= 0f) return;
|
||||||
|
|
||||||
@@ -384,89 +418,65 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
{
|
{
|
||||||
bool isHorizontalWall = (x % 2 == 0 && z % 2 != 0);
|
bool isHorizontalWall = (x % 2 == 0 && z % 2 != 0);
|
||||||
bool isVerticalWall = (x % 2 != 0 && z % 2 == 0);
|
bool isVerticalWall = (x % 2 != 0 && z % 2 == 0);
|
||||||
|
|
||||||
if (!isHorizontalWall && !isVerticalWall) continue;
|
if (!isHorizontalWall && !isVerticalWall) continue;
|
||||||
|
|
||||||
if (grid[x, z] == MazeReworkCellType.Wall)
|
if (grid[x, z] == MazeReworkCellType.Wall)
|
||||||
{
|
{
|
||||||
if (isHorizontalWall)
|
bool carve = isHorizontalWall
|
||||||
{
|
? IsPathCell(grid[x - 1, z]) && IsPathCell(grid[x + 1, z])
|
||||||
if (IsPathCell(grid[x - 1, z]) && IsPathCell(grid[x + 1, z]))
|
: IsPathCell(grid[x, z - 1]) && IsPathCell(grid[x, z + 1]);
|
||||||
{
|
|
||||||
if (rng.NextDouble() < _config.loopChance)
|
if (carve && rng.NextDouble() < _config.loopChance)
|
||||||
{
|
{
|
||||||
grid[x, z] = MazeReworkCellType.Corridor;
|
grid[x, z] = MazeReworkCellType.Corridor;
|
||||||
}
|
onCellChanged?.Invoke(x, z, MazeReworkCellType.Corridor);
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (IsPathCell(grid[x, z - 1]) && IsPathCell(grid[x, z + 1]))
|
|
||||||
{
|
|
||||||
if (rng.NextDouble() < _config.loopChance)
|
|
||||||
{
|
|
||||||
grid[x, z] = MazeReworkCellType.Corridor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlaceStartAndEnd(MazeReworkCellType[,] grid, List<Room> rooms, int width, int depth)
|
private void PlaceStartAndEnd(MazeReworkCellType[,] grid, List<Room> rooms, int width, int depth,
|
||||||
|
Action<int, int, MazeReworkCellType> onCellChanged = null)
|
||||||
{
|
{
|
||||||
if (rooms != null && rooms.Count > 0)
|
if (rooms != null && rooms.Count > 0)
|
||||||
{
|
{
|
||||||
var startRoom = rooms[0];
|
var startRoom = rooms[0];
|
||||||
var startPt = startRoom.GetCenter();
|
var startPt = startRoom.GetCenter();
|
||||||
grid[startPt.x, startPt.y] = MazeReworkCellType.Start;
|
grid[startPt.x, startPt.y] = MazeReworkCellType.Start;
|
||||||
|
onCellChanged?.Invoke(startPt.x, startPt.y, MazeReworkCellType.Start);
|
||||||
|
|
||||||
var endRoom = rooms[rooms.Count - 1];
|
var endRoom = rooms[rooms.Count - 1];
|
||||||
var endPt = endRoom.GetCenter();
|
var endPt = endRoom.GetCenter();
|
||||||
if (endPt == startPt && rooms.Count > 1)
|
if (endPt == startPt && rooms.Count > 1) { endRoom = rooms[1]; endPt = endRoom.GetCenter(); }
|
||||||
{
|
|
||||||
endRoom = rooms[1];
|
|
||||||
endPt = endRoom.GetCenter();
|
|
||||||
}
|
|
||||||
grid[endPt.x, endPt.y] = MazeReworkCellType.End;
|
grid[endPt.x, endPt.y] = MazeReworkCellType.End;
|
||||||
|
onCellChanged?.Invoke(endPt.x, endPt.y, MazeReworkCellType.End);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int sx = _config.startLocation.x;
|
int sx = _config.startLocation.x, sz = _config.startLocation.y;
|
||||||
int sz = _config.startLocation.y;
|
|
||||||
EnsureValidOddCoordinates(width, depth, ref sx, ref sz);
|
EnsureValidOddCoordinates(width, depth, ref sx, ref sz);
|
||||||
grid[sx, sz] = MazeReworkCellType.Start;
|
grid[sx, sz] = MazeReworkCellType.Start;
|
||||||
|
onCellChanged?.Invoke(sx, sz, MazeReworkCellType.Start);
|
||||||
|
|
||||||
int ex = width - 2;
|
int ex = width - 2, ez = depth - 2;
|
||||||
int ez = depth - 2;
|
|
||||||
EnsureValidOddCoordinates(width, depth, ref ex, ref ez);
|
EnsureValidOddCoordinates(width, depth, ref ex, ref ez);
|
||||||
|
|
||||||
if (grid[ex, ez] == MazeReworkCellType.Wall)
|
if (grid[ex, ez] == MazeReworkCellType.Wall)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int r = 1; r < Mathf.Max(width, depth) && !found; r++)
|
for (int r = 1; r < Mathf.Max(width, depth) && !found; r++)
|
||||||
|
for (int ddx = -r; ddx <= r && !found; ddx++)
|
||||||
|
for (int ddz = -r; ddz <= r && !found; ddz++)
|
||||||
{
|
{
|
||||||
for (int dx = -r; dx <= r && !found; dx++)
|
int tx = ex + ddx, tz = ez + ddz;
|
||||||
{
|
|
||||||
for (int dz = -r; dz <= r && !found; dz++)
|
|
||||||
{
|
|
||||||
int tx = ex + dx;
|
|
||||||
int tz = ez + dz;
|
|
||||||
if (tx >= 0 && tx < width && tz >= 0 && tz < depth && IsPathCell(grid[tx, tz]))
|
if (tx >= 0 && tx < width && tz >= 0 && tz < depth && IsPathCell(grid[tx, tz]))
|
||||||
{
|
{ ex = tx; ez = tz; found = true; }
|
||||||
ex = tx;
|
|
||||||
ez = tz;
|
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ex != sx || ez != sz)
|
if (ex != sx || ez != sz)
|
||||||
{
|
{
|
||||||
grid[ex, ez] = MazeReworkCellType.End;
|
grid[ex, ez] = MazeReworkCellType.End;
|
||||||
|
onCellChanged?.Invoke(ex, ez, MazeReworkCellType.End);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Sirenix.OdinInspector;
|
using Sirenix.OdinInspector;
|
||||||
|
using Baba_yaga.GameSetup.MazeRework.Animation;
|
||||||
|
|
||||||
namespace Baba_yaga.GameSetup.MazeRework
|
namespace Baba_yaga.GameSetup.MazeRework
|
||||||
{
|
{
|
||||||
@@ -16,6 +17,11 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
[Header("References")]
|
[Header("References")]
|
||||||
[SerializeField] private MazeReworkSpawner spawner;
|
[SerializeField] private MazeReworkSpawner spawner;
|
||||||
[SerializeField] private Transform mazeContainer;
|
[SerializeField] private Transform mazeContainer;
|
||||||
|
[SerializeField] private MazeAnimator animator;
|
||||||
|
|
||||||
|
[Header("Animation")]
|
||||||
|
[Tooltip("If true, visually animates the generation process step-by-step. (Best used with 1 floor)")]
|
||||||
|
[SerializeField] private bool animateGeneration = false;
|
||||||
|
|
||||||
[Header("Multi-floor Settings")]
|
[Header("Multi-floor Settings")]
|
||||||
[Tooltip("Number of floors to generate.")]
|
[Tooltip("Number of floors to generate.")]
|
||||||
@@ -102,10 +108,27 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
|
|
||||||
// Clear any previously spawned maze objects
|
// Clear any previously spawned maze objects
|
||||||
ClearMaze();
|
ClearMaze();
|
||||||
|
if (animator != null) animator.StopAnimation();
|
||||||
|
|
||||||
var generator = new MazeReworkGenerator(config);
|
var generator = new MazeReworkGenerator(config);
|
||||||
|
|
||||||
// Generate each floor using the configuration
|
if (animateGeneration && animator != null)
|
||||||
|
{
|
||||||
|
// Animated mode: generates floor 0 and replays the creation step-by-step
|
||||||
|
int seed = config.useRandomSeed ? Random.Range(0, 1000000) : config.seed;
|
||||||
|
var (grid, history) = generator.GenerateAnimated(seed);
|
||||||
|
_grids.Add(grid);
|
||||||
|
|
||||||
|
BeginningWorldPosition = FindBeginningWorldPosition(grid);
|
||||||
|
|
||||||
|
animator.AnimateGeneration(history, grid, spawner, 0f, mazeContainer, () =>
|
||||||
|
{
|
||||||
|
Debug.Log($"[MazeReworkManager] Animation complete. Beginning world position: {BeginningWorldPosition}");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Standard instantaneous generation
|
||||||
for (int i = 0; i < floorCount; i++)
|
for (int i = 0; i < floorCount; i++)
|
||||||
{
|
{
|
||||||
int seed = config.useRandomSeed ? Random.Range(0, 1000000) : config.seed + i * 1000;
|
int seed = config.useRandomSeed ? Random.Range(0, 1000000) : config.seed + i * 1000;
|
||||||
@@ -130,6 +153,7 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
BeginningWorldPosition = FindBeginningWorldPosition(_grids[0]);
|
BeginningWorldPosition = FindBeginningWorldPosition(_grids[0]);
|
||||||
Debug.Log($"[MazeReworkManager] Beginning world position set to: {BeginningWorldPosition}");
|
Debug.Log($"[MazeReworkManager] Beginning world position set to: {BeginningWorldPosition}");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void GenerateConnections()
|
private void GenerateConnections()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Baba_yaga.GameSetup.MazeRework.Animation;
|
||||||
|
|
||||||
namespace Baba_yaga.GameSetup.MazeRework
|
namespace Baba_yaga.GameSetup.MazeRework
|
||||||
{
|
{
|
||||||
@@ -27,6 +28,11 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
[Tooltip("Prefab for the End cell (player exit point). Auto-rotates based on neighbors.")]
|
[Tooltip("Prefab for the End cell (player exit point). Auto-rotates based on neighbors.")]
|
||||||
public GameObject endPrefab;
|
public GameObject endPrefab;
|
||||||
|
|
||||||
|
[Header("Highlight Prefabs (Animation Only)")]
|
||||||
|
public GameObject searchHeadPrefab;
|
||||||
|
public GameObject frontierPrefab;
|
||||||
|
public GameObject evaluatingPrefab;
|
||||||
|
|
||||||
[Header("Rotation Offsets (Degrees)")]
|
[Header("Rotation Offsets (Degrees)")]
|
||||||
[Tooltip("Rotation offset added to Hall 'I' prefab.")]
|
[Tooltip("Rotation offset added to Hall 'I' prefab.")]
|
||||||
public float hallRotationOffset = 0f;
|
public float hallRotationOffset = 0f;
|
||||||
@@ -47,7 +53,8 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
[Tooltip("Physical distance between each grid cell center.")]
|
[Tooltip("Physical distance between each grid cell center.")]
|
||||||
public float spacing = 3.0f;
|
public float spacing = 3.0f;
|
||||||
|
|
||||||
private readonly List<GameObject> _spawnedObjects = new List<GameObject>();
|
private readonly Dictionary<Vector2Int, GameObject> _spawnedObjects = new Dictionary<Vector2Int, GameObject>();
|
||||||
|
private readonly Dictionary<Vector2Int, GameObject> _spawnedHighlights = new Dictionary<Vector2Int, GameObject>();
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
@@ -73,20 +80,21 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
foreach (var obj in _spawnedObjects)
|
foreach (var obj in _spawnedObjects.Values)
|
||||||
{
|
{
|
||||||
if (obj == null) continue;
|
if (obj == null) continue;
|
||||||
if (Application.isPlaying)
|
if (Application.isPlaying) Destroy(obj); else DestroyImmediate(obj);
|
||||||
Destroy(obj);
|
|
||||||
else
|
|
||||||
DestroyImmediate(obj);
|
|
||||||
}
|
}
|
||||||
_spawnedObjects.Clear();
|
_spawnedObjects.Clear();
|
||||||
|
|
||||||
|
foreach (var obj in _spawnedHighlights.Values)
|
||||||
|
{
|
||||||
|
if (obj == null) continue;
|
||||||
|
if (Application.isPlaying) Destroy(obj); else DestroyImmediate(obj);
|
||||||
|
}
|
||||||
|
_spawnedHighlights.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Spawns the modular prefabs based on the generated 2D grid array.
|
|
||||||
/// </summary>
|
|
||||||
public void Spawn(MazeReworkCellType[,] grid, float yOffset, Transform container)
|
public void Spawn(MazeReworkCellType[,] grid, float yOffset, Transform container)
|
||||||
{
|
{
|
||||||
if (grid == null) return;
|
if (grid == null) return;
|
||||||
@@ -99,39 +107,95 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
{
|
{
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
MazeReworkCellType type = grid[x, z];
|
RefreshSingleCell(grid, null, x, z, width, depth, yOffset, container);
|
||||||
|
}
|
||||||
// Wall cells spawn nothing
|
}
|
||||||
if (type == MazeReworkCellType.Wall)
|
}
|
||||||
{
|
|
||||||
continue;
|
/// <summary>
|
||||||
|
/// Refreshes a specific cell and its neighbors based on the current grid state.
|
||||||
|
/// </summary>
|
||||||
|
public void RefreshCell(MazeReworkCellType[,] grid, MazeCellHighlight[,] highlights, int x, int z, float yOffset, Transform container)
|
||||||
|
{
|
||||||
|
if (grid == null) return;
|
||||||
|
int width = grid.GetLength(0);
|
||||||
|
int depth = grid.GetLength(1);
|
||||||
|
|
||||||
|
// Refresh the target cell
|
||||||
|
RefreshSingleCell(grid, highlights, x, z, width, depth, yOffset, container);
|
||||||
|
|
||||||
|
// Refresh neighbors because their connectivity might have changed
|
||||||
|
RefreshSingleCell(grid, highlights, x + 1, z, width, depth, yOffset, container);
|
||||||
|
RefreshSingleCell(grid, highlights, x - 1, z, width, depth, yOffset, container);
|
||||||
|
RefreshSingleCell(grid, highlights, x, z + 1, width, depth, yOffset, container);
|
||||||
|
RefreshSingleCell(grid, highlights, x, z - 1, width, depth, yOffset, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshSingleCell(MazeReworkCellType[,] grid, MazeCellHighlight[,] highlights, int x, int z, int width, int depth, float yOffset, Transform container)
|
||||||
|
{
|
||||||
|
if (x < 0 || x >= width || z < 0 || z >= depth) return;
|
||||||
|
|
||||||
|
Vector2Int pos = new Vector2Int(x, z);
|
||||||
|
MazeReworkCellType type = grid[x, z];
|
||||||
|
MazeCellHighlight hType = highlights != null ? highlights[x, z] : MazeCellHighlight.None;
|
||||||
|
|
||||||
|
// 1. Process Highlights
|
||||||
|
if (_spawnedHighlights.TryGetValue(pos, out GameObject existingHighlight))
|
||||||
|
{
|
||||||
|
if (Application.isPlaying) Destroy(existingHighlight);
|
||||||
|
else DestroyImmediate(existingHighlight);
|
||||||
|
_spawnedHighlights.Remove(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hType != MazeCellHighlight.None)
|
||||||
|
{
|
||||||
|
GameObject hPrefab = null;
|
||||||
|
if (hType == MazeCellHighlight.SearchHead) hPrefab = searchHeadPrefab;
|
||||||
|
else if (hType == MazeCellHighlight.Frontier) hPrefab = frontierPrefab;
|
||||||
|
else if (hType == MazeCellHighlight.Evaluating) hPrefab = evaluatingPrefab;
|
||||||
|
|
||||||
|
if (hPrefab != null)
|
||||||
|
{
|
||||||
|
Vector3 localPos = new Vector3(x * spacing, yOffset, z * spacing);
|
||||||
|
GameObject spawnedH = Instantiate(hPrefab, container != null ? container : transform);
|
||||||
|
spawnedH.transform.localPosition = localPos;
|
||||||
|
spawnedH.name = $"Highlight_{hType}_{x}_{z}";
|
||||||
|
_spawnedHighlights[pos] = spawnedH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Process Grid Cells
|
||||||
|
if (type == MazeReworkCellType.Wall)
|
||||||
|
{
|
||||||
|
if (_spawnedObjects.TryGetValue(pos, out GameObject existing))
|
||||||
|
{
|
||||||
|
if (Application.isPlaying) Destroy(existing);
|
||||||
|
else DestroyImmediate(existing);
|
||||||
|
_spawnedObjects.Remove(pos);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Start and End cells, use their dedicated prefab if assigned,
|
|
||||||
// then apply connectivity-based rotation so they face the correct open direction.
|
|
||||||
if (type == MazeReworkCellType.Start && beginningPrefab != null)
|
if (type == MazeReworkCellType.Start && beginningPrefab != null)
|
||||||
{
|
{
|
||||||
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
||||||
SpawnPrefab(beginningPrefab, x, yOffset, z, baseRot + beginningRotationOffset, container, "Beginning");
|
SpawnPrefab(beginningPrefab, x, yOffset, z, baseRot + beginningRotationOffset, container, "Beginning");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == MazeReworkCellType.End && endPrefab != null)
|
if (type == MazeReworkCellType.End && endPrefab != null)
|
||||||
{
|
{
|
||||||
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
||||||
SpawnPrefab(endPrefab, x, yOffset, z, baseRot + endRotationOffset, container, "End");
|
SpawnPrefab(endPrefab, x, yOffset, z, baseRot + endRotationOffset, container, "End");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All other path cells: evaluate connectivity to select and rotate the modular hallway prefab
|
|
||||||
(GameObject modularPrefab, float yRotation) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
(GameObject modularPrefab, float yRotation) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
||||||
if (modularPrefab != null)
|
if (modularPrefab != null)
|
||||||
{
|
{
|
||||||
SpawnPrefab(modularPrefab, x, yOffset, z, yRotation, container, $"{type}");
|
SpawnPrefab(modularPrefab, x, yOffset, z, yRotation, container, $"{type}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SpawnPrefab(GameObject prefab, int x, float y, int z, float yRotation, Transform container, string namePrefix)
|
private void SpawnPrefab(GameObject prefab, int x, float y, int z, float yRotation, Transform container, string namePrefix)
|
||||||
{
|
{
|
||||||
@@ -140,7 +204,14 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
spawnedObj.transform.localPosition = localPosition;
|
spawnedObj.transform.localPosition = localPosition;
|
||||||
spawnedObj.transform.localRotation = Quaternion.Euler(0f, yRotation, 0f);
|
spawnedObj.transform.localRotation = Quaternion.Euler(0f, yRotation, 0f);
|
||||||
spawnedObj.name = $"{namePrefix}_{x}_{z}";
|
spawnedObj.name = $"{namePrefix}_{x}_{z}";
|
||||||
_spawnedObjects.Add(spawnedObj);
|
|
||||||
|
var pos = new Vector2Int(x, z);
|
||||||
|
if (_spawnedObjects.TryGetValue(pos, out GameObject existing))
|
||||||
|
{
|
||||||
|
if (Application.isPlaying) Destroy(existing);
|
||||||
|
else DestroyImmediate(existing);
|
||||||
|
}
|
||||||
|
_spawnedObjects[pos] = spawnedObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (GameObject, float) GetModularPrefabAndRotation(MazeReworkCellType[,] grid, int x, int z, int width, int depth)
|
private (GameObject, float) GetModularPrefabAndRotation(MazeReworkCellType[,] grid, int x, int z, int width, int depth)
|
||||||
|
|||||||
Reference in New Issue
Block a user