From e04c615f44df1a06cf9df464b66aeaa57e498c3b Mon Sep 17 00:00:00 2001 From: Xevion Date: Tue, 10 Nov 2020 00:18:01 -0600 Subject: [PATCH] continuously re-path, random start/end positions, 2 index skip speed, update shader colors --- Paths/Assets/Scenes/Default.unity | 227 +++++++++++++++++++ Paths/Assets/Scripts/Algorithms/AStar.cs | 45 ++-- Paths/Assets/Scripts/Algorithms/NodeGrid.cs | 7 +- Paths/Assets/Scripts/Manager.cs | 72 ++++-- Paths/Assets/Scripts/Pathfinding.cs | 2 + Paths/Assets/Shaders/GridShader Material.mat | 7 +- Paths/Assets/Shaders/GridShader.shader | 6 +- 7 files changed, 317 insertions(+), 49 deletions(-) diff --git a/Paths/Assets/Scenes/Default.unity b/Paths/Assets/Scenes/Default.unity index 3dba733..a41abd2 100644 --- a/Paths/Assets/Scenes/Default.unity +++ b/Paths/Assets/Scenes/Default.unity @@ -203,3 +203,230 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1373243071 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1373243072} + - component: {fileID: 1373243073} + m_Layer: 0 + m_Name: Game Manager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1373243072 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1373243071} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1373243073 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1373243071} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ca142250b9964eb1adf66ac7c5cc3e3e, type: 3} + m_Name: + m_EditorClassIdentifier: + gridController: {fileID: 2092623185} +--- !u!1 &1951333406 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1951333408} + - component: {fileID: 1951333407} + 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 &1951333407 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1951333406} + m_Enabled: 1 + serializedVersion: 9 + m_Type: 1 + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_Intensity: 1.49 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 0 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &1951333408 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1951333406} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -8.05} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2092623184 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2092623188} + - component: {fileID: 2092623187} + - component: {fileID: 2092623186} + - component: {fileID: 2092623185} + m_Layer: 0 + m_Name: GridController + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2092623185 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2092623184} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ae862ef271614573a2ecacb6d9fa2078, type: 3} + m_Name: + m_EditorClassIdentifier: + gridMaterial: {fileID: 2100000, guid: 780d53bea4df7b0418e9c8ed8afd6410, type: 2} + size: 31 +--- !u!23 &2092623186 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2092623184} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 780d53bea4df7b0418e9c8ed8afd6410, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 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_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &2092623187 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2092623184} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &2092623188 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2092623184} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 10, y: 10, z: 10} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Paths/Assets/Scripts/Algorithms/AStar.cs b/Paths/Assets/Scripts/Algorithms/AStar.cs index b1f908a..7a3871a 100644 --- a/Paths/Assets/Scripts/Algorithms/AStar.cs +++ b/Paths/Assets/Scripts/Algorithms/AStar.cs @@ -14,18 +14,21 @@ namespace Algorithms { private Vector2 _start; private Vector2 _end; + + public Vector2 Start { get => _start; } + public Vector2 End { get => _end; } public AStar(NodeGrid nodeGrid) { this._nodeGrid = nodeGrid; _states = new List(); } - public Stack FindPath(Vector2 Start, Vector2 End) { - this._start = Start; - this._end = End; + public Stack FindPath(Vector2 start, Vector2 end) { + this._start = start; + this._end = end; - var start = new Node(Start, true); - var end = new Node(End, true); + var startNode = new Node(start, true); + var endNode = new Node(end, true); _path = new Stack(); @@ -33,37 +36,39 @@ namespace Algorithms { _closedList = new List(); RecordState(); - Node current = start; + Node current = startNode; // add start node to Open List - _openList.Add(start); + _openList.Add(startNode); - while (_openList.Count != 0 && !_closedList.Exists(x => x.Position == end.Position)) { + while (_openList.Count != 0 && !_closedList.Exists(x => x.Position == endNode.Position)) { current = _openList[0]; _openList.Remove(current); _closedList.Add(current); RecordState(); - IEnumerable adjacentNodes = this._nodeGrid.GetAdjacentNodes(current); + List adjacentNodes = this._nodeGrid.GetAdjacentNodes(current); - foreach (Node n in adjacentNodes) { - if (!_closedList.Contains(n) && n.Walkable) { - if (!_openList.Contains(n)) { - n.Parent = current; - n.DistanceToTarget = NodeGrid.Manhattan(n, end); - n.Cost = n.Weight + n.Parent.Cost; + if (adjacentNodes.Count > 0) { + foreach (Node n in adjacentNodes) { + if (!_closedList.Contains(n) && n.Walkable) { + if (!_openList.Contains(n)) { + n.Parent = current; + n.DistanceToTarget = NodeGrid.Manhattan(n, endNode); + n.Cost = n.Weight + n.Parent.Cost; - _openList.Add(n); - _openList = _openList.OrderBy(node => node.F).ToList(); + _openList.Add(n); + _openList = _openList.OrderBy(node => node.F).ToList(); - RecordState(); + } } } + RecordState(); } } // construct path, if end was not closed return null - if (!_closedList.Exists(x => x.Position == end.Position)) { + if (!_closedList.Exists(x => x.Position == endNode.Position)) { return null; } @@ -74,7 +79,7 @@ namespace Algorithms { _path.Push(temp); RecordState(); temp = temp.Parent; - } while (temp != start && temp != null); + } while (temp != startNode && temp != null); return _path; } diff --git a/Paths/Assets/Scripts/Algorithms/NodeGrid.cs b/Paths/Assets/Scripts/Algorithms/NodeGrid.cs index 212f315..52c2f53 100644 --- a/Paths/Assets/Scripts/Algorithms/NodeGrid.cs +++ b/Paths/Assets/Scripts/Algorithms/NodeGrid.cs @@ -39,7 +39,7 @@ namespace Algorithms { this.Width = this.grid.Count; } - public IEnumerable GetAdjacentNodes(Node node) { + public List GetAdjacentNodes(Node node) { List temp = new List(); int row = (int) node.Position.Y; @@ -79,6 +79,10 @@ namespace Algorithms { return Math.Abs(first.Position.X - second.Position.X) + Math.Abs(first.Position.Y - second.Position.Y); } + public static float Manhattan(Vector2 algorithmStart, Vector2 algorithmEnd) { + return NodeGrid.Manhattan(new Node(algorithmStart, false), new Node(algorithmEnd, false)); + } + /// /// Returns a random Vector2 position within the grid. /// @@ -86,5 +90,6 @@ namespace Algorithms { public Vector2 RandomPosition() { return new Vector2(Random.Range(0, Width - 1), Random.Range(0, Height - 1)); } + } } \ No newline at end of file diff --git a/Paths/Assets/Scripts/Manager.cs b/Paths/Assets/Scripts/Manager.cs index 13ec6aa..23b1168 100644 --- a/Paths/Assets/Scripts/Manager.cs +++ b/Paths/Assets/Scripts/Manager.cs @@ -1,10 +1,9 @@ -using System.Collections; +using System; using System.Collections.Generic; using System.Linq; -using System.Numerics; using Algorithms; -using Vector2 = System.Numerics.Vector2; using UnityEngine; +using Vector2 = System.Numerics.Vector2; /// /// The primary controller of the entire application, managing state, events and sending commands @@ -12,28 +11,53 @@ using UnityEngine; public class Manager : MonoBehaviour { public GridController gridController; private IPathfinding _algorithm; - + private List _states; + private int _curIndex; + private Stack path; + public void Start() { - var nodeGrid = new NodeGrid(gridController.size, gridController.size); - _algorithm = new AStar(nodeGrid); - - Vector2 start = new Vector2(0, 0); - Vector2 end = new Vector2(16, 16); - - foreach(int index in Enumerable.Range(0, 150)) - nodeGrid.FlipRandomWall(); - - Stack path = _algorithm.FindPath(start, end); - - List states = _algorithm.GetStates(); - gridController.LoadGridState(states[states.Count - 1]); - Debug.Log(states[states.Count - 1].RenderGrid()); - Debug.Log(start); - Debug.Log(end); - - // StartCoroutine(LateStart()); + GeneratePath(); + _states = new List(); } - // IEnumerator LateStart() { - // } + public void Update() { + if (_curIndex < _states.Count) + this.LoadNextState(); + else { + float t1 = Time.time, t2 = Time.time; + try { + t1 = Time.time; + GeneratePath(); + _curIndex = 0; + Debug.Log($"({NodeGrid.Manhattan(_algorithm.Start, _algorithm.End)} in {_states.Count} states. {path.Count} path length."); + t2 = Time.time; + // Debug.Log(t2 - t1); + } + catch (ArgumentOutOfRangeException e) { + } + } + } + + private void GeneratePath() { + var nodeGrid = new NodeGrid(gridController.size, gridController.size); + _algorithm = new AStar(nodeGrid); + + Vector2 start = nodeGrid.RandomPosition(); + Vector2 end = nodeGrid.RandomPosition(); + // Vector2 start = new Vector2(1, 1); + // Vector2 end = new Vector2(gridController.size - 5, gridController.size - 5); + + foreach (int index in Enumerable.Range(0, 300)) + nodeGrid.FlipRandomWall(); + + path = _algorithm.FindPath(start, end); + + _states = _algorithm.GetStates(); + } + + private void LoadNextState() { + GridState state = _states[_curIndex]; + gridController.LoadGridState(state); + _curIndex += 2; + } } \ No newline at end of file diff --git a/Paths/Assets/Scripts/Pathfinding.cs b/Paths/Assets/Scripts/Pathfinding.cs index bc62ddc..8f06ddd 100644 --- a/Paths/Assets/Scripts/Pathfinding.cs +++ b/Paths/Assets/Scripts/Pathfinding.cs @@ -20,4 +20,6 @@ public interface IPathfinding { void RecordState(); List GetStates(); + Vector2 Start { get; } + Vector2 End { get; } } \ No newline at end of file diff --git a/Paths/Assets/Shaders/GridShader Material.mat b/Paths/Assets/Shaders/GridShader Material.mat index 0123d42..9a98b3c 100644 --- a/Paths/Assets/Shaders/GridShader Material.mat +++ b/Paths/Assets/Shaders/GridShader Material.mat @@ -8,7 +8,7 @@ Material: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: GridShader Material - m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_Shader: {fileID: 4800000, guid: b4e207edb1333434ba20f91ec9066366, type: 3} m_ShaderKeywords: m_LightmapFlags: 4 m_EnableInstancingVariants: 0 @@ -63,6 +63,8 @@ Material: - _GlossMapScale: 1 - _Glossiness: 0.5 - _GlossyReflections: 1 + - _GridSize: 31 + - _LineSize: 0.055 - _Metallic: 0 - _Mode: 0 - _OcclusionStrength: 1 @@ -73,5 +75,8 @@ Material: - _UVSec: 0 - _ZWrite: 1 m_Colors: + - _ActiveColor: {r: 1, g: 0, b: 0, a: 1} - _Color: {r: 1, g: 1, b: 1, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _InactiveColor: {r: 0, g: 0, b: 0, a: 0} + - _LineColor: {r: 1, g: 1, b: 1, a: 1} diff --git a/Paths/Assets/Shaders/GridShader.shader b/Paths/Assets/Shaders/GridShader.shader index ae5c99c..2f14279 100644 --- a/Paths/Assets/Shaders/GridShader.shader +++ b/Paths/Assets/Shaders/GridShader.shader @@ -33,12 +33,12 @@ Shader "PDT Shaders/TestGrid" { float4 _ActiveColor; static const float4 _gridColors[7] = { - float4(255 / 255.0, 255 / 255.0, 255 / 255.0, 0.0), // Empty - float4(50 / 255.0, 50 / 255.0, 50 / 255.0, 1.0), // Wall + float4(255 / 255.0, 255 / 255.0, 255 / 255.0, 1.0), // Empty + float4(0 / 255.0, 0 / 255.0, 0 / 255.0, 1.0), // Wall float4(0 / 255.0, 255 / 255.0, 0 / 255.0, 1.0), // Start float4(255 / 255.0, 0 / 255.0, 0 / 255.0, 1.0), // End float4(252 / 255.0, 236 / 255.0, 3 / 255.0, 1.0), // Seen - float4(252 / 255.0, 127 / 255.0, 3 / 255.0, 1.0), // Expanded + float4(227 / 255.0, 65 / 255.0, 11 / 255.0, 1.0), // Expanded float4(166 / 255.0, 2 / 255.0, 51 / 255.0, 1.0) // Path };