├── Project ├── .gitignore ├── Assets │ ├── 3rd.meta │ ├── 3rd │ │ ├── PriorityQueue.meta │ │ └── PriorityQueue │ │ │ ├── FastPriorityQueue.cs │ │ │ ├── FastPriorityQueue.cs.meta │ │ │ ├── FastPriorityQueueNode.cs │ │ │ ├── FastPriorityQueueNode.cs.meta │ │ │ ├── GenericPriorityQueue.cs │ │ │ ├── GenericPriorityQueue.cs.meta │ │ │ ├── GenericPriorityQueueNode.cs │ │ │ ├── GenericPriorityQueueNode.cs.meta │ │ │ ├── IFixedSizePriorityQueue.cs │ │ │ ├── IFixedSizePriorityQueue.cs.meta │ │ │ ├── IPriorityQueue.cs │ │ │ ├── IPriorityQueue.cs.meta │ │ │ ├── SimplePriorityQueue.cs │ │ │ ├── SimplePriorityQueue.cs.meta │ │ │ ├── StablePriorityQueue.cs │ │ │ ├── StablePriorityQueue.cs.meta │ │ │ ├── StablePriorityQueueNode.cs │ │ │ └── StablePriorityQueueNode.cs.meta │ ├── Materials.meta │ ├── Materials │ │ ├── Arrow.mat │ │ ├── Arrow.mat.meta │ │ ├── Node.mat │ │ ├── Node.mat.meta │ │ ├── TransparentColor.mat │ │ ├── TransparentColor.mat.meta │ │ ├── TransparentTexColor.mat │ │ ├── TransparentTexColor.mat.meta │ │ ├── UnlitColor.mat │ │ └── UnlitColor.mat.meta │ ├── Plugins.meta │ ├── Plugins │ │ ├── Clipper.meta │ │ ├── Clipper │ │ │ ├── ClipperLicense.txt │ │ │ ├── ClipperLicense.txt.meta │ │ │ ├── Pathfinding.ClipperLib.dll │ │ │ └── Pathfinding.ClipperLib.dll.meta │ │ ├── Poly2Tri.meta │ │ └── Poly2Tri │ │ │ ├── Pathfinding.Poly2Tri.dll │ │ │ ├── Pathfinding.Poly2Tri.dll.meta │ │ │ ├── Poly2TriLicense.txt │ │ │ └── Poly2TriLicense.txt.meta │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── AbstractNode.prefab │ │ ├── AbstractNode.prefab.meta │ │ ├── Cluster.prefab │ │ ├── Cluster.prefab.meta │ │ ├── ConcreteNode.prefab │ │ ├── ConcreteNode.prefab.meta │ │ ├── Edge.prefab │ │ ├── Edge.prefab.meta │ │ ├── FlowFieldNode.prefab │ │ ├── FlowFieldNode.prefab.meta │ │ ├── Node.prefab │ │ ├── Node.prefab.meta │ │ ├── SearchNode.prefab │ │ └── SearchNode.prefab.meta │ ├── Scenes.meta │ ├── Scenes │ │ ├── CircleVisibilityGraph.unity │ │ ├── CircleVisibilityGraph.unity.meta │ │ ├── FlowField.unity │ │ ├── FlowField.unity.meta │ │ ├── HPA.unity │ │ ├── HPA.unity.meta │ │ ├── Navmesh.unity │ │ ├── Navmesh.unity.meta │ │ ├── Pathfinding.unity │ │ ├── Pathfinding.unity.meta │ │ ├── VisibilityGraph.unity │ │ └── VisibilityGraph.unity.meta │ ├── Scripts.meta │ ├── Scripts │ │ ├── AStar.meta │ │ ├── AStar │ │ │ ├── AStar.cs │ │ │ ├── AStar.cs.meta │ │ │ ├── AStar_GoalBounding.cs │ │ │ ├── AStar_GoalBounding.cs.meta │ │ │ ├── BestFirstSearch.cs │ │ │ ├── BestFirstSearch.cs.meta │ │ │ ├── BreadthFirstSearch.cs │ │ │ ├── BreadthFirstSearch.cs.meta │ │ │ ├── DijkstraSearch.cs │ │ │ └── DijkstraSearch.cs.meta │ │ ├── Bidirection.meta │ │ ├── Bidirection │ │ │ ├── BiAStar.cs │ │ │ └── BiAStar.cs.meta │ │ ├── Common.meta │ │ ├── Common │ │ │ ├── BaseGrid.cs │ │ │ ├── BaseGrid.cs.meta │ │ │ ├── BaseNode.cs │ │ │ ├── BaseNode.cs.meta │ │ │ ├── BaseSearchAlgo.cs │ │ │ ├── BaseSearchAlgo.cs.meta │ │ │ ├── CommonDefine.cs │ │ │ ├── CommonDefine.cs.meta │ │ │ ├── GraphAStar.cs │ │ │ ├── GraphAStar.cs.meta │ │ │ ├── GraphNode.cs │ │ │ ├── GraphNode.cs.meta │ │ │ ├── Heuristic.cs │ │ │ ├── Heuristic.cs.meta │ │ │ ├── SearchGrid.cs │ │ │ ├── SearchGrid.cs.meta │ │ │ ├── SearchNode.cs │ │ │ └── SearchNode.cs.meta │ │ ├── FlowField.meta │ │ ├── FlowField │ │ │ ├── FlowField.cs │ │ │ ├── FlowField.cs.meta │ │ │ ├── FlowFieldNode.cs │ │ │ └── FlowFieldNode.cs.meta │ │ ├── Hierarchy.meta │ │ ├── Hierarchy │ │ │ ├── HAAStar.meta │ │ │ ├── HAAStar │ │ │ │ ├── AnnotatedAStar.cs │ │ │ │ └── AnnotatedAStar.cs.meta │ │ │ ├── HPAStar.meta │ │ │ └── HPAStar │ │ │ │ ├── Demo.meta │ │ │ │ ├── Demo │ │ │ │ ├── HPADemo.cs │ │ │ │ └── HPADemo.cs.meta │ │ │ │ ├── Edge.meta │ │ │ │ ├── Edge │ │ │ │ ├── AbstractEdge.cs │ │ │ │ ├── AbstractEdge.cs.meta │ │ │ │ ├── IEdge.cs │ │ │ │ └── IEdge.cs.meta │ │ │ │ ├── Element.meta │ │ │ │ ├── Element │ │ │ │ ├── AbstractNode.cs │ │ │ │ ├── AbstractNode.cs.meta │ │ │ │ ├── Cluster.cs │ │ │ │ ├── Cluster.cs.meta │ │ │ │ ├── ConcreteNode.cs │ │ │ │ ├── ConcreteNode.cs.meta │ │ │ │ ├── Entrance.cs │ │ │ │ ├── Entrance.cs.meta │ │ │ │ ├── EntrancePoint.cs │ │ │ │ ├── EntrancePoint.cs.meta │ │ │ │ ├── INode.cs │ │ │ │ └── INode.cs.meta │ │ │ │ ├── HierarchicalMapFactory.cs │ │ │ │ ├── HierarchicalMapFactory.cs.meta │ │ │ │ ├── Map.meta │ │ │ │ ├── Map │ │ │ │ ├── AbstractGraph.cs │ │ │ │ ├── AbstractGraph.cs.meta │ │ │ │ ├── AbstractMap.cs │ │ │ │ ├── AbstractMap.cs.meta │ │ │ │ ├── ConcreteMap.cs │ │ │ │ ├── ConcreteMap.cs.meta │ │ │ │ ├── HierarchicalMap.cs │ │ │ │ ├── HierarchicalMap.cs.meta │ │ │ │ ├── IMap.cs │ │ │ │ └── IMap.cs.meta │ │ │ │ ├── Search.meta │ │ │ │ └── Search │ │ │ │ ├── HierarchicalSearch.cs │ │ │ │ ├── HierarchicalSearch.cs.meta │ │ │ │ ├── Path.cs │ │ │ │ ├── Path.cs.meta │ │ │ │ ├── PathPlanner.cs │ │ │ │ └── PathPlanner.cs.meta │ │ ├── IDAStar.meta │ │ ├── IDAStar │ │ │ ├── IDAStar.cs │ │ │ └── IDAStar.cs.meta │ │ ├── Incremental.meta │ │ ├── Incremental │ │ │ ├── AdaptiveAStar.meta │ │ │ ├── AdaptiveAStar │ │ │ │ ├── Path_AAStar.cs │ │ │ │ ├── Path_AAStar.cs.meta │ │ │ │ ├── Tree_AAStar.cs │ │ │ │ └── Tree_AAStar.cs.meta │ │ │ ├── DStar.meta │ │ │ ├── DStar │ │ │ │ ├── BaseDStar.cs │ │ │ │ ├── BaseDStar.cs.meta │ │ │ │ ├── DStar.cs │ │ │ │ ├── DStar.cs.meta │ │ │ │ ├── FocussedDStar.cs │ │ │ │ └── FocussedDStar.cs.meta │ │ │ ├── DStarLite.cs │ │ │ ├── DStarLite.cs.meta │ │ │ ├── LPAStar.meta │ │ │ ├── LPAStar │ │ │ │ ├── LPAKey.cs │ │ │ │ ├── LPAKey.cs.meta │ │ │ │ ├── LPAStar.cs │ │ │ │ ├── LPAStar.cs.meta │ │ │ │ ├── LPAStar_Optimized.cs │ │ │ │ └── LPAStar_Optimized.cs.meta │ │ │ ├── Moving Target.meta │ │ │ └── Moving Target │ │ │ │ ├── GAAStar.cs │ │ │ │ ├── GAAStar.cs.meta │ │ │ │ ├── GFRAStar.cs │ │ │ │ ├── GFRAStar.cs.meta │ │ │ │ ├── MT_DStarLite.cs │ │ │ │ └── MT_DStarLite.cs.meta │ │ ├── JPS.meta │ │ ├── JPS │ │ │ ├── JPSPlus.cs │ │ │ ├── JPSPlus.cs.meta │ │ │ ├── JumpPointSearch.cs │ │ │ └── JumpPointSearch.cs.meta │ │ ├── Navmesh.meta │ │ ├── Navmesh │ │ │ ├── NavmeshDemo.cs │ │ │ ├── NavmeshDemo.cs.meta │ │ │ ├── NavmeshGenerator.cs │ │ │ └── NavmeshGenerator.cs.meta │ │ ├── ThetaStar.meta │ │ ├── ThetaStar │ │ │ ├── LazyThetaStar.cs │ │ │ ├── LazyThetaStar.cs.meta │ │ │ ├── ThetaStar.cs │ │ │ └── ThetaStar.cs.meta │ │ ├── Utils.meta │ │ ├── Utils │ │ │ ├── GraphicsTool.cs │ │ │ ├── GraphicsTool.cs.meta │ │ │ ├── Utils.cs │ │ │ └── Utils.cs.meta │ │ ├── VisibilityGraph.meta │ │ └── VisibilityGraph │ │ │ ├── CircleObstacles.meta │ │ │ ├── CircleObstacles │ │ │ ├── CircleGraphAStar.cs │ │ │ ├── CircleGraphAStar.cs.meta │ │ │ ├── CircleGraphNode.cs │ │ │ ├── CircleGraphNode.cs.meta │ │ │ ├── CircleVisibilityGraphDemo.cs │ │ │ ├── CircleVisibilityGraphDemo.cs.meta │ │ │ ├── CircleVisibilityGraphGenerator.cs │ │ │ └── CircleVisibilityGraphGenerator.cs.meta │ │ │ ├── VisibilityGraphDemo.cs │ │ │ ├── VisibilityGraphDemo.cs.meta │ │ │ ├── VisibilityGraphGenerator.cs │ │ │ └── VisibilityGraphGenerator.cs.meta │ ├── Shaders.meta │ ├── Shaders │ │ ├── TransparentColor.shader │ │ └── TransparentColor.shader.meta │ ├── Textures.meta │ └── Textures │ │ ├── Rect.png │ │ └── Rect.png.meta ├── Packages │ └── manifest.json └── ProjectSettings │ ├── AudioManager.asset │ ├── ClusterInputManager.asset │ ├── DynamicsManager.asset │ ├── EditorBuildSettings.asset │ ├── EditorSettings.asset │ ├── GraphicsSettings.asset │ ├── InputManager.asset │ ├── NavMeshAreas.asset │ ├── Physics2DSettings.asset │ ├── PresetManager.asset │ ├── ProjectSettings.asset │ ├── ProjectVersion.txt │ ├── QualitySettings.asset │ ├── TagManager.asset │ ├── TimeManager.asset │ ├── UnityConnectSettings.asset │ ├── VFXManager.asset │ └── XRSettings.asset └── README.md /Project/.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Mm]emoryCaptures/ 12 | 13 | # Asset meta data should only be ignored when the corresponding asset is also ignored 14 | !/[Aa]ssets/**/*.meta 15 | 16 | # Uncomment this line if you wish to ignore the asset store tools plugin 17 | # /[Aa]ssets/AssetStoreTools* 18 | 19 | # Autogenerated Jetbrains Rider plugin 20 | [Aa]ssets/Plugins/Editor/JetBrains* 21 | 22 | # Visual Studio cache directory 23 | .vs/ 24 | 25 | # Gradle cache directory 26 | .gradle/ 27 | 28 | # Autogenerated VS/MD/Consulo solution and project files 29 | ExportedObj/ 30 | .consulo/ 31 | *.csproj 32 | *.unityproj 33 | *.sln 34 | *.suo 35 | *.tmp 36 | *.user 37 | *.userprefs 38 | *.pidb 39 | *.booproj 40 | *.svd 41 | *.pdb 42 | *.mdb 43 | *.opendb 44 | *.VC.db 45 | 46 | # Unity3D generated meta files 47 | *.pidb.meta 48 | *.pdb.meta 49 | *.mdb.meta 50 | 51 | # Unity3D generated file on crash reports 52 | sysinfo.txt 53 | 54 | # Builds 55 | *.apk 56 | *.unitypackage 57 | 58 | # Crashlytics generated file 59 | crashlytics-build.properties 60 | 61 | -------------------------------------------------------------------------------- /Project/Assets/3rd.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 23b03bae4b7c3e64a92e19ae9005bc95 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad393919aec08e847839cec44daf860b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/FastPriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7e9fe637aaf2874f8fe7176dbdb7ea3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/FastPriorityQueueNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Priority_Queue 4 | { 5 | public class FastPriorityQueueNode 6 | { 7 | /// 8 | /// The Priority to insert this node at. Must be set BEFORE adding a node to the queue (ideally just once, in the node's constructor). 9 | /// Should not be manually edited once the node has been enqueued - use queue.UpdatePriority() instead 10 | /// 11 | public float Priority { get; protected internal set; } 12 | 13 | /// 14 | /// Represents the current position in the queue 15 | /// 16 | public int QueueIndex { get; internal set; } 17 | 18 | #if DEBUG 19 | /// 20 | /// The queue this node is tied to. Used only for debug builds. 21 | /// 22 | public object Queue { get; internal set; } 23 | #endif 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/FastPriorityQueueNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 607d6dca174af2c438e5ed1ad993385f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/GenericPriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b32ee8d06e1bead4e9c0bd3d36620ef0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/GenericPriorityQueueNode.cs: -------------------------------------------------------------------------------- 1 | namespace Priority_Queue 2 | { 3 | public class GenericPriorityQueueNode 4 | { 5 | /// 6 | /// The Priority to insert this node at. Must be set BEFORE adding a node to the queue (ideally just once, in the node's constructor). 7 | /// Should not be manually edited once the node has been enqueued - use queue.UpdatePriority() instead 8 | /// 9 | public TPriority Priority { get; protected internal set; } 10 | 11 | /// 12 | /// Represents the current position in the queue 13 | /// 14 | public int QueueIndex { get; internal set; } 15 | 16 | /// 17 | /// Represents the order the node was inserted in 18 | /// 19 | public long InsertionIndex { get; internal set; } 20 | 21 | 22 | #if DEBUG 23 | /// 24 | /// The queue this node is tied to. Used only for debug builds. 25 | /// 26 | public object Queue { get; internal set; } 27 | #endif 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/GenericPriorityQueueNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6dffffb2efe0d4b4082d9a5d5ee6fa9c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/IFixedSizePriorityQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Priority_Queue 6 | { 7 | /// 8 | /// A helper-interface only needed to make writing unit tests a bit easier (hence the 'internal' access modifier) 9 | /// 10 | internal interface IFixedSizePriorityQueue : IPriorityQueue 11 | where TPriority : IComparable 12 | { 13 | /// 14 | /// Resize the queue so it can accept more nodes. All currently enqueued nodes are remain. 15 | /// Attempting to decrease the queue size to a size too small to hold the existing nodes results in undefined behavior 16 | /// 17 | void Resize(int maxNodes); 18 | 19 | /// 20 | /// Returns the maximum number of items that can be enqueued at once in this queue. Once you hit this number (ie. once Count == MaxSize), 21 | /// attempting to enqueue another item will cause undefined behavior. 22 | /// 23 | int MaxSize { get; } 24 | 25 | /// 26 | /// By default, nodes that have been previously added to one queue cannot be added to another queue. 27 | /// If you need to do this, please call originalQueue.ResetNode(node) before attempting to add it in the new queue 28 | /// 29 | void ResetNode(TItem node); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/IFixedSizePriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eba1c5a45e8225441abfd6658f4b0582 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/IPriorityQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Priority_Queue 5 | { 6 | /// 7 | /// The IPriorityQueue interface. This is mainly here for purists, and in case I decide to add more implementations later. 8 | /// For speed purposes, it is actually recommended that you *don't* access the priority queue through this interface, since the JIT can 9 | /// (theoretically?) optimize method calls from concrete-types slightly better. 10 | /// 11 | public interface IPriorityQueue : IEnumerable 12 | where TPriority : IComparable 13 | { 14 | /// 15 | /// Enqueue a node to the priority queue. Lower values are placed in front. Ties are broken by first-in-first-out. 16 | /// See implementation for how duplicates are handled. 17 | /// 18 | void Enqueue(TItem node, TPriority priority); 19 | 20 | /// 21 | /// Removes the head of the queue (node with minimum priority; ties are broken by order of insertion), and returns it. 22 | /// 23 | TItem Dequeue(); 24 | 25 | /// 26 | /// Removes every node from the queue. 27 | /// 28 | void Clear(); 29 | 30 | /// 31 | /// Returns whether the given node is in the queue. 32 | /// 33 | bool Contains(TItem node); 34 | 35 | /// 36 | /// Removes a node from the queue. The node does not need to be the head of the queue. 37 | /// 38 | void Remove(TItem node); 39 | 40 | /// 41 | /// Call this method to change the priority of a node. 42 | /// 43 | void UpdatePriority(TItem node, TPriority priority); 44 | 45 | /// 46 | /// Returns the head of the queue, without removing it (use Dequeue() for that). 47 | /// 48 | TItem First { get; } 49 | 50 | /// 51 | /// Returns the number of nodes in the queue. 52 | /// 53 | int Count { get; } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/IPriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 05d7d689abb81714c931704f35fc5ae8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/SimplePriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b93f150b32066bb42b1fee9432113378 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/StablePriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d399a5d550fc8ae4786eb0722544ccd3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/StablePriorityQueueNode.cs: -------------------------------------------------------------------------------- 1 | namespace Priority_Queue 2 | { 3 | public class StablePriorityQueueNode : FastPriorityQueueNode 4 | { 5 | /// 6 | /// Represents the order the node was inserted in 7 | /// 8 | public long InsertionIndex { get; internal set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Project/Assets/3rd/PriorityQueue/StablePriorityQueueNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 61f2a1d0a8d6bce4abc1f4a13440db34 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4db5d62c50b0dcb42802c93204ba68d6 3 | folderAsset: yes 4 | timeCreated: 1517457432 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Materials/Arrow.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Arrow 11 | m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 2800000, guid: 86abf8d6120d7ec42b1d0b53afa62ada, type: 3} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 1, g: 1, b: 1, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Project/Assets/Materials/Arrow.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a64191a940141248ab7c754da894040 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Materials/Node.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Node 11 | m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 1, g: 1, b: 1, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Project/Assets/Materials/Node.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2c54c639668cd2140bdb5e52de446300 3 | timeCreated: 1517457439 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 2100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Materials/TransparentColor.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: TransparentColor 11 | m_Shader: {fileID: 4800000, guid: 5e05940326c3a514b997f7d02516a058, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0, g: 0.6310754, b: 1, a: 0.5372549} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Project/Assets/Materials/TransparentColor.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e248cce551d726441babf7f117c4aa00 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Materials/TransparentTexColor.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: TransparentTexColor 11 | m_Shader: {fileID: 4800000, guid: 5e05940326c3a514b997f7d02516a058, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 2800000, guid: 3216cead1acc3c847b73eb08085b7dc7, type: 3} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 1, g: 1, b: 1, a: 0.5372549} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Project/Assets/Materials/TransparentTexColor.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0cbcf79488a9bf4dab270d4942d8883 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Materials/UnlitColor.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: UnlitColor 11 | m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0, g: 0, b: 0, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Project/Assets/Materials/UnlitColor.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a7b2a217e5e41f4aa174427a5734569 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a70e36e4abbeb648a5dc34c678fd491 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Plugins/Clipper.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 288c2545dfd07b847b75eb2dd8a322f2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Plugins/Clipper/ClipperLicense.txt: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Project/Assets/Plugins/Clipper/ClipperLicense.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 08c5ae29106b34503b70cdb469fece59 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Project/Assets/Plugins/Clipper/Pathfinding.ClipperLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KaimaChen/Pathfinding/ee1010d13f7b2a87f4fe2806de660cb5e81f0fd1/Project/Assets/Plugins/Clipper/Pathfinding.ClipperLib.dll -------------------------------------------------------------------------------- /Project/Assets/Plugins/Clipper/Pathfinding.ClipperLib.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 19035d002594b44d09f9db8816a03092 3 | PluginImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | isPreloaded: 0 8 | platformData: 9 | Any: 10 | enabled: 1 11 | settings: {} 12 | Editor: 13 | enabled: 0 14 | settings: 15 | DefaultValueInitialized: true 16 | userData: 17 | assetBundleName: 18 | assetBundleVariant: 19 | -------------------------------------------------------------------------------- /Project/Assets/Plugins/Poly2Tri.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43ee921b3a3b8c74ba90f0e66f45c75c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Plugins/Poly2Tri/Pathfinding.Poly2Tri.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KaimaChen/Pathfinding/ee1010d13f7b2a87f4fe2806de660cb5e81f0fd1/Project/Assets/Plugins/Poly2Tri/Pathfinding.Poly2Tri.dll -------------------------------------------------------------------------------- /Project/Assets/Plugins/Poly2Tri/Pathfinding.Poly2Tri.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30b798b6b35e94042b75435e2c52e2eb 3 | PluginImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | isPreloaded: 0 8 | platformData: 9 | Any: 10 | enabled: 1 11 | settings: {} 12 | Editor: 13 | enabled: 0 14 | settings: 15 | DefaultValueInitialized: true 16 | userData: 17 | assetBundleName: 18 | assetBundleVariant: 19 | -------------------------------------------------------------------------------- /Project/Assets/Plugins/Poly2Tri/Poly2TriLicense.txt: -------------------------------------------------------------------------------- 1 | The BSD 3-Clause License 2 | The following is a BSD 3-Clause ("BSD New" or "BSD Simplified") license template. To generate your own license, change the values of OWNER, ORGANIZATION and YEAR from their original values as given here, and substitute your own. 3 | 4 | Note: You may omit clause 3 and still be OSD-conformant. Despite its colloquial name "BSD New", this is not the newest version of the BSD license; it was followed by the even newer BSD-2-Clause version, sometimes known as the "Simplified BSD License". On January 9th, 2008 the OSI Board approved BSD-2-Clause, which is used by FreeBSD and others. It omits the final "no-endorsement" clause and is thus roughly equivalent to the MIT License. 5 | 6 | Historical Background: The original license used on BSD Unix had four clauses. The advertising clause (the third of four clauses) required you to acknowledge use of U.C. Berkeley code in your advertising of any product using that code. It was officially rescinded by the Director of the Office of Technology Licensing of the University of California on July 22nd, 1999. He states that clause 3 is "hereby deleted in its entirety." The four clause license has not been approved by OSI. The license below does not contain the advertising clause. 7 | 8 | This prelude is not part of the license. 9 | 10 | = Regents of the University of California 11 | = University of California, Berkeley 12 | = 1998 13 | 14 | In the original BSD license, both occurrences of the phrase "COPYRIGHT HOLDERS AND CONTRIBUTORS" in the disclaimer read "REGENTS AND CONTRIBUTORS". 15 | 16 | Here is the license template: 17 | 18 | Copyright (c) , 19 | All rights reserved. 20 | 21 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 22 | 23 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 24 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 25 | Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Project/Assets/Plugins/Poly2Tri/Poly2TriLicense.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8de03443595d54cd8ac8280d34835f5f 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d57b236c09a9f5645b9ab6c5b1bd1ee2 3 | folderAsset: yes 4 | timeCreated: 1517457549 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/AbstractNode.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6681d9f3eac6a541a3628e63ff188f5 3 | timeCreated: 1517457562 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 100100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/Cluster.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &3928776573106042551 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 3932562142223320379} 12 | - component: {fileID: 3960265475974796329} 13 | - component: {fileID: 3951741970857681845} 14 | - component: {fileID: 658283669350576818} 15 | m_Layer: 0 16 | m_Name: Cluster 17 | m_TagString: Untagged 18 | m_Icon: {fileID: 0} 19 | m_NavMeshLayer: 0 20 | m_StaticEditorFlags: 0 21 | m_IsActive: 1 22 | --- !u!4 &3932562142223320379 23 | Transform: 24 | m_ObjectHideFlags: 0 25 | m_CorrespondingSourceObject: {fileID: 0} 26 | m_PrefabInstance: {fileID: 0} 27 | m_PrefabAsset: {fileID: 0} 28 | m_GameObject: {fileID: 3928776573106042551} 29 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 30 | m_LocalPosition: {x: 0, y: 0, z: 0} 31 | m_LocalScale: {x: 0.95, y: 0.95, z: 0.95} 32 | m_Children: [] 33 | m_Father: {fileID: 0} 34 | m_RootOrder: 0 35 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 36 | --- !u!33 &3960265475974796329 37 | MeshFilter: 38 | m_ObjectHideFlags: 0 39 | m_CorrespondingSourceObject: {fileID: 0} 40 | m_PrefabInstance: {fileID: 0} 41 | m_PrefabAsset: {fileID: 0} 42 | m_GameObject: {fileID: 3928776573106042551} 43 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 44 | --- !u!23 &3951741970857681845 45 | MeshRenderer: 46 | m_ObjectHideFlags: 0 47 | m_CorrespondingSourceObject: {fileID: 0} 48 | m_PrefabInstance: {fileID: 0} 49 | m_PrefabAsset: {fileID: 0} 50 | m_GameObject: {fileID: 3928776573106042551} 51 | m_Enabled: 1 52 | m_CastShadows: 1 53 | m_ReceiveShadows: 1 54 | m_DynamicOccludee: 1 55 | m_MotionVectors: 1 56 | m_LightProbeUsage: 1 57 | m_ReflectionProbeUsage: 1 58 | m_RayTracingMode: 2 59 | m_RenderingLayerMask: 1 60 | m_RendererPriority: 0 61 | m_Materials: 62 | - {fileID: 2100000, guid: e0cbcf79488a9bf4dab270d4942d8883, type: 2} 63 | m_StaticBatchInfo: 64 | firstSubMesh: 0 65 | subMeshCount: 0 66 | m_StaticBatchRoot: {fileID: 0} 67 | m_ProbeAnchor: {fileID: 0} 68 | m_LightProbeVolumeOverride: {fileID: 0} 69 | m_ScaleInLightmap: 1 70 | m_ReceiveGI: 1 71 | m_PreserveUVs: 1 72 | m_IgnoreNormalsForChartDetection: 0 73 | m_ImportantGI: 0 74 | m_StitchLightmapSeams: 1 75 | m_SelectedEditorRenderState: 3 76 | m_MinimumChartSize: 4 77 | m_AutoUVMaxDistance: 0.5 78 | m_AutoUVMaxAngle: 89 79 | m_LightmapParameters: {fileID: 0} 80 | m_SortingLayerID: 0 81 | m_SortingLayer: 0 82 | m_SortingOrder: 0 83 | --- !u!114 &658283669350576818 84 | MonoBehaviour: 85 | m_ObjectHideFlags: 0 86 | m_CorrespondingSourceObject: {fileID: 0} 87 | m_PrefabInstance: {fileID: 0} 88 | m_PrefabAsset: {fileID: 0} 89 | m_GameObject: {fileID: 3928776573106042551} 90 | m_Enabled: 1 91 | m_EditorHideFlags: 0 92 | m_Script: {fileID: 11500000, guid: 785f2a4b2dab57a4eac55e98c7263875, type: 3} 93 | m_Name: 94 | m_EditorClassIdentifier: 95 | m_id: 0 96 | m_pos: {x: 0, y: 0} 97 | m_area: 98 | x: 0 99 | y: 0 100 | width: 0 101 | height: 0 102 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/Cluster.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33709336e1bcfe84ab4ea9a658288f68 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/ConcreteNode.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &3436412753754515511 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 3433434127354469307} 12 | - component: {fileID: 3441020856481663657} 13 | - component: {fileID: 3409488883533585435} 14 | - component: {fileID: 3450371021235633461} 15 | - component: {fileID: -4175244298562268843} 16 | m_Layer: 0 17 | m_Name: ConcreteNode 18 | m_TagString: Untagged 19 | m_Icon: {fileID: 0} 20 | m_NavMeshLayer: 0 21 | m_StaticEditorFlags: 0 22 | m_IsActive: 1 23 | --- !u!4 &3433434127354469307 24 | Transform: 25 | m_ObjectHideFlags: 0 26 | m_CorrespondingSourceObject: {fileID: 0} 27 | m_PrefabInstance: {fileID: 0} 28 | m_PrefabAsset: {fileID: 0} 29 | m_GameObject: {fileID: 3436412753754515511} 30 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 31 | m_LocalPosition: {x: 0, y: 0, z: 0} 32 | m_LocalScale: {x: 0.95, y: 0.95, z: 0.95} 33 | m_Children: [] 34 | m_Father: {fileID: 0} 35 | m_RootOrder: 0 36 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 37 | --- !u!33 &3441020856481663657 38 | MeshFilter: 39 | m_ObjectHideFlags: 0 40 | m_CorrespondingSourceObject: {fileID: 0} 41 | m_PrefabInstance: {fileID: 0} 42 | m_PrefabAsset: {fileID: 0} 43 | m_GameObject: {fileID: 3436412753754515511} 44 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 45 | --- !u!64 &3409488883533585435 46 | MeshCollider: 47 | m_ObjectHideFlags: 0 48 | m_CorrespondingSourceObject: {fileID: 0} 49 | m_PrefabInstance: {fileID: 0} 50 | m_PrefabAsset: {fileID: 0} 51 | m_GameObject: {fileID: 3436412753754515511} 52 | m_Material: {fileID: 0} 53 | m_IsTrigger: 0 54 | m_Enabled: 1 55 | serializedVersion: 3 56 | m_Convex: 0 57 | m_CookingOptions: 30 58 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 59 | --- !u!23 &3450371021235633461 60 | MeshRenderer: 61 | m_ObjectHideFlags: 0 62 | m_CorrespondingSourceObject: {fileID: 0} 63 | m_PrefabInstance: {fileID: 0} 64 | m_PrefabAsset: {fileID: 0} 65 | m_GameObject: {fileID: 3436412753754515511} 66 | m_Enabled: 1 67 | m_CastShadows: 1 68 | m_ReceiveShadows: 1 69 | m_DynamicOccludee: 1 70 | m_MotionVectors: 1 71 | m_LightProbeUsage: 1 72 | m_ReflectionProbeUsage: 1 73 | m_RayTracingMode: 2 74 | m_RenderingLayerMask: 1 75 | m_RendererPriority: 0 76 | m_Materials: 77 | - {fileID: 2100000, guid: 2c54c639668cd2140bdb5e52de446300, type: 2} 78 | m_StaticBatchInfo: 79 | firstSubMesh: 0 80 | subMeshCount: 0 81 | m_StaticBatchRoot: {fileID: 0} 82 | m_ProbeAnchor: {fileID: 0} 83 | m_LightProbeVolumeOverride: {fileID: 0} 84 | m_ScaleInLightmap: 1 85 | m_ReceiveGI: 1 86 | m_PreserveUVs: 1 87 | m_IgnoreNormalsForChartDetection: 0 88 | m_ImportantGI: 0 89 | m_StitchLightmapSeams: 1 90 | m_SelectedEditorRenderState: 3 91 | m_MinimumChartSize: 4 92 | m_AutoUVMaxDistance: 0.5 93 | m_AutoUVMaxAngle: 89 94 | m_LightmapParameters: {fileID: 0} 95 | m_SortingLayerID: 0 96 | m_SortingLayer: 0 97 | m_SortingOrder: 0 98 | --- !u!114 &-4175244298562268843 99 | MonoBehaviour: 100 | m_ObjectHideFlags: 0 101 | m_CorrespondingSourceObject: {fileID: 0} 102 | m_PrefabInstance: {fileID: 0} 103 | m_PrefabAsset: {fileID: 0} 104 | m_GameObject: {fileID: 3436412753754515511} 105 | m_Enabled: 1 106 | m_EditorHideFlags: 0 107 | m_Script: {fileID: 11500000, guid: a16432d64be796040b8752fb5a2c0b2a, type: 3} 108 | m_Name: 109 | m_EditorClassIdentifier: 110 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/ConcreteNode.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 61ba71cb7da5eba4b9e1c97e04909333 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/Edge.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &7561475511319441073 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 7688152685152684364} 12 | - component: {fileID: 2849580201488149374} 13 | - component: {fileID: 4492989241654025644} 14 | m_Layer: 0 15 | m_Name: Edge 16 | m_TagString: Untagged 17 | m_Icon: {fileID: 0} 18 | m_NavMeshLayer: 0 19 | m_StaticEditorFlags: 0 20 | m_IsActive: 1 21 | --- !u!4 &7688152685152684364 22 | Transform: 23 | m_ObjectHideFlags: 0 24 | m_CorrespondingSourceObject: {fileID: 0} 25 | m_PrefabInstance: {fileID: 0} 26 | m_PrefabAsset: {fileID: 0} 27 | m_GameObject: {fileID: 7561475511319441073} 28 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 29 | m_LocalPosition: {x: 0, y: 0, z: -2} 30 | m_LocalScale: {x: 1, y: 1, z: 1} 31 | m_Children: [] 32 | m_Father: {fileID: 0} 33 | m_RootOrder: 0 34 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 35 | --- !u!120 &2849580201488149374 36 | LineRenderer: 37 | m_ObjectHideFlags: 0 38 | m_CorrespondingSourceObject: {fileID: 0} 39 | m_PrefabInstance: {fileID: 0} 40 | m_PrefabAsset: {fileID: 0} 41 | m_GameObject: {fileID: 7561475511319441073} 42 | m_Enabled: 1 43 | m_CastShadows: 1 44 | m_ReceiveShadows: 1 45 | m_DynamicOccludee: 1 46 | m_MotionVectors: 0 47 | m_LightProbeUsage: 0 48 | m_ReflectionProbeUsage: 0 49 | m_RayTracingMode: 0 50 | m_RenderingLayerMask: 1 51 | m_RendererPriority: 0 52 | m_Materials: 53 | - {fileID: 2100000, guid: 1a7b2a217e5e41f4aa174427a5734569, type: 2} 54 | m_StaticBatchInfo: 55 | firstSubMesh: 0 56 | subMeshCount: 0 57 | m_StaticBatchRoot: {fileID: 0} 58 | m_ProbeAnchor: {fileID: 0} 59 | m_LightProbeVolumeOverride: {fileID: 0} 60 | m_ScaleInLightmap: 1 61 | m_ReceiveGI: 1 62 | m_PreserveUVs: 0 63 | m_IgnoreNormalsForChartDetection: 0 64 | m_ImportantGI: 0 65 | m_StitchLightmapSeams: 1 66 | m_SelectedEditorRenderState: 3 67 | m_MinimumChartSize: 4 68 | m_AutoUVMaxDistance: 0.5 69 | m_AutoUVMaxAngle: 89 70 | m_LightmapParameters: {fileID: 0} 71 | m_SortingLayerID: 0 72 | m_SortingLayer: 0 73 | m_SortingOrder: 0 74 | m_Positions: 75 | - {x: 0, y: 0, z: 0} 76 | - {x: 0, y: 0, z: 1} 77 | m_Parameters: 78 | serializedVersion: 3 79 | widthMultiplier: 0.15 80 | widthCurve: 81 | serializedVersion: 2 82 | m_Curve: 83 | - serializedVersion: 3 84 | time: 0 85 | value: 1 86 | inSlope: 0 87 | outSlope: 0 88 | tangentMode: 0 89 | weightedMode: 0 90 | inWeight: 0.33333334 91 | outWeight: 0.33333334 92 | m_PreInfinity: 2 93 | m_PostInfinity: 2 94 | m_RotationOrder: 4 95 | colorGradient: 96 | serializedVersion: 2 97 | key0: {r: 1, g: 1, b: 1, a: 1} 98 | key1: {r: 1, g: 1, b: 1, a: 1} 99 | key2: {r: 0, g: 0, b: 0, a: 0} 100 | key3: {r: 0, g: 0, b: 0, a: 0} 101 | key4: {r: 0, g: 0, b: 0, a: 0} 102 | key5: {r: 0, g: 0, b: 0, a: 0} 103 | key6: {r: 0, g: 0, b: 0, a: 0} 104 | key7: {r: 0, g: 0, b: 0, a: 0} 105 | ctime0: 0 106 | ctime1: 65535 107 | ctime2: 0 108 | ctime3: 0 109 | ctime4: 0 110 | ctime5: 0 111 | ctime6: 0 112 | ctime7: 0 113 | atime0: 0 114 | atime1: 65535 115 | atime2: 0 116 | atime3: 0 117 | atime4: 0 118 | atime5: 0 119 | atime6: 0 120 | atime7: 0 121 | m_Mode: 0 122 | m_NumColorKeys: 2 123 | m_NumAlphaKeys: 2 124 | numCornerVertices: 0 125 | numCapVertices: 0 126 | alignment: 0 127 | textureMode: 0 128 | shadowBias: 0.5 129 | generateLightingData: 0 130 | m_UseWorldSpace: 0 131 | m_Loop: 0 132 | --- !u!114 &4492989241654025644 133 | MonoBehaviour: 134 | m_ObjectHideFlags: 0 135 | m_CorrespondingSourceObject: {fileID: 0} 136 | m_PrefabInstance: {fileID: 0} 137 | m_PrefabAsset: {fileID: 0} 138 | m_GameObject: {fileID: 7561475511319441073} 139 | m_Enabled: 1 140 | m_EditorHideFlags: 0 141 | m_Script: {fileID: 11500000, guid: 9358d9f9b8225f5418ad224a83f7089b, type: 3} 142 | m_Name: 143 | m_EditorClassIdentifier: 144 | m_targetNodeId: 0 145 | m_cost: 0 146 | m_level: 0 147 | m_isInterEdge: 0 148 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/Edge.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af7e270a92332764fb038d7267ce89c8 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/FlowFieldNode.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ce25f8c03fe8a854bb2c5ffeca26c0b9 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/Node.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1001 &100100000 4 | Prefab: 5 | m_ObjectHideFlags: 1 6 | serializedVersion: 2 7 | m_Modification: 8 | m_TransformParent: {fileID: 0} 9 | m_Modifications: [] 10 | m_RemovedComponents: [] 11 | m_ParentPrefab: {fileID: 0} 12 | m_RootGameObject: {fileID: 1902866159556996} 13 | m_IsPrefabParent: 1 14 | --- !u!1 &1902866159556996 15 | GameObject: 16 | m_ObjectHideFlags: 0 17 | m_PrefabParentObject: {fileID: 0} 18 | m_PrefabInternal: {fileID: 100100000} 19 | serializedVersion: 5 20 | m_Component: 21 | - component: {fileID: 4600017566083592} 22 | - component: {fileID: 33393989388008218} 23 | - component: {fileID: 64921246382402984} 24 | - component: {fileID: 23779951406419078} 25 | - component: {fileID: 114839097338427770} 26 | m_Layer: 0 27 | m_Name: Node 28 | m_TagString: Untagged 29 | m_Icon: {fileID: 0} 30 | m_NavMeshLayer: 0 31 | m_StaticEditorFlags: 0 32 | m_IsActive: 1 33 | --- !u!4 &4600017566083592 34 | Transform: 35 | m_ObjectHideFlags: 1 36 | m_PrefabParentObject: {fileID: 0} 37 | m_PrefabInternal: {fileID: 100100000} 38 | m_GameObject: {fileID: 1902866159556996} 39 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 40 | m_LocalPosition: {x: 0, y: 0, z: 0} 41 | m_LocalScale: {x: 0.95, y: 0.95, z: 0.95} 42 | m_Children: [] 43 | m_Father: {fileID: 0} 44 | m_RootOrder: 0 45 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 46 | --- !u!23 &23779951406419078 47 | MeshRenderer: 48 | m_ObjectHideFlags: 1 49 | m_PrefabParentObject: {fileID: 0} 50 | m_PrefabInternal: {fileID: 100100000} 51 | m_GameObject: {fileID: 1902866159556996} 52 | m_Enabled: 1 53 | m_CastShadows: 1 54 | m_ReceiveShadows: 1 55 | m_MotionVectors: 1 56 | m_LightProbeUsage: 1 57 | m_ReflectionProbeUsage: 1 58 | m_Materials: 59 | - {fileID: 2100000, guid: 2c54c639668cd2140bdb5e52de446300, type: 2} 60 | m_StaticBatchInfo: 61 | firstSubMesh: 0 62 | subMeshCount: 0 63 | m_StaticBatchRoot: {fileID: 0} 64 | m_ProbeAnchor: {fileID: 0} 65 | m_LightProbeVolumeOverride: {fileID: 0} 66 | m_ScaleInLightmap: 1 67 | m_PreserveUVs: 1 68 | m_IgnoreNormalsForChartDetection: 0 69 | m_ImportantGI: 0 70 | m_SelectedEditorRenderState: 3 71 | m_MinimumChartSize: 4 72 | m_AutoUVMaxDistance: 0.5 73 | m_AutoUVMaxAngle: 89 74 | m_LightmapParameters: {fileID: 0} 75 | m_SortingLayerID: 0 76 | m_SortingLayer: 0 77 | m_SortingOrder: 0 78 | --- !u!33 &33393989388008218 79 | MeshFilter: 80 | m_ObjectHideFlags: 1 81 | m_PrefabParentObject: {fileID: 0} 82 | m_PrefabInternal: {fileID: 100100000} 83 | m_GameObject: {fileID: 1902866159556996} 84 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 85 | --- !u!64 &64921246382402984 86 | MeshCollider: 87 | m_ObjectHideFlags: 1 88 | m_PrefabParentObject: {fileID: 0} 89 | m_PrefabInternal: {fileID: 100100000} 90 | m_GameObject: {fileID: 1902866159556996} 91 | m_Material: {fileID: 0} 92 | m_IsTrigger: 0 93 | m_Enabled: 1 94 | serializedVersion: 2 95 | m_Convex: 0 96 | m_InflateMesh: 0 97 | m_SkinWidth: 0.01 98 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 99 | --- !u!114 &114839097338427770 100 | MonoBehaviour: 101 | m_ObjectHideFlags: 1 102 | m_PrefabParentObject: {fileID: 0} 103 | m_PrefabInternal: {fileID: 100100000} 104 | m_GameObject: {fileID: 1902866159556996} 105 | m_Enabled: 1 106 | m_EditorHideFlags: 0 107 | m_Script: {fileID: 11500000, guid: 66b79e807e7e83a4fac9c9ed3852dcda, type: 3} 108 | m_Name: 109 | m_EditorClassIdentifier: 110 | nodeType: -1 111 | parent: {fileID: 0} 112 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/Node.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55f8dbac9caf5ca4f84132ebdff559fd 3 | timeCreated: 1517457562 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 100100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Prefabs/SearchNode.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ca41f8e1be07654cb5f54cca148faf8 3 | timeCreated: 1517457562 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 100100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e2c4ec5074e02b14087e444c51b6e99e 3 | folderAsset: yes 4 | timeCreated: 1517219846 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Scenes/CircleVisibilityGraph.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 245dc08493b3cdb43b1149d467e57d49 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Scenes/FlowField.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d7b91830cdc783a4a8bc54a3b9a23dda 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Scenes/HPA.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 335680c8a17eb0e468081075a7b409b5 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Scenes/Navmesh.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 700de0d16e6e0c74da2e2d8f92734bfb 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Scenes/Pathfinding.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34002652c2f6a3944959a687e4a66ba7 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Scenes/VisibilityGraph.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ac4d498e7e674f418309877a1caae51 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Project/Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 666f4e16db9b8914eb4cabace65ca2d4 3 | folderAsset: yes 4 | timeCreated: 1517219842 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d79303d28a74ccd4abd7815a9bbb7380 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/AStar.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using Priority_Queue; 5 | 6 | /// 7 | /// A*寻路 8 | /// 9 | public class AStar : BaseSearchAlgo 10 | { 11 | protected readonly float m_weight = 1; 12 | private readonly SimplePriorityQueue m_open = new SimplePriorityQueue(); 13 | 14 | public AStar(SearchNode start, SearchNode goal, SearchNode[,] nodes, float weight, float showTime) 15 | : base(start, goal, nodes, showTime) 16 | { 17 | m_weight = weight; 18 | } 19 | 20 | public override IEnumerator Process() 21 | { 22 | //离线预处理,这里为了展示方便所以放到Process()里 23 | Preprocess(); 24 | 25 | m_mapStart.G = 0; 26 | 27 | AddToOpenList(m_mapStart); 28 | while (OpenListSize() > 0) 29 | { 30 | Vector2Int curtPos = PopOpenList(); 31 | SearchNode curtNode = GetNode(curtPos); 32 | 33 | SetVertex(curtNode); 34 | 35 | if (curtPos == m_mapGoal.Pos) //找到终点 36 | { 37 | break; 38 | } 39 | else 40 | { 41 | #region show 42 | yield return new WaitForSeconds(m_showTime); //等待一点时间,以便观察 43 | curtNode.SetSearchType(SearchType.Expanded, true); 44 | #endregion 45 | 46 | curtNode.Closed = true; 47 | 48 | List neighbors = GetNeighbors(curtNode); 49 | for (int i = 0; i < neighbors.Count; i++) 50 | { 51 | SearchNode neighbor = neighbors[i]; 52 | if (IsNeighborValid(neighbor)) 53 | { 54 | if (neighbor.Opened == false) 55 | neighbor.SetParent(null, float.MaxValue); 56 | 57 | UpdateVertex(curtNode, neighbor); 58 | } 59 | } 60 | } 61 | } 62 | 63 | //绘制出最终的路径 64 | GeneratePath(); 65 | 66 | yield break; 67 | } 68 | 69 | protected virtual void Preprocess() 70 | { 71 | 72 | } 73 | 74 | protected virtual bool IsNeighborValid(SearchNode neighbor) 75 | { 76 | return neighbor.Closed == false; 77 | } 78 | 79 | protected void GeneratePath() 80 | { 81 | SearchNode lastNode = GetNode(m_mapGoal.Pos); 82 | while (lastNode != null) 83 | { 84 | lastNode.SetSearchType(SearchType.Path, true); 85 | lastNode = lastNode.Parent; 86 | } 87 | } 88 | 89 | protected virtual void UpdateVertex(SearchNode curtNode, SearchNode nextNode) 90 | { 91 | float oldG = nextNode.G; 92 | ComputeCost(curtNode, nextNode); 93 | 94 | if(nextNode.G < oldG) 95 | { 96 | if (nextNode.Opened == false) 97 | AddToOpenList(nextNode); 98 | } 99 | } 100 | 101 | protected virtual void ComputeCost(SearchNode curtNode, SearchNode nextNode) 102 | { 103 | //Path 1 104 | float cost = curtNode.G + c(curtNode, nextNode); 105 | if (cost < nextNode.G) 106 | nextNode.SetParent(curtNode, cost); 107 | } 108 | 109 | protected virtual void SetVertex(SearchNode node) 110 | { 111 | 112 | } 113 | 114 | protected virtual void AddToOpenList(SearchNode node) 115 | { 116 | m_open.Enqueue(node.Pos, node.F(m_weight)); 117 | node.Opened = true; 118 | node.SetSearchType(SearchType.Open, true); 119 | } 120 | 121 | /// 122 | /// 在open list中找成本最低的节点并去掉 123 | /// 124 | protected virtual Vector2Int PopOpenList() 125 | { 126 | return m_open.Dequeue(); 127 | } 128 | 129 | protected virtual int OpenListSize() 130 | { 131 | return m_open.Count; 132 | } 133 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/AStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6922d1b9b4ee8f1409a67ab42df9baa2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/AStar_GoalBounding.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class AStar_GoalBounding : AStar 6 | { 7 | public AStar_GoalBounding(SearchNode start, SearchNode end, SearchNode[,] nodes, float weight, float showTime) 8 | : base(start, end, nodes, weight, showTime) 9 | { 10 | 11 | } 12 | 13 | private void Preprocess() 14 | { 15 | 16 | } 17 | 18 | public override IEnumerator Process() 19 | { 20 | //TODO 21 | return base.Process(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/AStar_GoalBounding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f79c65ac2a548de4884883574062e427 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/BestFirstSearch.cs: -------------------------------------------------------------------------------- 1 | public class BestFirstSearch : AStar 2 | { 3 | public BestFirstSearch(SearchNode start, SearchNode goal, SearchNode[,] nodes, float weight, float showTime) 4 | : base(start, goal, nodes, 100000, showTime) 5 | { } 6 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/BestFirstSearch.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 391d6b874c0782140abf32efd1929e1a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/BreadthFirstSearch.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | /// 5 | /// 宽度优先搜索(泛洪) 6 | /// 7 | public class BreadthFirstSearch : AStar 8 | { 9 | private readonly Queue m_openQueue = new Queue(); 10 | 11 | public BreadthFirstSearch(SearchNode start, SearchNode goal, SearchNode[,] nodes, float weight, float showTime) 12 | : base(start, goal, nodes, weight, showTime) 13 | { } 14 | 15 | protected override void AddToOpenList(SearchNode node) 16 | { 17 | m_openQueue.Enqueue(node.Pos); 18 | node.Opened = true; 19 | node.SetSearchType(SearchType.Open, true); 20 | } 21 | 22 | protected override Vector2Int PopOpenList() 23 | { 24 | return m_openQueue.Dequeue(); 25 | } 26 | 27 | protected override int OpenListSize() 28 | { 29 | return m_openQueue.Count; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/BreadthFirstSearch.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4df4f33ce51ce7348930c934d40898c3 3 | timeCreated: 1517479210 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/DijkstraSearch.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dijkstra's Algorithm 3 | /// 只考虑最接近起点的 4 | /// 5 | public class DijkstraSearch : AStar 6 | { 7 | public DijkstraSearch(SearchNode start, SearchNode goal, SearchNode[,] nodes, float weight, float showTime) 8 | : base(start, goal, nodes, 0, showTime) 9 | { } 10 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/AStar/DijkstraSearch.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 565b53a694cd61c4a83fae2cd09c02ba 3 | timeCreated: 1517538346 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Bidirection.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 988a7f7d043196642aad275b88295a19 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Bidirection/BiAStar.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using Priority_Queue; 5 | 6 | public class BiAStar : AStar 7 | { 8 | private readonly SimplePriorityQueue m_startOpen = new SimplePriorityQueue(); 9 | private readonly SimplePriorityQueue m_endOpen = new SimplePriorityQueue(); 10 | 11 | public BiAStar(SearchNode start, SearchNode goal, SearchNode[,] nodes, float weight, float showTime) 12 | : base(start, goal, nodes, weight, showTime) 13 | { 14 | 15 | } 16 | 17 | public override IEnumerator Process() 18 | { 19 | m_mapStart.G = 0; 20 | AddToOpenList(m_mapStart, true); 21 | 22 | m_mapGoal.G = 0; 23 | AddToOpenList(m_mapGoal, false); 24 | 25 | SearchNode startStopNode = null, endStopNode = null; 26 | 27 | while(m_startOpen.Count > 0 && m_endOpen.Count > 0) 28 | { 29 | //处理start方向 30 | ProcessStart(ref startStopNode, ref endStopNode); 31 | yield return new WaitForSeconds(m_showTime); //等待一点时间,以便观察 32 | if (startStopNode != null && endStopNode != null) 33 | break; 34 | 35 | //处理end方向 36 | ProcessEnd(ref startStopNode, ref endStopNode); 37 | yield return new WaitForSeconds(m_showTime); //等待一点时间,以便观察 38 | if (startStopNode != null && endStopNode != null) 39 | break; 40 | } 41 | 42 | GeneratePath(startStopNode, endStopNode); 43 | 44 | yield break; 45 | } 46 | 47 | private void ProcessStart(ref SearchNode startStopNode, ref SearchNode endStopNode) 48 | { 49 | Vector2Int curtPos = PopOpenList(true); 50 | SearchNode curtNode = GetNode(curtPos); 51 | 52 | #region show 53 | curtNode.SetSearchType(SearchType.Expanded, true); 54 | #endregion 55 | 56 | curtNode.Closed = true; 57 | 58 | List neighbors = GetNeighbors(curtNode); 59 | for (int i = 0; i < neighbors.Count; i++) 60 | { 61 | SearchNode neighbor = neighbors[i]; 62 | if(neighbor.IsEndOpen()) 63 | { 64 | startStopNode = curtNode; 65 | endStopNode = neighbor; 66 | return; 67 | } 68 | 69 | if (neighbor.Closed == false) 70 | { 71 | if (neighbor.IsStartOpen() == false) 72 | neighbor.SetParent(null, float.MaxValue); 73 | 74 | UpdateVertex(curtNode, neighbor, true); 75 | } 76 | } 77 | } 78 | 79 | private void ProcessEnd(ref SearchNode startStopNode, ref SearchNode endStopNode) 80 | { 81 | Vector2Int curtPos = PopOpenList(false); 82 | SearchNode curtNode = GetNode(curtPos); 83 | 84 | #region show 85 | curtNode.SetSearchType(SearchType.Expanded, true); 86 | #endregion 87 | 88 | curtNode.Closed = true; 89 | 90 | List neighbors = GetNeighbors(curtNode); 91 | for (int i = 0; i < neighbors.Count; i++) 92 | { 93 | SearchNode neighbor = neighbors[i]; 94 | if (neighbor.IsStartOpen()) 95 | { 96 | startStopNode = curtNode; 97 | endStopNode = neighbor; 98 | return; 99 | } 100 | 101 | if (neighbor.Closed == false) 102 | { 103 | if (neighbor.IsEndOpen() == false) 104 | neighbor.SetParent(null, float.MaxValue); 105 | 106 | UpdateVertex(curtNode, neighbor, false); 107 | } 108 | } 109 | } 110 | 111 | private void AddToOpenList(SearchNode node, bool isStart) 112 | { 113 | if(isStart) 114 | { 115 | m_startOpen.Enqueue(node.Pos, node.F(m_weight)); 116 | node.SetStartOpen(); 117 | } 118 | else 119 | { 120 | m_endOpen.Enqueue(node.Pos, node.F(m_weight)); 121 | node.SetEndOpen(); 122 | } 123 | 124 | node.SetSearchType(SearchType.Open, true); 125 | } 126 | 127 | private Vector2Int PopOpenList(bool isStart) 128 | { 129 | if (isStart) 130 | return m_startOpen.Dequeue(); 131 | else 132 | return m_endOpen.Dequeue(); 133 | } 134 | 135 | private void UpdateVertex(SearchNode curtNode, SearchNode nextNode, bool isStart) 136 | { 137 | float oldG = nextNode.G; 138 | ComputeCost(curtNode, nextNode); 139 | 140 | if (nextNode.G < oldG) 141 | { 142 | if (nextNode.Opened == false) 143 | AddToOpenList(nextNode, isStart); 144 | } 145 | } 146 | 147 | private void GeneratePath(SearchNode startStopNode, SearchNode endStopNode) 148 | { 149 | if (startStopNode == null || endStopNode == null) 150 | return; 151 | 152 | SearchNode lastNode = startStopNode; 153 | while(lastNode != null) 154 | { 155 | lastNode.SetSearchType(SearchType.Path, true); 156 | lastNode = lastNode.Parent; 157 | } 158 | 159 | lastNode = endStopNode; 160 | while (lastNode != null) 161 | { 162 | lastNode.SetSearchType(SearchType.Path, true); 163 | lastNode = lastNode.Parent; 164 | } 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Bidirection/BiAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47011c5fe37d55b43b00b006da222892 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3729718b18b431f42a6eabd72c2cff20 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/BaseGrid.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | /// 5 | /// 操作: 6 | /// 左键点击:添加障碍 7 | /// 右键点击:移除障碍 8 | /// 空格键:开始寻路 9 | /// 10 | public abstract class BaseGrid : MonoBehaviour where T : BaseNode 11 | { 12 | public GameObject m_nodePrefab; 13 | 14 | protected int m_row = 8; 15 | protected int m_col = 15; 16 | 17 | protected T[,] m_nodes; 18 | 19 | protected int m_brushType = Define.c_costObstacle; 20 | 21 | protected virtual void Awake() 22 | { 23 | m_nodes = new T[m_row, m_col]; 24 | for(int y = 0; y < m_row; y++) 25 | { 26 | for(int x = 0; x < m_col; x++) 27 | { 28 | GameObject go = GameObject.Instantiate(m_nodePrefab); 29 | go.name = $"node({x}, {y})"; 30 | go.transform.SetParent(transform); 31 | go.transform.localPosition = new Vector3(x, y, 0); 32 | 33 | m_nodes[y, x] = go.GetComponent(); 34 | m_nodes[y, x].Init(x, y, Define.c_costGround); 35 | } 36 | } 37 | } 38 | 39 | protected virtual void Update() 40 | { 41 | if (Input.GetMouseButton(0)) 42 | Brush(m_brushType); 43 | else if (Input.GetMouseButton(1)) 44 | Brush(Define.c_costGround); 45 | else if (Input.GetKeyDown(KeyCode.Space)) 46 | Generate(); 47 | } 48 | 49 | protected abstract void Generate(); 50 | 51 | protected virtual bool Brush(int brushType) 52 | { 53 | BaseNode node = GetMouseOverNode(); 54 | if(node != null) 55 | { 56 | int last = node.Cost; 57 | node.SetCost(brushType); 58 | return last != node.Cost; 59 | } 60 | 61 | return false; 62 | } 63 | 64 | protected T GetMouseOverNode() 65 | { 66 | T result = null; 67 | 68 | Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 69 | if(Physics.Raycast(ray, out RaycastHit hit)) 70 | result = hit.collider.GetComponent(); 71 | 72 | return result; 73 | } 74 | 75 | protected List GetNeighbors(BaseNode node, bool useDiagonal) 76 | { 77 | List result = new List(); 78 | 79 | if (node == null) 80 | return result; 81 | 82 | int x = node.X; 83 | int y = node.Y; 84 | 85 | //left 86 | CheckAdd(x - 1, y, result); 87 | //right 88 | CheckAdd(x + 1, y, result); 89 | //Bottom 90 | CheckAdd(x, y - 1, result); 91 | //top 92 | CheckAdd(x, y + 1, result); 93 | 94 | //是否考虑对角线 95 | if(useDiagonal) 96 | { 97 | //Top Left 98 | CheckAdd(x - 1, y + 1, result); 99 | //Bottom Left 100 | CheckAdd(x - 1, y - 1, result); 101 | //Top Right 102 | CheckAdd(x + 1, y + 1, result); 103 | //Bottom Right 104 | CheckAdd(x + 1, y - 1, result); 105 | } 106 | 107 | return result; 108 | } 109 | 110 | void CheckAdd(int x, int y, List list) 111 | { 112 | if (x >= 0 && x < m_col && y >= 0 && y < m_row) 113 | list.Add(GetNode(x, y)); 114 | } 115 | 116 | protected virtual T GetNode(int x, int y) 117 | { 118 | return m_nodes[y, x]; 119 | } 120 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/BaseGrid.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 16e540a0c8ab3db4fb37ef39c48d85ee 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/BaseNode.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class BaseNode : MonoBehaviour 4 | { 5 | protected int m_x; 6 | protected int m_y; 7 | protected int m_cost; 8 | 9 | #region get_set 10 | public int X { get { return m_x; } } 11 | 12 | public int Y { get { return m_y; } } 13 | 14 | public Vector2Int Pos { get { return new Vector2Int(m_x, m_y); } } 15 | 16 | public int Cost { get { return m_cost; } } 17 | #endregion 18 | 19 | protected virtual void Awake() 20 | { 21 | if (GetComponent() == null) 22 | Debug.LogError("请在Node的预设上绑定Collider"); 23 | } 24 | 25 | public virtual void Init(int x, int y, int cost) 26 | { 27 | m_x = x; 28 | m_y = y; 29 | m_cost = cost; 30 | } 31 | 32 | public bool IsObstacle() 33 | { 34 | return m_cost == Define.c_costObstacle; 35 | } 36 | 37 | public virtual void SetCost(int cost) 38 | { 39 | m_cost = cost; 40 | } 41 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/BaseNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e2460d7602203ed4dbe8d19075e52dd5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/BaseSearchAlgo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | public abstract class BaseSearchAlgo 7 | { 8 | private const float c_minDelta = 0.0001f; //误差小于该值则认为两个Float相等 9 | 10 | protected readonly int m_infinite; //用于表示论文中的无限,不用int.MaxValue是怕运算溢出 11 | 12 | protected SearchNode m_mapStart; 13 | protected SearchNode m_mapGoal; 14 | protected readonly SearchNode[,] m_nodes; 15 | protected readonly int m_mapWidth; 16 | protected readonly int m_mapHeight; 17 | 18 | protected readonly float m_showTime; 19 | 20 | public BaseSearchAlgo(SearchNode start, SearchNode end, SearchNode[,] nodes, float showTime) 21 | { 22 | m_mapStart = start; 23 | m_mapGoal = end; 24 | m_nodes = nodes; 25 | m_showTime = showTime; 26 | 27 | m_mapHeight = nodes.GetLength(0); 28 | m_mapWidth = nodes.GetLength(1); 29 | m_infinite = m_mapWidth * m_mapHeight * 10; 30 | } 31 | 32 | public abstract IEnumerator Process(); 33 | 34 | protected virtual List GetNeighbors(SearchNode node) 35 | { 36 | List result = new List(); 37 | Vector2Int pos = node.Pos; 38 | 39 | bool left = TryAddNode(pos, -1, 0, result); 40 | bool right = TryAddNode(pos, 1, 0, result); 41 | bool top = TryAddNode(pos, 0, 1, result); 42 | bool bottom = TryAddNode(pos, 0, -1, result); 43 | 44 | if (left || top) TryAddNode(pos, -1, 1, result); 45 | if (left || bottom) TryAddNode(pos, -1, -1, result); 46 | if (right || bottom) TryAddNode(pos, 1, -1, result); 47 | if (right || top) TryAddNode(pos, 1, 1, result); 48 | 49 | return result; 50 | } 51 | 52 | protected void ForeachNeighbors(SearchNode node, Action func) 53 | { 54 | List neighbors = GetNeighbors(node); 55 | for (int i = 0; i < neighbors.Count; i++) 56 | func(neighbors[i]); 57 | } 58 | 59 | protected virtual bool TryAddNode(Vector2Int curtPos, int dx, int dy, List result) 60 | { 61 | int x = curtPos.x + dx; 62 | int y = curtPos.y + dy; 63 | SearchNode node = GetNode(x, y); 64 | if(node != null && node.IsObstacle() == false) 65 | { 66 | result.Add(node); 67 | return true; 68 | } 69 | else 70 | { 71 | return false; 72 | } 73 | } 74 | 75 | protected bool IsWalkableAt(int x, int y) 76 | { 77 | SearchNode node = GetNode(x, y); 78 | return node != null && !node.IsObstacle(); 79 | } 80 | 81 | protected bool IsInside(int x, int y) 82 | { 83 | return (x >= 0 && x < m_nodes.GetLength(1) && y >= 0 && y < m_nodes.GetLength(0)); 84 | } 85 | 86 | protected SearchNode GetNode(int x, int y) 87 | { 88 | if (IsInside(x, y)) 89 | return m_nodes[y, x]; 90 | else 91 | return null; 92 | } 93 | 94 | protected SearchNode GetNode(Vector2Int pos) 95 | { 96 | return GetNode(pos.x, pos.y); 97 | } 98 | 99 | protected float g(SearchNode s) 100 | { 101 | return s.G; 102 | } 103 | 104 | protected virtual float h(SearchNode s) 105 | { 106 | if (s.H < 0) 107 | s.H = CalcHeuristic(s, m_mapGoal); 108 | 109 | return s.H; 110 | } 111 | 112 | protected virtual float c(SearchNode a, SearchNode b) 113 | { 114 | Vector2Int ap = a.Pos; 115 | Vector2Int bp = b.Pos; 116 | return SearchGrid.Instance.CalcHeuristic(ap, bp, b.Cost); //TODO 对于FlowField,需要把直线上的所有格子代价都加进来 117 | } 118 | 119 | protected float CalcHeuristic(SearchNode a, SearchNode b, float weight = 1) 120 | { 121 | return SearchGrid.Instance.CalcHeuristic(a.Pos, b.Pos, weight); 122 | } 123 | 124 | public virtual void NotifyChangeNode(List nodes, bool increaseCost) { } 125 | 126 | public virtual void NotifyChangeStart(SearchNode startNode) { } 127 | 128 | public virtual void NotifyChangeGoal(SearchNode goalNode) { } 129 | 130 | protected void ForeachNode(Action callback) 131 | { 132 | for(int y = 0; y < m_mapHeight; y++) 133 | for(int x = 0; x < m_mapWidth; x++) 134 | callback(m_nodes[y, x]); 135 | } 136 | 137 | //TODO 想想更好的处理方式,不用float 138 | #region Handle float 139 | protected bool Equal(float a, float b) 140 | { 141 | return Mathf.Abs(a - b) <= c_minDelta; 142 | } 143 | 144 | protected bool NotEqual(float a, float b) 145 | { 146 | return !Equal(a, b); 147 | } 148 | 149 | protected bool Bigger(float a, float b) 150 | { 151 | return (a - b) > c_minDelta; 152 | } 153 | 154 | protected bool Less(float a, float b) 155 | { 156 | return Bigger(b, a); 157 | } 158 | 159 | protected bool LessEqual(float a, float b) 160 | { 161 | return Equal(a, b) || Less(a, b); 162 | } 163 | #endregion 164 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/BaseSearchAlgo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0c038bd486360fa4ba70a77747bb5355 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/CommonDefine.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public static class Define 4 | { 5 | public const int c_costGround = 1; 6 | public const int c_costWater = 2; 7 | public const int c_costObstacle = 255; 8 | public static readonly float c_sqrt2 = Mathf.Sqrt(2); 9 | 10 | public static Color Cost2Color(int cost) 11 | { 12 | switch(cost) 13 | { 14 | case 1: 15 | return Color.white; 16 | case 2: 17 | return Color.blue; 18 | case 3: 19 | return Color.green; 20 | case c_costObstacle: 21 | return Color.black; 22 | default: 23 | return Color.white; 24 | } 25 | } 26 | 27 | public static Color SearchType2Color(SearchType type) 28 | { 29 | switch(type) 30 | { 31 | case SearchType.Start: 32 | return new Color(0.5f, 0, 0, 1); 33 | case SearchType.Goal: 34 | return new Color(1, 0, 0, 1); 35 | case SearchType.Open: 36 | return new Color(0, 0.5f, 0.5f, 1); 37 | case SearchType.Expanded: 38 | return Color.cyan; 39 | case SearchType.Path: 40 | return Color.yellow; 41 | case SearchType.CurtPos: 42 | return Color.blue; 43 | default: 44 | return Color.white; 45 | } 46 | } 47 | } 48 | 49 | public enum Dir 50 | { 51 | None, 52 | 53 | TopLeft, 54 | Left, 55 | BottomLeft, 56 | Bottom, 57 | BottomRight, 58 | Right, 59 | TopRight, 60 | Top, 61 | } 62 | 63 | public enum SearchType 64 | { 65 | None, 66 | Start, 67 | Goal, 68 | Open, 69 | Expanded, 70 | Path, 71 | CurtPos, 72 | } 73 | 74 | public enum SearchAlgo 75 | { 76 | A_Star, 77 | BestFirstSearch, 78 | BreadthFirstSearch, 79 | DijkstraSearch, 80 | Theta_Star, 81 | LazyTheta_Star, 82 | JPS, 83 | JPSPlus, 84 | BiA_Star, 85 | AnnotatedA_Star, 86 | //Incremental 87 | D_Star, 88 | FocussedD_Star, 89 | IDA_Star, 90 | LPA_Star, 91 | DstarLite, 92 | Path_AA_Star, 93 | Tree_AA_Star, 94 | //Moving Target 95 | GAA_Star, 96 | GFRA_Star, 97 | MT_DstarLite, 98 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/CommonDefine.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e371c4e2ce4f93543bfa9b9f5aa4f5df 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/GraphAStar.cs: -------------------------------------------------------------------------------- 1 | using Priority_Queue; 2 | using UnityEngine; 3 | 4 | public class GraphAStar 5 | { 6 | public static GraphNode StartNode; 7 | public static GraphNode EndNode; 8 | 9 | private readonly SimplePriorityQueue m_open = new SimplePriorityQueue(); 10 | 11 | public GraphAStar(GraphNode startNode, GraphNode endNode) 12 | { 13 | StartNode = startNode; 14 | EndNode = endNode; 15 | } 16 | 17 | public void Process() 18 | { 19 | StartNode.G = 0; 20 | AddToOpen(StartNode); 21 | 22 | while (OpenSize() > 0) 23 | { 24 | var node = PopOpen(); 25 | 26 | if (node == EndNode) 27 | break; 28 | 29 | node.Closed = true; 30 | var neighbors = node.Neighbors; 31 | for (int i = 0; i < neighbors.Count; i++) 32 | { 33 | var n = neighbors[i]; 34 | if (!n.Closed) 35 | { 36 | if (!n.Opened) 37 | n.SetParent(null, float.MaxValue); 38 | 39 | UpdateVertex(node, n); 40 | } 41 | } 42 | } 43 | } 44 | 45 | private void UpdateVertex(GraphNode curtNode, GraphNode nextNode) 46 | { 47 | float oldG = nextNode.G; 48 | ComputeCost(curtNode, nextNode); 49 | 50 | if (nextNode.G < oldG) 51 | { 52 | if (!nextNode.Opened) 53 | AddToOpen(nextNode); 54 | else 55 | m_open.UpdatePriority(nextNode, nextNode.F(EndNode)); 56 | } 57 | } 58 | 59 | protected virtual void ComputeCost(GraphNode curtNode, GraphNode nextNode) 60 | { 61 | float cost = curtNode.G + (curtNode.Center - nextNode.Center).magnitude; 62 | if (cost < nextNode.G) 63 | nextNode.SetParent(curtNode, cost); 64 | } 65 | 66 | #region Open 67 | private void AddToOpen(GraphNode node) 68 | { 69 | m_open.Enqueue(node, node.F(EndNode)); 70 | node.Opened = true; 71 | } 72 | 73 | private GraphNode PopOpen() 74 | { 75 | return m_open.Dequeue(); 76 | } 77 | 78 | private int OpenSize() 79 | { 80 | return m_open.Count; 81 | } 82 | #endregion 83 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/GraphAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0166a8d3ef61e641a42c44334dd15dd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/GraphNode.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | public class GraphNode 5 | { 6 | private GraphNode m_parent; 7 | private float m_g = float.MaxValue; 8 | private float m_h = -1; 9 | private bool m_opened; 10 | private bool m_closed; 11 | private readonly List m_neighbors = new List(); 12 | 13 | public Vector2 Center { get; set; } 14 | 15 | public GraphNode Parent 16 | { 17 | get { return m_parent; } 18 | set { m_parent = value; } 19 | } 20 | 21 | public List Neighbors { get { return m_neighbors; } } 22 | 23 | public bool Opened 24 | { 25 | get { return m_opened; } 26 | set 27 | { 28 | m_opened = value; 29 | if (m_opened) 30 | m_closed = false; 31 | } 32 | } 33 | 34 | public bool Closed 35 | { 36 | get { return m_closed; } 37 | set 38 | { 39 | m_closed = value; 40 | if (m_closed) 41 | m_opened = false; 42 | } 43 | } 44 | 45 | public float G 46 | { 47 | get { return m_g; } 48 | set { m_g = value; } 49 | } 50 | 51 | public GraphNode(Vector2 center) 52 | { 53 | Center = center; 54 | } 55 | 56 | public void AddNeighbor(GraphNode n) 57 | { 58 | m_neighbors.Add(n); 59 | } 60 | 61 | public void SetParent(GraphNode parent, float g) 62 | { 63 | m_parent = parent; 64 | m_g = g; 65 | } 66 | 67 | public float F(GraphNode endNode) 68 | { 69 | if (m_h < 0) 70 | m_h = (Center - endNode.Center).magnitude; 71 | 72 | return m_g + m_h; 73 | } 74 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/GraphNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c3a2ad6612f1df844a99f79d6998de9b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/Heuristic.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// 启发式函数 5 | /// 6 | public static class Heuristic 7 | { 8 | /// 9 | /// 曼哈顿距离 10 | /// 适用场景:四方向网格移动 11 | /// 12 | public static float Manhattan(int dx, int dy) 13 | { 14 | return dx + dy; 15 | } 16 | 17 | public static float Manhattan(Vector2Int a, Vector2Int b) 18 | { 19 | int dx = Mathf.Abs(a.x - b.x); 20 | int dy = Mathf.Abs(a.y - b.y); 21 | return Manhattan(dx, dy); 22 | } 23 | 24 | /// 25 | /// 切比雪夫距离 26 | /// 使用场景:八方向网格移动(斜线代价为1) 27 | /// 28 | public static float Chebyshev(int dx, int dy) 29 | { 30 | return Mathf.Max(dx, dy); 31 | } 32 | 33 | public static float Chebyshev(Vector2Int a, Vector2Int b) 34 | { 35 | int dx = Mathf.Abs(a.x - b.x); 36 | int dy = Mathf.Abs(a.y - b.y); 37 | return Chebyshev(dx, dy); 38 | } 39 | 40 | /// 41 | /// Oct tile 八方向网格距离 42 | /// 使用场景:八方向移动(斜线代价为Sqrt(2)) 43 | /// 44 | public static float Octile(int dx, int dy) 45 | { 46 | //做法:先走45度斜线,然后走剩余的x或y方向 47 | float f = Define.c_sqrt2 - 1; 48 | return (dx < dy) ? f * dx + dy : f * dy + dx; 49 | } 50 | 51 | public static float Octile(Vector2Int a, Vector2Int b) 52 | { 53 | int dx = Mathf.Abs(a.x - b.x); 54 | int dy = Mathf.Abs(a.y - b.y); 55 | return Octile(dx, dy); 56 | } 57 | 58 | /// 59 | /// 欧几里德距离 60 | /// 使用场景:没有移动方向限制(路点或Navmesh) 61 | /// 62 | public static float Euclidean(int dx, int dy) 63 | { 64 | return Mathf.Sqrt(dx * dx + dy * dy); 65 | } 66 | 67 | public static float Euclidean(Vector2Int a, Vector2Int b) 68 | { 69 | int dx = Mathf.Abs(a.x - b.x); 70 | int dy = Mathf.Abs(a.y - b.y); 71 | return Euclidean(dx, dy); 72 | } 73 | } 74 | 75 | public enum HeuristicType 76 | { 77 | Manhattan, 78 | Chebyshev, 79 | Octile, 80 | Euclidean 81 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/Heuristic.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f217972963676547a4eab9708281325 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/SearchGrid.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1fe9d058a6c3d047871dc28aede470f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Common/SearchNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41e48c57595d65a448c621c477b71db0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/FlowField.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ac678e1f1586f4479cef8bdf82836d4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/FlowField/FlowField.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | //步骤 6 | //1.配置Cost field 7 | //2.根据Cost field生成Integration field 8 | //3.根据Integration field生成Flow field 9 | 10 | public class FlowField : BaseGrid 11 | { 12 | private const int c_stateOpen = 1; 13 | private const int c_stateClose = 2; 14 | 15 | public FlowFieldShowType m_showType = FlowFieldShowType.All; 16 | private FlowFieldNode m_targetNode; 17 | private bool m_dragTarget; 18 | 19 | protected override void Awake() 20 | { 21 | base.Awake(); 22 | 23 | m_targetNode = GetNode(0, 0); 24 | m_targetNode.SetIsTarget(true); 25 | Generate(); 26 | } 27 | 28 | protected override void Update() 29 | { 30 | if(Input.GetMouseButtonDown(0)) 31 | { 32 | BaseNode node = GetMouseOverNode(); 33 | if (node == m_targetNode) 34 | m_dragTarget = true; 35 | } 36 | else if(Input.GetMouseButtonUp(0)) 37 | { 38 | m_dragTarget = false; 39 | } 40 | else if(Input.GetMouseButton(0)) 41 | { 42 | if(m_dragTarget) 43 | { 44 | FlowFieldNode node = DragNode(); 45 | if(node != null) 46 | { 47 | m_targetNode.SetIsTarget(false); 48 | m_targetNode = node; 49 | m_targetNode.SetIsTarget(true); 50 | Generate(); 51 | } 52 | } 53 | else 54 | { 55 | Brush(Define.c_costObstacle); 56 | } 57 | } 58 | else if(Input.GetMouseButton(1)) 59 | { 60 | Brush(Define.c_costGround); 61 | } 62 | else if(Input.GetKeyDown(KeyCode.Space)) 63 | { 64 | Generate(); 65 | } 66 | } 67 | 68 | private FlowFieldNode DragNode() 69 | { 70 | FlowFieldNode node = GetMouseOverNode(); 71 | if (node != null && node != m_targetNode && node.IsObstacle() == false) 72 | return node; 73 | else 74 | return null; 75 | } 76 | 77 | protected override bool Brush(int brushType) 78 | { 79 | bool result = false; 80 | 81 | BaseNode node = GetMouseOverNode(); 82 | if (node != null && node != m_targetNode) 83 | { 84 | int last = node.Cost; 85 | node.SetCost(brushType); 86 | result = last != node.Cost; 87 | } 88 | 89 | if (result) 90 | Generate(); 91 | 92 | return result; 93 | } 94 | 95 | protected override void Generate() 96 | { 97 | int tx = Mathf.Clamp(m_targetNode.X, 0, m_col - 1); 98 | int ty = Mathf.Clamp(m_targetNode.Y, 0, m_row - 1); 99 | 100 | GenerateIntegrationField(tx, ty); 101 | GenerateFlowField(); 102 | 103 | TraverseAllNode((FlowFieldNode n) => n.Show(m_showType)); 104 | } 105 | 106 | void TraverseAllNode(Action action) 107 | { 108 | for(int y = 0; y < m_row; y++) 109 | for(int x = 0; x < m_col; x++) 110 | action(m_nodes[y, x] as FlowFieldNode); 111 | } 112 | 113 | void GenerateIntegrationField(int targetX, int targetY) 114 | { 115 | //重置状态 116 | TraverseAllNode((node) => node.Reset()); 117 | 118 | //设置目标 119 | Stack openStack = new Stack(); 120 | FlowFieldNode goal = GetNode(targetX, targetY) as FlowFieldNode; 121 | goal.State = c_stateOpen; 122 | goal.Distance = 0; 123 | openStack.Push(goal); 124 | 125 | while (openStack.Count > 0) 126 | { 127 | FlowFieldNode node = openStack.Pop(); 128 | node.State = c_stateClose; 129 | 130 | List neighbors = GetNeighbors(node, false); 131 | for (int i = 0; i < neighbors.Count; i++) 132 | { 133 | FlowFieldNode neighbor = neighbors[i] as FlowFieldNode; 134 | 135 | if (neighbor.IsObstacle()) 136 | continue; 137 | 138 | if (neighbor.Distance == FlowFieldNode.k_NoInit || neighbor.Distance > (node.Distance + neighbor.Cost)) 139 | { 140 | neighbor.Distance = node.Distance + neighbor.Cost; 141 | 142 | if (neighbor.State != c_stateOpen) 143 | { 144 | openStack.Push(neighbor); 145 | neighbor.State = c_stateOpen; 146 | } 147 | } 148 | } 149 | } 150 | } 151 | 152 | void GenerateFlowField() 153 | { 154 | TraverseAllNode((node) => CalcDir(node)); 155 | } 156 | 157 | //TODO 优化计算方向的方法 158 | void CalcDir(FlowFieldNode node) 159 | { 160 | if (node == null || node.IsObstacle() || node.Distance <= 0) 161 | { 162 | node.Dir = -1; 163 | return; 164 | } 165 | 166 | int min = int.MaxValue; 167 | int angle = -1; 168 | 169 | int x = node.X; 170 | int y = node.Y; 171 | 172 | bool left = CalcDirHelper(x - 1, y, Dir.Left, ref min, ref angle); 173 | bool right = CalcDirHelper(x + 1, y, Dir.Right, ref min, ref angle); 174 | bool top = CalcDirHelper(x, y + 1, Dir.Top, ref min, ref angle); 175 | bool bottom = CalcDirHelper(x, y - 1, Dir.Bottom, ref min, ref angle); 176 | 177 | if(top || left) 178 | CalcDirHelper(x - 1, y + 1, Dir.TopLeft, ref min, ref angle); 179 | 180 | if(bottom || left) 181 | CalcDirHelper(x - 1, y - 1, Dir.BottomLeft, ref min, ref angle); 182 | 183 | if(bottom || right) 184 | CalcDirHelper(x + 1, y - 1, Dir.BottomRight, ref min, ref angle); 185 | 186 | if(top || right) 187 | CalcDirHelper(x + 1, y + 1, Dir.TopRight, ref min, ref angle); 188 | 189 | node.Dir = angle; 190 | } 191 | 192 | bool CalcDirHelper(int x, int y, Dir dir, ref int min, ref int angle) 193 | { 194 | if (x >= 0 && x < m_col && y >= 0 && y < m_row) 195 | { 196 | FlowFieldNode n = GetNode(x, y) as FlowFieldNode; 197 | if (!n.IsObstacle() && n.Distance >= 0 && n.Distance < min) 198 | { 199 | min = n.Distance; 200 | angle = (int)dir * 45; 201 | } 202 | 203 | return !n.IsObstacle(); 204 | } 205 | else 206 | { 207 | return false; 208 | } 209 | } 210 | } 211 | 212 | public enum FlowFieldShowType 213 | { 214 | None, 215 | HeatMap, 216 | VectorField, 217 | All, 218 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/FlowField/FlowField.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 184f7313c0f173340b2b3bd8acb9323f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/FlowField/FlowFieldNode.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class FlowFieldNode : BaseNode 4 | { 5 | public const int k_Obstacle = -1; 6 | public const int k_NoInit = -2; 7 | public const int k_NoAngle = -1; 8 | 9 | private int m_distance = k_NoInit; //到目标的移动距离(非欧几里德距离) 10 | private int m_dir = k_NoAngle; 11 | private byte m_state; //0=未处理,1=IsOpen, 2=IsClose 12 | private bool m_isTarget; 13 | 14 | [SerializeField] private MeshRenderer m_bgRenderer; 15 | private Material m_bgMat; 16 | [SerializeField] private TextMesh m_text; 17 | [SerializeField] private Transform m_arrow; 18 | 19 | #region get-set 20 | public int Distance 21 | { 22 | get { return m_distance; } 23 | set { m_distance = value; } 24 | } 25 | 26 | public int Dir 27 | { 28 | get { return m_dir; } 29 | set { m_dir = value; } 30 | } 31 | 32 | public byte State 33 | { 34 | get { return m_state; } 35 | set { m_state = value; } 36 | } 37 | #endregion 38 | 39 | public override void Init(int x, int y, int cost) 40 | { 41 | base.Init(x, y, cost); 42 | 43 | gameObject.SetActive(true); 44 | 45 | float widthGap = 1.1f; 46 | transform.position = new Vector3(x * widthGap, y * widthGap, 0); 47 | 48 | m_bgMat = m_bgRenderer.material; 49 | m_bgMat.color = GetColor(m_cost); 50 | 51 | m_text.gameObject.SetActive(false); 52 | } 53 | 54 | public void Reset() 55 | { 56 | m_distance = k_NoInit; 57 | m_dir = k_NoAngle; 58 | m_state = 0; 59 | m_bgMat.color = GetColor(m_cost); 60 | } 61 | 62 | private void ShowValue() 63 | { 64 | if (m_distance == k_Obstacle) 65 | { 66 | m_text.gameObject.SetActive(false); 67 | return; 68 | } 69 | 70 | m_text.gameObject.SetActive(true); 71 | m_text.text = m_distance.ToString(); 72 | } 73 | 74 | private void HideValue() 75 | { 76 | m_text.gameObject.SetActive(false); 77 | } 78 | 79 | private void ShowArrow() 80 | { 81 | if (m_dir < 0) 82 | { 83 | HideArrow(); 84 | return; 85 | } 86 | 87 | m_arrow.gameObject.SetActive(true); 88 | m_arrow.localRotation = Quaternion.Euler(0, 0, m_dir); 89 | } 90 | 91 | private void HideArrow() 92 | { 93 | m_arrow.gameObject.SetActive(false); 94 | } 95 | 96 | public void Show(FlowFieldShowType showType) 97 | { 98 | switch (showType) 99 | { 100 | case FlowFieldShowType.HeatMap: 101 | ShowValue(); 102 | HideArrow(); 103 | break; 104 | case FlowFieldShowType.VectorField: 105 | ShowArrow(); 106 | HideValue(); 107 | break; 108 | case FlowFieldShowType.All: 109 | ShowValue(); 110 | ShowArrow(); 111 | break; 112 | default: 113 | HideValue(); 114 | HideArrow(); 115 | break; 116 | } 117 | } 118 | 119 | private Color GetColor(int cost) 120 | { 121 | if (m_isTarget) 122 | return Color.red; 123 | else 124 | return Define.Cost2Color(cost); 125 | } 126 | 127 | public void SetIsTarget(bool isTarget) 128 | { 129 | m_isTarget = isTarget; 130 | m_bgMat.color = GetColor(m_cost); 131 | } 132 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/FlowField/FlowFieldNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 280948e8ffc68e34a974d50c1e682f81 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0a50541a1ba67774d9c2c6d26b0b598f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HAAStar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: accd9139d47a2e04d937ecd4b620c86b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HAAStar/AnnotatedAStar.cs: -------------------------------------------------------------------------------- 1 | public class AnnotatedAStar : AStar 2 | { 3 | private readonly int m_unitSize; 4 | 5 | public AnnotatedAStar(SearchNode start, SearchNode goal, SearchNode[,] nodes, float weight, float showTime, int unitSize) 6 | : base(start, goal, nodes, weight, showTime) 7 | { 8 | m_unitSize = unitSize; 9 | } 10 | 11 | protected override bool IsNeighborValid(SearchNode neighbor) 12 | { 13 | return (neighbor.Closed == false && neighbor.TrueClearance >= m_unitSize); 14 | } 15 | 16 | #region Preprocess 17 | /// 18 | /// 离线预处理:给每个可行走格子设置Clearance 19 | /// 如果有多种地形,则每种地形及组合都要单独遍历地图处理一遍 20 | /// 21 | protected override void Preprocess() 22 | { 23 | ForeachNode((node) => 24 | { 25 | if (node.IsObstacle() == false) 26 | node.SetTrueClearance(CalcTrueClearance(node)); 27 | }); 28 | } 29 | 30 | private int CalcTrueClearance(SearchNode node) 31 | { 32 | int x = node.X; 33 | int y = node.Y; 34 | 35 | int curtExpand = 2; 36 | //不断往右下扩展,直到发现不可走的点 37 | while (true) 38 | { 39 | for(int dx = 0; dx < curtExpand; dx++) 40 | { 41 | for(int dy = 0; dy < curtExpand; dy++) 42 | { 43 | SearchNode next = GetNode(x + dx, y - dy); 44 | if (next == null || next.IsObstacle()) 45 | return curtExpand - 1; 46 | } 47 | } 48 | 49 | curtExpand++; 50 | } 51 | } 52 | #endregion 53 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HAAStar/AnnotatedAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 19ccb42d9652ee34ab4f40c1109c9d8a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 360c89e591aa2a74c816c382540ad7b4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Demo.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c7e564eacb50c5a4cbbfa665d7978dd7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Demo/HPADemo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d00e627340ec6a4ea56eab172b16aa9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Edge.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf66711380deda24dbf41663478d3b6f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Edge/AbstractEdge.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | public class AbstractEdge : MonoBehaviour, IEdge 5 | { 6 | [SerializeField] private int m_targetNodeId; 7 | [SerializeField] private float m_cost; 8 | [SerializeField] private int m_level; 9 | [SerializeField] private bool m_isInterEdge; 10 | 11 | public int TargetNodeId { get { return m_targetNodeId; } } 12 | public float Cost { get { return m_cost; } } 13 | public int Level { get { return m_level; } } 14 | public bool IsInterEdge { get { return m_isInterEdge; } } 15 | public List InnerLowerLevelPath { get; private set; } 16 | 17 | public void Init(int targetNodeId, float cost, int level, bool isInterEdge) 18 | { 19 | m_targetNodeId = targetNodeId; 20 | m_cost = cost; 21 | m_level = level; 22 | m_isInterEdge = isInterEdge; 23 | } 24 | 25 | public void Release() 26 | { 27 | Destroy(gameObject); 28 | } 29 | 30 | public void SetInnerLowerLevelPath(List path) 31 | { 32 | if (path != null) 33 | InnerLowerLevelPath = new List(path); 34 | else 35 | InnerLowerLevelPath = null; 36 | } 37 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Edge/AbstractEdge.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9358d9f9b8225f5418ad224a83f7089b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Edge/IEdge.cs: -------------------------------------------------------------------------------- 1 | public interface IEdge 2 | { 3 | int TargetNodeId { get; } 4 | float Cost { get; } 5 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Edge/IEdge.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8fa9c5ef774928c4fb369507ead699c4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: faa2d36211d119545a1d97f4a55a68dc 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/AbstractNode.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | public class AbstractNode : MonoBehaviour, INode 5 | { 6 | [SerializeField] private int m_id; 7 | [SerializeField] private int m_level; 8 | [SerializeField] private int m_clusterId; 9 | [SerializeField] private Vector2Int m_pos; 10 | 11 | public int Id { get { return m_id; } } 12 | public int Level 13 | { 14 | get { return m_level; } 15 | set { m_level = value; } 16 | } 17 | public int ClusterId { get { return m_clusterId; } } 18 | public Vector2Int Pos { get { return m_pos; } } 19 | 20 | public Dictionary Edges { get; } = new Dictionary(); 21 | 22 | public void Init(int id, int level, int clusterId, Vector2Int concretePos) 23 | { 24 | m_id = id; 25 | m_level = level; 26 | m_clusterId = clusterId; 27 | m_pos = concretePos; 28 | } 29 | 30 | public void AddEdge(AbstractEdge edge) 31 | { 32 | if(Edges.TryGetValue(edge.TargetNodeId, out AbstractEdge originEdge)) 33 | { 34 | if(originEdge.Level < edge.Level) 35 | { 36 | Edges[edge.TargetNodeId] = edge; 37 | originEdge.Release(); 38 | } 39 | } 40 | else 41 | { 42 | Edges[edge.TargetNodeId] = edge; 43 | } 44 | } 45 | 46 | public void RemoveEdge(int targetNodeId) 47 | { 48 | if(Edges.TryGetValue(targetNodeId, out AbstractEdge edge)) 49 | { 50 | edge.Release(); 51 | Edges.Remove(targetNodeId); 52 | } 53 | } 54 | 55 | public bool IsContainsEdge(int targetId) 56 | { 57 | return Edges.ContainsKey(targetId); 58 | } 59 | 60 | public void ClearEdges() 61 | { 62 | foreach (var edge in Edges.Values) 63 | edge.Release(); 64 | 65 | Edges.Clear(); 66 | } 67 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/AbstractNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fbb9116c5cb05b648b5eeb25b706bbe1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/Cluster.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | public class Cluster : MonoBehaviour 6 | { 7 | [SerializeField] private int m_id; 8 | 9 | /// 10 | /// 在Cluster级别的位置 11 | /// 12 | [SerializeField] private Vector2Int m_pos; 13 | 14 | /// 15 | /// Cluster覆盖的grid范围 16 | /// 17 | [SerializeField] private RectInt m_area; 18 | 19 | private ConcreteMap m_concreteMap; 20 | 21 | private readonly Dictionary, float> m_distanceDict = new Dictionary, float>(); 22 | private readonly Dictionary, List> m_pathDict = new Dictionary, List>(); 23 | 24 | public List EntrancePoints { get; } = new List(); 25 | 26 | public int Id { get { return m_id; } } 27 | public Vector2Int Pos { get { return m_pos; } } 28 | public RectInt Area { get { return m_area; } } 29 | 30 | public void Init(int id, Vector2Int pos, Vector2Int concretePos, Vector2Int size, ConcreteMap concreteMap) 31 | { 32 | m_id = id; 33 | m_pos = pos; 34 | m_concreteMap = concreteMap; 35 | m_area = new RectInt(concretePos, size); 36 | transform.localPosition = new Vector3(m_area.center.x, m_area.center.y, -0.1f); 37 | transform.localScale = new Vector3(size.x, size.y, 1); 38 | } 39 | 40 | public bool IsContainsPoint(Vector2Int concretePos) 41 | { 42 | return Area.Contains(concretePos); 43 | } 44 | 45 | public EntrancePoint AddEntrancePoint(int abstractId, ConcreteNode node) 46 | { 47 | EntrancePoint point = new EntrancePoint(abstractId, node); 48 | EntrancePoints.Add(point); 49 | return point; 50 | } 51 | 52 | public void RemoveEntrancePoint(int abstractId) 53 | { 54 | for(int i = 0; i < EntrancePoints.Count; i++) 55 | { 56 | if(EntrancePoints[i].AbstractId == abstractId) 57 | { 58 | EntrancePoints.RemoveAt(i); 59 | break; 60 | } 61 | } 62 | 63 | List> removeList = new List>(); 64 | foreach(var key in m_distanceDict.Keys) 65 | { 66 | if (key.Item1 == abstractId || key.Item2 == abstractId) 67 | removeList.Add(key); 68 | } 69 | 70 | for(int i = 0; i< removeList.Count; i++) 71 | { 72 | var key = removeList[i]; 73 | m_distanceDict.Remove(key); 74 | m_pathDict.Remove(key); 75 | } 76 | } 77 | 78 | private void CalcPathBetweenEntrances(EntrancePoint e1, EntrancePoint e2) 79 | { 80 | if (e1.AbstractId == e2.AbstractId) 81 | return; 82 | 83 | var tuple = Tuple.Create(e1.AbstractId, e2.AbstractId); 84 | var invTuple = Tuple.Create(e2.AbstractId, e1.AbstractId); 85 | 86 | if (m_distanceDict.ContainsKey(tuple)) 87 | return; 88 | 89 | PathPlanner planner = new PathPlanner(m_concreteMap, Area); 90 | Path path = planner.Search(e1.ConcreteNode, e2.ConcreteNode); 91 | if(path != null) 92 | { 93 | m_distanceDict[tuple] = m_distanceDict[invTuple] = path.Cost; 94 | 95 | m_pathDict[tuple] = new List(); 96 | m_pathDict[tuple].AddRange(path.Nodes); 97 | 98 | path.Nodes.Reverse(); 99 | m_pathDict[invTuple] = new List(); 100 | m_pathDict[invTuple].AddRange(path.Nodes); 101 | } 102 | } 103 | 104 | public void CalcIntraEdgesData() 105 | { 106 | foreach (var e1 in EntrancePoints) 107 | foreach (var e2 in EntrancePoints) 108 | CalcPathBetweenEntrances(e1, e2); 109 | } 110 | 111 | public void AddIntraEdgesData(EntrancePoint entrance) 112 | { 113 | foreach (var other in EntrancePoints) 114 | CalcPathBetweenEntrances(entrance, other); 115 | } 116 | 117 | public bool IsConnected(int abstractId1, int abstractId2) 118 | { 119 | return m_distanceDict.ContainsKey(Tuple.Create(abstractId1, abstractId2)); 120 | } 121 | 122 | public float Distance(int abstractId1, int abstractId2) 123 | { 124 | return m_distanceDict[Tuple.Create(abstractId1, abstractId2)]; 125 | } 126 | 127 | public List GetPath(int abstractId1, int abstractId2) 128 | { 129 | List result; 130 | m_pathDict.TryGetValue(Tuple.Create(abstractId1, abstractId2), out result); 131 | return result; 132 | } 133 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/Cluster.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 785f2a4b2dab57a4eac55e98c7263875 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/ConcreteNode.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class ConcreteNode : MonoBehaviour, INode 4 | { 5 | [SerializeField] private int m_id; 6 | [SerializeField] private int m_cost; 7 | [SerializeField] private Vector2Int m_pos; 8 | private SearchType m_searchType; 9 | 10 | public int Id { get { return m_id; } } 11 | public int Cost { get { return m_cost; } } 12 | public Vector2Int Pos { get { return m_pos; } } 13 | public SearchType SearchType { get { return m_searchType; } } 14 | public bool IsObstacle { get { return Cost == Define.c_costObstacle; } } 15 | 16 | public void Init(int id, int x, int y, int cost = 1) 17 | { 18 | m_id = id; 19 | SetCost(cost); 20 | SetPos(x, y); 21 | } 22 | 23 | private void SetPos(int x, int y) 24 | { 25 | m_pos = new Vector2Int(x, y); 26 | transform.position = new Vector3(x + 0.5f, y + 0.5f, 0); 27 | } 28 | 29 | public void SetCost(int cost) 30 | { 31 | m_cost = cost; 32 | GetComponent().material.color = Define.Cost2Color(cost); 33 | } 34 | 35 | public void SetSearchType(SearchType type, bool excludeStartEnd = true) 36 | { 37 | if (excludeStartEnd && (m_searchType == SearchType.Start || m_searchType == SearchType.Goal)) 38 | return; 39 | 40 | m_searchType = type; 41 | GetComponent().material.color = Define.SearchType2Color(type); 42 | } 43 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/ConcreteNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a16432d64be796040b8752fb5a2c0b2a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/Entrance.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public enum Orientation 4 | { 5 | Horizontal, 6 | Vertical, 7 | } 8 | 9 | public class Entrance 10 | { 11 | public Cluster Cluster1 { get; } 12 | public Cluster Cluster2 { get; } 13 | 14 | public ConcreteNode Node1 { get; } 15 | public ConcreteNode Node2 { get; } 16 | 17 | public Orientation Orientation { get; } 18 | 19 | public Entrance(Cluster cluster1, Cluster cluster2, ConcreteNode node1, ConcreteNode node2, Orientation orientation) 20 | { 21 | Cluster1 = cluster1; 22 | Cluster2 = cluster2; 23 | Node1 = node1; 24 | Node2 = node2; 25 | Orientation = orientation; 26 | } 27 | 28 | /// 29 | /// 获取该Entrance所属的最大Level 30 | /// 31 | public int MaxBelongLevel(int clusterSize, int maxLevel) 32 | { 33 | switch(Orientation) 34 | { 35 | case Orientation.Horizontal: 36 | return CalcLevel(clusterSize, maxLevel, Node1.Pos.x); 37 | case Orientation.Vertical: 38 | return CalcLevel(clusterSize, maxLevel, Node1.Pos.y); 39 | default: 40 | Debug.LogErrorFormat("没有代码处理Orientation={0}", Orientation); 41 | return -1; 42 | } 43 | } 44 | 45 | private int CalcLevel(int clusterSize, int maxLevel, int value) 46 | { 47 | if (value <= clusterSize) 48 | return 1; 49 | 50 | int count = value / clusterSize; 51 | if (value % clusterSize != 0) 52 | count++; 53 | 54 | int level = 1; 55 | while (count % 2 == 0 && level < maxLevel) //这里默认上一级的clusterSize是下一级的2倍 56 | { 57 | count /= 2; 58 | level++; 59 | } 60 | 61 | return level; 62 | } 63 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/Entrance.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7e79d0118be564b4483d4f7b58e5c49d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/EntrancePoint.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class EntrancePoint 4 | { 5 | public int AbstractId { get; private set; } 6 | public ConcreteNode ConcreteNode { get; private set; } 7 | 8 | public EntrancePoint(int abstractId, ConcreteNode concreteNode) 9 | { 10 | AbstractId = abstractId; 11 | ConcreteNode = concreteNode; 12 | } 13 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/EntrancePoint.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a03d0f95e830c04291df013fe912d5a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/INode.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public interface INode 4 | { 5 | int Id { get; } 6 | Vector2Int Pos { get; } 7 | } 8 | 9 | public struct PathNode : INode 10 | { 11 | public int Id { get; } 12 | public Vector2Int Pos { get; } 13 | public int Level { get; } 14 | 15 | public PathNode(int id, Vector2Int pos, int level) 16 | { 17 | Id = id; 18 | Pos = pos; 19 | Level = level; 20 | } 21 | 22 | public PathNode(Vector2Int pos) 23 | { 24 | Pos = pos; 25 | Id = Level = 0; 26 | } 27 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Element/INode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4175de3049607df46863ad9c6b59dec7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/HierarchicalMapFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 913b79ab37e847c4eba96d836a90df58 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2a08b52fa2962e848a591da960788b92 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/AbstractGraph.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | public class AbstractGraph 5 | { 6 | /// 7 | /// 索引值就是节点的id 8 | /// 9 | public List Nodes { get; set; } 10 | 11 | public AbstractGraph() 12 | { 13 | Nodes = new List(); 14 | } 15 | 16 | public void AddNode(AbstractNode node) 17 | { 18 | int size = node.Id + 1; 19 | if (Nodes.Count >= size) 20 | Nodes[node.Id] = node; 21 | else 22 | Nodes.Add(node); 23 | } 24 | 25 | public bool RemoveLastNode(int abstractId) 26 | { 27 | //TODO:因为以index作为id,因此只能移除最后一个,想想其它快速的数据组织方式 28 | if (abstractId != Nodes.Count - 1) 29 | { 30 | Debug.LogError($"移除的不是最后一个({abstractId}, {Nodes.Count-1}),有地方出问题了"); 31 | return false; 32 | } 33 | 34 | Nodes.RemoveAt(abstractId); 35 | return true; 36 | } 37 | 38 | public void AddEdge(int sourceId, int targetId, float cost, int level, bool isInterEdge) 39 | { 40 | var sourceNode = GetNode(sourceId); 41 | var targetNode = GetNode(targetId); 42 | var edge = HPADemo.Instance.CreateEdge(sourceNode.Pos, targetNode.Pos, level, isInterEdge); 43 | edge.Init(targetId, cost, level, isInterEdge); 44 | Nodes[sourceId].AddEdge(edge); 45 | } 46 | 47 | public void AddEdge(int srcId, AbstractEdge edge) 48 | { 49 | Nodes[srcId].AddEdge(edge); 50 | } 51 | 52 | public bool IsContainsEdge(int srcId, int targetId) 53 | { 54 | return Nodes[srcId].IsContainsEdge(targetId); 55 | } 56 | 57 | /// 58 | /// 移除所有起点或终点是该点的边 59 | /// 60 | public void RemoveEdgeFromAndToNode(int nodeId) 61 | { 62 | for(int i = 0; i < Nodes.Count; i++) 63 | { 64 | if(nodeId == i) 65 | Nodes[i].ClearEdges(); 66 | else 67 | Nodes[i].RemoveEdge(nodeId); 68 | } 69 | } 70 | 71 | public AbstractNode GetNode(int id) 72 | { 73 | return Nodes[id]; 74 | } 75 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/AbstractGraph.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 96ef82ecabb345e4e8285475dc6877b8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/AbstractMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Assets.Scripts.Hierarchy.HPAStar.Map 8 | { 9 | class AbstractMap 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/AbstractMap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bceecde20fa84064e9144201bbcda434 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/ConcreteMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class ConcreteMap : IMap 6 | { 7 | public int Width { get; } 8 | public int Height { get; } 9 | private readonly ConcreteNode[,] m_nodes; 10 | 11 | public ConcreteMap(int width, int height) 12 | { 13 | Width = width; 14 | Height = height; 15 | m_nodes = new ConcreteNode[height, width]; 16 | } 17 | 18 | public void ForeachNode(Action callback) 19 | { 20 | for (int y = 0; y < Height; y++) 21 | for (int x = 0; x < Width; x++) 22 | callback(m_nodes[y, x]); 23 | } 24 | 25 | public void AddNode(int x, int y, ConcreteNode node) 26 | { 27 | m_nodes[y, x] = node; 28 | } 29 | 30 | public ConcreteNode GetNode(int x, int y) 31 | { 32 | if (x < 0 || x >= Width || y < 0 || y >= Height) 33 | return null; 34 | 35 | return m_nodes[y, x]; 36 | } 37 | 38 | public ConcreteNode Get(Vector2Int pos) 39 | { 40 | return GetNode(pos.x, pos.y); 41 | } 42 | 43 | public int NodeCount() 44 | { 45 | return Width * Height; 46 | } 47 | 48 | public List GetSuccessors(INode source) 49 | { 50 | List result = new List(); 51 | Vector2Int pos = source.Pos; 52 | 53 | bool left = TryAddNode(pos, -1, 0, result); 54 | bool right = TryAddNode(pos, 1, 0, result); 55 | bool top = TryAddNode(pos, 0, 1, result); 56 | bool bottom = TryAddNode(pos, 0, -1, result); 57 | 58 | if (left || top) TryAddNode(pos, -1, 1, result); 59 | if (left || bottom) TryAddNode(pos, -1, -1, result); 60 | if (right || bottom) TryAddNode(pos, 1, -1, result); 61 | if (right || top) TryAddNode(pos, 1, 1, result); 62 | 63 | return result; 64 | } 65 | 66 | private bool TryAddNode(Vector2Int curtPos, int dx, int dy, List result) 67 | { 68 | int x = curtPos.x + dx; 69 | int y = curtPos.y + dy; 70 | ConcreteNode node = GetNode(x, y); 71 | if(node != null && !node.IsObstacle) 72 | { 73 | result.Add(node); 74 | return true; 75 | } 76 | else 77 | { 78 | return false; 79 | } 80 | } 81 | 82 | public float CalcHeuristic(INode a, INode b) 83 | { 84 | return Heuristic.Octile(a.Pos, b.Pos); 85 | } 86 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/ConcreteMap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b0f94c5f648f814bb721f71a72fcd4b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/HierarchicalMap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 574ebb7b7cac7f84bbfb5a10a745e5da 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/IMap.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | public interface IMap 4 | { 5 | int NodeCount(); 6 | List GetSuccessors(INode source); 7 | float CalcHeuristic(INode a, INode b); 8 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Map/IMap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15c4c31daaae96848a01ae8250d5c8ae 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Search.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dc885da66cdb0f749bfcafb8920b1d64 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Search/HierarchicalSearch.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f0c5e1b2d58c3c2499cdabc47052e3c4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Search/Path.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | public class Path 5 | { 6 | public List Nodes { get; set; } 7 | public float Cost { get; } 8 | 9 | public Path(float cost) 10 | { 11 | Cost = cost; 12 | } 13 | 14 | public Path(List nodes, float cost) 15 | { 16 | Nodes = nodes; 17 | Cost = cost; 18 | } 19 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Search/Path.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74c7e69caacb9d448ad7ffd176b1bfb1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Search/PathPlanner.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Priority_Queue; 3 | using UnityEngine; 4 | 5 | public class PathPlanner 6 | { 7 | private IMap m_map; 8 | private PlannerNode[] m_nodes; 9 | private INode m_start; 10 | private INode m_goal; 11 | private RectInt? m_limitRect; //限制在哪个区域内寻路 12 | private readonly SimplePriorityQueue m_open = new SimplePriorityQueue(); 13 | 14 | public PathPlanner(IMap map, RectInt? limitRect) 15 | { 16 | m_map = map; 17 | m_limitRect = limitRect; 18 | m_nodes = new PlannerNode[map.NodeCount()]; 19 | } 20 | 21 | public Path Search(INode start, INode goal) 22 | { 23 | m_start = start; 24 | m_goal = goal; 25 | 26 | PlannerNode startNode = new PlannerNode(start, 0, m_map.CalcHeuristic(start, goal), NodeStatus.Open); 27 | m_nodes[start.Id] = startNode; 28 | m_open.Enqueue(startNode, startNode.F); 29 | 30 | while(m_open.Count > 0) 31 | { 32 | PlannerNode curtNode = m_open.Dequeue(); 33 | if (curtNode.OriginNode.Id == m_goal.Id) 34 | break; 35 | 36 | curtNode.Status = NodeStatus.Close; 37 | 38 | List successors = m_map.GetSuccessors(curtNode.OriginNode); 39 | for(int i = 0; i < successors.Count; i++) 40 | { 41 | INode successor = successors[i]; 42 | if (m_limitRect != null && !m_limitRect.Value.Contains(successor.Pos)) 43 | continue; 44 | 45 | PlannerNode node = m_nodes[successor.Id]; 46 | if(node != null) 47 | { 48 | if(node.Status != NodeStatus.Close) 49 | { 50 | float oldG = node.G; 51 | float newG = curtNode.G + m_map.CalcHeuristic(curtNode.OriginNode, successor); 52 | if(newG < node.G) 53 | { 54 | node.G = newG; 55 | node.Parent = curtNode; 56 | } 57 | } 58 | } 59 | else 60 | { 61 | float g = curtNode.G + m_map.CalcHeuristic(curtNode.OriginNode, successor); 62 | float h = m_map.CalcHeuristic(successor, m_goal); 63 | node = new PlannerNode(successor, g, h, NodeStatus.Open); 64 | node.Parent = curtNode; 65 | m_nodes[successor.Id] = node; 66 | m_open.Enqueue(node, node.F); 67 | } 68 | } 69 | } 70 | 71 | return GeneratePath(); 72 | } 73 | 74 | private Path GeneratePath() 75 | { 76 | PlannerNode node = m_nodes[m_goal.Id]; 77 | if (node == null) 78 | return null; 79 | 80 | Path path = new Path(node.G); 81 | List list = new List() { node.OriginNode }; 82 | while(node.Parent != null) 83 | { 84 | node = node.Parent; 85 | list.Add(node.OriginNode); 86 | 87 | if (node.OriginNode.Id == m_start.Id) 88 | break; 89 | } 90 | 91 | list.Reverse(); 92 | 93 | path.Nodes = list; 94 | return path; 95 | } 96 | 97 | #region Node 98 | enum NodeStatus 99 | { 100 | Open, 101 | Close, 102 | } 103 | 104 | class PlannerNode 105 | { 106 | public INode OriginNode { get; } 107 | public float G { get; set; } 108 | public float H { get; set; } 109 | public float F { get { return G + H; } } 110 | public PlannerNode Parent { get; set; } 111 | public NodeStatus Status { get; set; } 112 | 113 | public PlannerNode(INode originNode, float g, float h, NodeStatus status) 114 | { 115 | OriginNode = originNode; 116 | G = g; 117 | H = h; 118 | Status = status; 119 | } 120 | } 121 | #endregion 122 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Hierarchy/HPAStar/Search/PathPlanner.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0a34aebce2359024a9a32ef65449aa97 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/IDAStar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ec1c5c3bb98c3974380e6eb9607c749b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/IDAStar/IDAStar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | //TODO 可视化搜索过程 7 | public class IDAStar : BaseSearchAlgo 8 | { 9 | private const int c_found = -1; 10 | private const int c_maxMilliSeconds = 2000; //最多运行多少毫秒 11 | private readonly float m_weight = 1; 12 | 13 | public IDAStar(SearchNode start, SearchNode end, SearchNode[,] nodes, float weight, float showTime) 14 | : base(start, end, nodes, showTime) 15 | { 16 | m_weight = weight; 17 | } 18 | 19 | public override IEnumerator Process() 20 | { 21 | DateTime startTime = DateTime.Now; 22 | 23 | float threshold = Heuristic(m_mapStart); 24 | Stack path = new Stack(); 25 | path.Push(m_mapStart); 26 | 27 | float result; 28 | while(true) 29 | { 30 | result = Search(path, 0, threshold); 31 | 32 | if (result == c_found) 33 | break; 34 | 35 | if (result == float.MaxValue) 36 | break; 37 | 38 | double runTime = DateTime.Now.Subtract(startTime).TotalMilliseconds; 39 | if (runTime > c_maxMilliSeconds) 40 | { 41 | Debug.LogError("Time Exceeded"); 42 | break; 43 | } 44 | 45 | threshold = result; 46 | } 47 | 48 | #region show 49 | if(result == c_found) 50 | { 51 | while(path.Count > 0) 52 | { 53 | SearchNode node = path.Pop(); 54 | node.SetSearchType(SearchType.Path, true); 55 | } 56 | } 57 | #endregion 58 | 59 | yield break; 60 | } 61 | 62 | private float Search(Stack path, float g, float threshold) 63 | { 64 | SearchNode node = path.Peek(); 65 | float f = g + Heuristic(node); 66 | if (f > threshold) 67 | return f; 68 | 69 | if (node == m_mapGoal) 70 | return c_found; 71 | 72 | float min = float.MaxValue; 73 | List neighbors = GetNeighbors(node); 74 | for(int i = 0; i < neighbors.Count; i++) 75 | { 76 | SearchNode neighbor = neighbors[i]; 77 | if (path.Contains(neighbor)) 78 | continue; 79 | 80 | path.Push(neighbor); 81 | 82 | float value = Search(path, g + c(node, neighbor), threshold); 83 | if (value == c_found) 84 | return c_found; 85 | 86 | if (value < min) 87 | min = value; 88 | 89 | path.Pop(); 90 | } 91 | 92 | return min; 93 | } 94 | 95 | private float Heuristic(SearchNode node) 96 | { 97 | return SearchGrid.Instance.CalcHeuristic(node.Pos, SearchGrid.Instance.EndNode.Pos, m_weight); 98 | } 99 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/IDAStar/IDAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d243ab9c260174e45863de7d6b68f3b0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b71ec387443497b40af27f7b09de092e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/AdaptiveAStar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 21eb8e017f5deac409f291e8c9e960cb 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/AdaptiveAStar/Path_AAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b2dbdf8c0e46b4646b79dc1ca9fd07a2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/AdaptiveAStar/Tree_AAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca835c6de2f644e40b70fa47a0568e56 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/DStar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2e44352b11f71054882854ad5e16b0ec 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/DStar/BaseDStar.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | /// 6 | /// D*和FD*十分相近,因此弄一个基类把共同部分抽离出来 7 | /// 8 | public abstract class BaseDStar : BaseSearchAlgo 9 | { 10 | protected const int c_sensorRadius = 2; //机器人传感器的探测范围 11 | protected readonly int m_largeValue; //用于阻挡的代价,普通算出来的移动代价一定要比该值小 12 | protected readonly int[,] m_foundMap; //目前通过传感器发现的地图 13 | 14 | public BaseDStar(SearchNode start, SearchNode goal, SearchNode[,] nodes, float showTime) 15 | : base(start, goal, nodes, showTime) 16 | { 17 | m_largeValue = m_mapWidth * m_mapHeight * 10; 18 | m_foundMap = new int[nodes.GetLength(0), nodes.GetLength(1)]; 19 | } 20 | 21 | protected bool IsFoundObstacle(int x, int y) 22 | { 23 | //假设并不知道整张地图的情况,那么只能依赖当前发现的格子代价来作为判断依据 24 | return m_foundMap[y, x] == Define.c_costObstacle; 25 | } 26 | 27 | /// 28 | /// 从节点b到节点a的代价(对于有向图来说,顺序很重要) 29 | /// 30 | protected float C(SearchNode a, SearchNode b) 31 | { 32 | if (IsFoundObstacle(a.X, a.Y) || IsFoundObstacle(b.X, b.Y)) 33 | { 34 | return m_largeValue; 35 | } 36 | else 37 | { 38 | //走斜线时,如果两边都是阻挡,那么该斜线的代价也是阻挡那么大 39 | int dx = a.X - b.X; 40 | int dy = a.Y - b.Y; 41 | if (Mathf.Abs(dx) != 0 && Mathf.Abs(dy) != 0) 42 | { 43 | if (IsFoundObstacle(b.X + dx, b.Y) && IsFoundObstacle(b.X, b.Y + dy)) 44 | return m_largeValue; 45 | } 46 | 47 | return c(a, b); 48 | } 49 | } 50 | 51 | /// 52 | /// 传感器能检测到的格子 53 | /// 54 | /// 检测的范围 55 | /// 能检测到的格子 56 | protected List SensorDetectNodes(SearchNode R, int radius) 57 | { 58 | List result = new List(); 59 | 60 | for (int dx = -radius; dx <= radius; dx++) 61 | for (int dy = -radius; dy <= radius; dy++) 62 | TryAddNode(R.Pos, dx, dy, result); 63 | 64 | return result; 65 | } 66 | 67 | protected override bool TryAddNode(Vector2Int curtPos, int dx, int dy, List result) 68 | { 69 | int x = curtPos.x + dx; 70 | int y = curtPos.y + dy; 71 | SearchNode node = GetNode(x, y); 72 | if (node != null) //原始论文中障碍物只是代价非常高,但还是可以作为邻居 73 | { 74 | result.Add(node); 75 | return true; 76 | } 77 | else 78 | { 79 | return false; 80 | } 81 | } 82 | 83 | protected bool MoveForwardOneStep(ref SearchNode R) 84 | { 85 | if (R.Parent == null) 86 | { 87 | Debug.LogError("前进失败,没有路径"); 88 | return false; 89 | } 90 | 91 | //路上遇到阻挡则认为没有可走路径了 92 | if (C(R, R.Parent) >= m_largeValue) 93 | { 94 | Debug.LogError("前进失败,遇见障碍"); 95 | return false; 96 | } 97 | 98 | R.SetSearchType(SearchType.Path, true); 99 | R = R.Parent; 100 | R.SetSearchType(SearchType.CurtPos, true); 101 | 102 | return true; 103 | } 104 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/DStar/BaseDStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0fe4b1544a4400d4aa3e4cc92a06105c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/DStar/DStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: daf517ebd6c04734eb96c92a5f87525d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/DStar/FocussedDStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9a38c616a0d2ea443bcf93c24929dc43 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/DStarLite.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: abfa160db1e07e245ba69b048f6ec3ef 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/LPAStar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 708d281a67108584bab480719589107d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/LPAStar/LPAKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public struct LPAKey : IComparable 4 | { 5 | public float Key1; 6 | public float Key2; 7 | 8 | public LPAKey(float key1, float key2) 9 | { 10 | Key1 = key1; 11 | Key2 = key2; 12 | } 13 | 14 | public static bool operator <(LPAKey lhs, LPAKey rhs) 15 | { 16 | return lhs.CompareTo(rhs) < 0; 17 | } 18 | 19 | public static bool operator >(LPAKey lhs, LPAKey rhs) 20 | { 21 | return !(lhs < rhs); 22 | } 23 | 24 | public int CompareTo(LPAKey other) 25 | { 26 | if (Key1 == other.Key1) 27 | return Key2.CompareTo(other.Key2); 28 | else 29 | return Key1.CompareTo(other.Key1); 30 | } 31 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/LPAStar/LPAKey.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f321003ec9e4aa4289cb42b507b7cb4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/LPAStar/LPAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9dc06dcfd86c54a4bbb82ddadac56b67 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/LPAStar/LPAStar_Optimized.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | /// 5 | /// 根据原始论文中优化章节进行的优化 6 | /// 7 | public class LPAStar_Optimized : LPAStar 8 | { 9 | private int m_mazeIteration; 10 | 11 | public LPAStar_Optimized(SearchNode start, SearchNode goal, SearchNode[,] nodes, float showTime) 12 | : base(start, goal, nodes, showTime) { } 13 | 14 | protected override void Initialize() 15 | { 16 | m_mazeIteration++; 17 | 18 | m_openQueue.Clear(); 19 | 20 | m_mapStart.G = c_large; 21 | m_mapStart.SetRhs(0, null); 22 | m_mapStart.LPAKey = CalculateKey(m_mapStart); 23 | m_mapStart.Iteration = m_mazeIteration; 24 | AddOrUpdateOpenQueue(m_mapStart); 25 | 26 | m_mapGoal.G = c_large; 27 | m_mapGoal.SetRhs(c_large, null); 28 | m_mapGoal.Iteration = m_mazeIteration; 29 | 30 | //优化点:避免遍历所有格子 31 | //* 实际应用时,因为格子可能很多,导致遍历格子十分耗时,而且其中很多格子根本不会访问到 32 | //* 这时可以直到访问该格子时才进行初始化(可以每个格子保存一个Iteration来确定格子是否在同一次搜索中) 33 | } 34 | 35 | private void InitNode(SearchNode node) 36 | { 37 | if(node.Iteration != m_mazeIteration) 38 | { 39 | node.G = c_large; 40 | node.SetRhs(c_large, null); 41 | node.Iteration = m_mazeIteration; 42 | } 43 | } 44 | 45 | protected override void UpdateVertex(SearchNode curtNode) 46 | { 47 | //注意:这里去掉了UpdateRhs,而把rhs的计算放到了ComputeShortestPath里 48 | 49 | if (Mathf.Approximately(curtNode.G, curtNode.Rhs)) 50 | { 51 | RemoveFromOpenQueue(curtNode); 52 | } 53 | else 54 | { 55 | curtNode.LPAKey = CalculateKey(curtNode); 56 | AddOrUpdateOpenQueue(curtNode); 57 | } 58 | } 59 | 60 | protected override void UpdateOverConsistent(SearchNode curtNode) 61 | { 62 | curtNode.G = curtNode.Rhs; 63 | RemoveFromOpenQueue(curtNode); 64 | 65 | List neighbors = GetNeighbors(curtNode); 66 | for (int i = 0; i < neighbors.Count; i++) 67 | { 68 | InitNode(neighbors[i]); 69 | float value = curtNode.G + c(curtNode, neighbors[i]); 70 | //优化点:简化rhs的计算 71 | //* 因为curtNode的g值变小,因此邻居中rhs值变化也肯定和curtNode有关,而不用遍历自己的邻居 72 | if (neighbors[i] != m_mapStart && neighbors[i].Rhs > value) 73 | { 74 | neighbors[i].SetRhs(value, curtNode); 75 | UpdateVertex(neighbors[i]); 76 | } 77 | } 78 | } 79 | 80 | protected override void UpdateUnderConsistent(SearchNode curtNode) 81 | { 82 | curtNode.G = c_large; 83 | UpdateVertex(curtNode); 84 | 85 | List neighbors = GetNeighbors(curtNode); 86 | for (int i = 0; i < neighbors.Count; i++) 87 | { 88 | InitNode(neighbors[i]); 89 | //优化点:简化rhs的计算 90 | //* 因为curtNode的g值变大,那么受影响的只有邻居中rhs依赖curtNode旧的g值的节点 91 | if (neighbors[i] != m_mapStart && neighbors[i].RhsSource == curtNode) 92 | { 93 | UpdateRhs(neighbors[i]); 94 | UpdateVertex(neighbors[i]); 95 | } 96 | } 97 | } 98 | 99 | protected override void ComputeShortestPath() 100 | { 101 | //优化点:提早结束 102 | //* 假设终点位于开放队列顶部,且属于过一致,那么当前要扩展的节点就是终点 103 | //* 扩展终点会把其g值设置为rhs值,让其变为局部一致,然后整个搜索结束 104 | //* 但最终生成路径时并不会使用到终点的g值,因此这一步可以省掉 105 | //* 该优化能避免扩展其它Key值与终点相同的点 106 | while(m_openQueue.Count > 0 && (TopKey() < CalculateKey(m_mapGoal) || m_mapGoal.Rhs > m_mapGoal.G)) 107 | { 108 | //优化点:减少开放队列的操作 109 | //* 这里由Pop改为Top,可以在欠一致的情况下减少一次移除操作的开销 110 | SearchNode curtNode = Top(); 111 | 112 | if (curtNode.G > curtNode.Rhs) 113 | UpdateOverConsistent(curtNode); 114 | else 115 | UpdateUnderConsistent(curtNode); 116 | } 117 | 118 | GeneratePath(); 119 | } 120 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/LPAStar/LPAStar_Optimized.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0291f1b55cc29c2428cc715fbe221674 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/Moving Target.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 18c77254380287b4fb6cf0738b5cf573 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/Moving Target/GAAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5500e256483b8004681f91b8f0ee6673 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/Moving Target/GFRAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c55af8b73febf2e43a85785a52f5c6c8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/Moving Target/MT_DStarLite.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | /// 6 | /// Moving Target D* Lite 7 | /// 作用:处理动态环境+起点终点同时变化的情景 8 | /// 思路:D* Lite + G-FRA* 9 | /// 10 | public class MT_DStarLite : DStarLite 11 | { 12 | private SearchNode m_currPos; 13 | private SearchNode m_currGoal; 14 | private readonly HashSet m_deleted = new HashSet(); 15 | 16 | public MT_DStarLite(SearchNode start, SearchNode goal, SearchNode[,] nodes, float showTime) 17 | : base(start, goal, nodes, showTime) { } 18 | 19 | public override IEnumerator Process() 20 | { 21 | m_currPos = m_mapStart; 22 | m_currStart = m_mapStart; 23 | m_currGoal = m_mapGoal; 24 | 25 | Initialize(); 26 | while(BeginNode() != EndNode()) 27 | { 28 | SearchNode oldStart = m_currStart; 29 | SearchNode oldGoal = m_currGoal; 30 | 31 | ComputeShortestPath(); 32 | if (m_currGoal.Rhs >= c_large) 33 | { 34 | Debug.LogError("找不到路径"); 35 | yield break; 36 | } 37 | 38 | List path = GetPath(); 39 | List nearChanged = new List(); 40 | //如果终点仍在路径上且环境没检测到变化,则继续往前走直到到达终点 41 | while(m_currPos != m_mapGoal && path.Contains(m_mapGoal) && nearChanged.Count <= 0) 42 | { 43 | MoveOneStep(path, nearChanged); 44 | yield return new WaitForSeconds(m_showTime); 45 | } 46 | if(m_currPos == m_currGoal) 47 | { 48 | Debug.LogError("到达目标"); 49 | yield break; 50 | } 51 | 52 | m_currStart = m_currPos; 53 | m_currGoal = m_mapGoal; 54 | m_km += c(oldGoal, m_currGoal); 55 | 56 | if (oldStart != m_currStart) 57 | { 58 | //BasicDeletion(oldStart); //Basic MT-D* Lite 59 | OptimizedDeletion(); //MT-D* Lite 60 | } 61 | 62 | HandleChangedNode(nearChanged); 63 | } 64 | 65 | yield break; 66 | } 67 | 68 | //因为起点和终点都会发生变化,因此没必要进行反向寻路 69 | protected override SearchNode BeginNode() 70 | { 71 | return m_currStart; 72 | } 73 | 74 | //因为起点和终点都会发生变化,因此没必要进行反向寻路 75 | protected override SearchNode EndNode() 76 | { 77 | return m_currGoal; 78 | } 79 | 80 | protected override void Initialize() 81 | { 82 | m_currGoal = m_mapGoal; 83 | 84 | base.Initialize(); 85 | } 86 | 87 | private void BasicDeletion(SearchNode oldStart) 88 | { 89 | m_currStart.SetRhs(m_currStart.Rhs, null); //新起点的parent(这里是rhsSource)要按照起点的要求设置为空 90 | UpdateVertex(oldStart); //将旧起点视为普通节点进行处理 91 | } 92 | 93 | /// 94 | /// 利用G-FRA* 的思想进行优化 95 | /// 尽早处理根不在当前起点的其他节点,而不是等到ComputeShortestPath再处理,因为那时就需要更多操作了 96 | /// 97 | private void OptimizedDeletion() 98 | { 99 | m_deleted.Clear(); 100 | BeginNode().SetRhs(BeginNode().Rhs, null); 101 | 102 | //类似FRA*的Step 2 103 | ForeachNode((s) => 104 | { 105 | //处理搜索树中不在根为当前起点的其他节点 106 | if(IsInSearchTree(s) && IsSubRoot(s, BeginNode()) == false) 107 | { 108 | s.SetRhs(c_large, null); 109 | s.G = c_large; 110 | RemoveFromOpenQueue(s); 111 | m_deleted.Add(s); 112 | } 113 | }); 114 | 115 | //类似FRA*的Step 4 116 | foreach(var s in m_deleted) 117 | { 118 | UpdateRhs(s); 119 | 120 | if (s.Rhs < c_large) 121 | { 122 | s.LPAKey = CalculateKey(s); 123 | AddOrUpdateOpenQueue(s); 124 | } 125 | } 126 | } 127 | 128 | /// 129 | /// 在OPEN或CLOSE的节点属于搜索树 130 | /// 131 | private bool IsInSearchTree(SearchNode s) 132 | { 133 | return s.Opened || s.RhsSource != null; 134 | } 135 | 136 | private bool IsSubRoot(SearchNode s, SearchNode subRoot) 137 | { 138 | if (s == subRoot) 139 | return true; 140 | 141 | while (s.Parent != null) 142 | { 143 | s = s.Parent; 144 | 145 | if (s == subRoot) 146 | return true; 147 | } 148 | 149 | return false; 150 | } 151 | 152 | private List GetPath() 153 | { 154 | List path = new List() { EndNode() }; 155 | 156 | SearchNode s = EndNode(); 157 | while(s.RhsSource != null) 158 | { 159 | s = s.RhsSource; 160 | if (s == BeginNode()) 161 | break; 162 | 163 | path.Add(s); 164 | } 165 | 166 | path.Reverse(); 167 | return path; 168 | } 169 | 170 | private void MoveOneStep(List path, List nearChanged) 171 | { 172 | m_currPos.SetSearchType(SearchType.Path, true); 173 | m_currPos = path[0]; 174 | path.RemoveAt(0); 175 | m_currPos.SetSearchType(SearchType.CurtPos, true); 176 | 177 | //假设检测器只能检查附近的点 178 | List neighbors = GetNeighbors(m_currPos); 179 | for (int i = 0; i < neighbors.Count; i++) 180 | { 181 | Vector2Int pos = neighbors[i].Pos; 182 | if (neighbors[i].Cost != m_foundMap[pos.y, pos.x]) 183 | { 184 | m_foundMap[pos.y, pos.x] = neighbors[i].Cost; 185 | nearChanged.Add(neighbors[i]); 186 | } 187 | } 188 | } 189 | 190 | #region 事件监听 191 | public override void NotifyChangeGoal(SearchNode goalNode) 192 | { 193 | m_mapGoal = goalNode; 194 | } 195 | #endregion 196 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Incremental/Moving Target/MT_DStarLite.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f3d3d64b742f8044ea03a99c09ea4dbc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/JPS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1c5a69b46626f643a95dbc756bbb629 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/JPS/JPSPlus.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcd3e7e521c0422418e037c73b4b39c4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/JPS/JumpPointSearch.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2777437dd2e04604e99dd267a5825a0d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Navmesh.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5fbad19a7389bc4fa7e3e305c705229 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Navmesh/NavmeshDemo.cs: -------------------------------------------------------------------------------- 1 | using Pathfinding.ClipperLib; 2 | using Pathfinding.Navmesh; 3 | using Pathfinding.Poly2Tri; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | 7 | public class NavmeshDemo : MonoBehaviour 8 | { 9 | private Material m_mat; 10 | 11 | void OnDrawGizmos() 12 | { 13 | if(m_mat == null) 14 | m_mat = new Material(Shader.Find("Unlit/Color")); 15 | 16 | List> walkablePolygons = new List>() 17 | { 18 | new List() 19 | { 20 | new IntPoint(10, 10), 21 | new IntPoint(600, 10), 22 | new IntPoint(600, 400), 23 | new IntPoint(10, 400), 24 | } 25 | }; 26 | 27 | List> blockedPolygons = new List>() 28 | { 29 | new List() 30 | { 31 | new IntPoint(100, 160), 32 | new IntPoint(150, 160), 33 | new IntPoint(200, 200), 34 | new IntPoint(130, 300), 35 | }, 36 | new List() 37 | { 38 | new IntPoint(220, 50), 39 | new IntPoint(260, 50), 40 | new IntPoint(260, 100), 41 | new IntPoint(220, 100), 42 | }, 43 | new List() 44 | { 45 | new IntPoint(300, 150), 46 | new IntPoint(350, 150), 47 | new IntPoint(350, 200), 48 | new IntPoint(300, 200), 49 | }, 50 | new List() 51 | { 52 | new IntPoint(400, 250), 53 | new IntPoint(450, 250), 54 | new IntPoint(450, 300), 55 | new IntPoint(400, 300), 56 | }, 57 | }; 58 | 59 | List triangles; 60 | var nodes = NavmeshGenerator.Generate(walkablePolygons, blockedPolygons, out triangles); 61 | 62 | //设置起点和终点 63 | DelaunayTriangle start = null, end = null; 64 | GraphNode startNode = null, endNode = null; 65 | float minX = float.MaxValue, maxX = 0; 66 | for(int i = 0; i < triangles.Count; i++) 67 | { 68 | var t = triangles[i]; 69 | var centroid = t.Centroid(); 70 | if(centroid.Xf < minX) 71 | { 72 | minX = centroid.Xf; 73 | start = t; 74 | startNode = nodes[i]; 75 | } 76 | if(centroid.Xf > maxX) 77 | { 78 | maxX = centroid.Xf; 79 | end = t; 80 | endNode = nodes[i]; 81 | } 82 | 83 | //鼠标所在三角形为终点 84 | if (IsTriangleContains(t, Input.mousePosition)) 85 | { 86 | maxX = float.MaxValue; 87 | end = t; 88 | endNode = nodes[i]; 89 | } 90 | } 91 | 92 | GraphAStar algo = new GraphAStar(startNode, endNode); 93 | algo.Process(); 94 | 95 | m_mat.SetColor("_Color", Color.black); 96 | for (int i = 0; i < blockedPolygons.Count; i++) 97 | DrawPolygon(blockedPolygons[i], true, true); 98 | 99 | m_mat.SetColor("_Color", Color.white); 100 | for (int i = 0; i < triangles.Count; i++) 101 | DrawTriangle(triangles[i], false); 102 | 103 | m_mat.SetColor("_Color", Color.yellow); 104 | DrawTriangle(start, false); 105 | DrawTriangle(end, false); 106 | 107 | List path = new List(); 108 | var node = endNode; 109 | while (node != null) 110 | { 111 | path.Add(node.Center); 112 | node = node.Parent; 113 | } 114 | 115 | m_mat.SetColor("_Color", Color.red); 116 | GraphicsTool.DrawPolygon(path, m_mat, false); 117 | } 118 | 119 | private static bool IsTriangleContains(DelaunayTriangle triangle, Vector2 pos) 120 | { 121 | var p0 = triangle.Points._0; 122 | var p1 = triangle.Points._1; 123 | var p2 = triangle.Points._2; 124 | 125 | var cross01 = (p1.Xf - p0.Xf) * (pos.y - p1.Yf) - (pos.x - p1.Xf) * (p1.Yf - p0.Yf); 126 | var cross12 = (p2.Xf - p1.Xf) * (pos.y - p2.Yf) - (pos.x - p2.Xf) * (p2.Yf - p1.Yf); 127 | var cross20 = (p0.Xf - p2.Xf) * (pos.y - p0.Yf) - (pos.x - p0.Xf) * (p0.Yf - p2.Yf); 128 | return (Mathf.Sign(cross01) == Mathf.Sign(cross12)) && (Mathf.Sign(cross01) == Mathf.Sign(cross20)); 129 | } 130 | 131 | void DrawPolygon(List polygon, bool isCCW, bool isFill) 132 | { 133 | List points = new List(); 134 | 135 | if (isCCW) 136 | { 137 | for(int i = polygon.Count - 1; i >= 0; i--) 138 | points.Add(new Vector2(polygon[i].X, polygon[i].Y)); 139 | } 140 | else 141 | { 142 | for (int i = 0; i < polygon.Count; i++) 143 | points.Add(new Vector2(polygon[i].X, polygon[i].Y)); 144 | } 145 | 146 | 147 | GraphicsTool.DrawPolygon(points, m_mat, true, isFill); 148 | } 149 | 150 | void DrawTriangle(DelaunayTriangle t, bool isFill = false) 151 | { 152 | if (t == null) 153 | return; 154 | 155 | var v0 = new Vector2(t.Points._0.Xf, t.Points._0.Yf); 156 | var v1 = new Vector2(t.Points._1.Xf, t.Points._1.Yf); 157 | var v2 = new Vector2(t.Points._2.Xf, t.Points._2.Yf); 158 | GraphicsTool.DrawTriangle(v2, v1, v0, m_mat, isFill); 159 | 160 | var centroid = t.Centroid(); 161 | GraphicsTool.DrawPoint(new Vector2(centroid.Xf, centroid.Yf), 3, m_mat); 162 | } 163 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Navmesh/NavmeshDemo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa0a75fddea8b914ab04492515337cd8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Navmesh/NavmeshGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using Pathfinding.ClipperLib; 4 | using Pathfinding.Poly2Tri; 5 | 6 | namespace Pathfinding.Navmesh 7 | { 8 | /// 9 | /// 简单的Navmesh生成器玩具,真正应用还得是业界标准RecastNavgation 10 | /// 11 | public class NavmeshGenerator 12 | { 13 | public static List Generate(List> walkablePolygons, List> blockedPolygons, out List triangles) 14 | { 15 | var polygons = ClipPolygons(walkablePolygons, blockedPolygons); 16 | triangles = GenerateTriangles(polygons); 17 | 18 | return TrianglesToNodes(triangles); 19 | } 20 | 21 | /// 22 | /// 将三角形转为图搜索节点 23 | /// 24 | private static List TrianglesToNodes(List triangles) 25 | { 26 | List result = new List(); 27 | 28 | var dict = new Dictionary(); 29 | for (int i = 0; i < triangles.Count; i++) 30 | { 31 | var centroid = triangles[i].Centroid(); 32 | var center = new Vector2(centroid.Xf, centroid.Yf); 33 | var node = new GraphNode(center); 34 | dict[triangles[i]] = node; 35 | result.Add(node); 36 | } 37 | 38 | for (int i = 0; i < triangles.Count; i++) 39 | { 40 | var t = triangles[i]; 41 | var node = result[i]; 42 | 43 | if (t.Neighbors._0 != null) 44 | { 45 | if (dict.TryGetValue(t.Neighbors._0, out GraphNode n)) 46 | node.AddNeighbor(n); 47 | } 48 | if (t.Neighbors._1 != null) 49 | { 50 | if (dict.TryGetValue(t.Neighbors._1, out GraphNode n)) 51 | node.AddNeighbor(n); 52 | } 53 | if (t.Neighbors._2 != null) 54 | { 55 | if (dict.TryGetValue(t.Neighbors._2, out GraphNode n)) 56 | node.AddNeighbor(n); 57 | } 58 | } 59 | 60 | return result; 61 | } 62 | 63 | /// 64 | /// 使用Clipper将阻挡裁剪出来 65 | /// 66 | private static List> ClipPolygons(List> walkablePolygons, List> blockedPolygons) 67 | { 68 | //合并可走区域 69 | List> result = new List>(); 70 | Clipper clipper = new Clipper(); 71 | clipper.AddPolygons(walkablePolygons, PolyType.ptClip); 72 | clipper.Execute(ClipType.ctUnion, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero); 73 | 74 | clipper.Clear(); 75 | 76 | //去掉不可走区域 77 | clipper.AddPolygons(result, PolyType.ptSubject); 78 | clipper.AddPolygons(blockedPolygons, PolyType.ptClip); 79 | clipper.Execute(ClipType.ctDifference, result); 80 | 81 | return result; 82 | } 83 | 84 | /// 85 | /// 使用Poly2Tri进行三角剖分 86 | /// 87 | /// 88 | /// 89 | private static List GenerateTriangles(List> polygons) 90 | { 91 | //根据时针方向判断可走区域和障碍 92 | var walkables = new List(); 93 | var blockeds = new List(); 94 | for (int i = 0; i < polygons.Count; i++) 95 | { 96 | var list = Convert(polygons[i]); 97 | if (IsCCW(polygons[i])) 98 | walkables.Add(new Polygon(list)); 99 | else 100 | blockeds.Add(new Polygon(list)); 101 | } 102 | 103 | //可以考虑添加SteinerPoint来避免生成狭长的三角形 104 | 105 | //三角剖分 106 | List triangles = new List(); 107 | for (int index = 0; index < walkables.Count; index++) 108 | { 109 | for (int i = 0; i < blockeds.Count; i++) 110 | walkables[index].AddHole(blockeds[i]); 111 | 112 | P2T.Triangulate(walkables[index]); 113 | triangles.AddRange(walkables[index].Triangles); 114 | } 115 | 116 | return triangles; 117 | } 118 | 119 | private static List Convert(List list) 120 | { 121 | List result = new List(); 122 | 123 | for (int i = 0; i < list.Count; i++) 124 | result.Add(new PolygonPoint(list[i].X, list[i].Y)); 125 | 126 | return result; 127 | } 128 | 129 | private static Vector2 Convert(TriangulationPoint p) 130 | { 131 | return new Vector2(p.Xf, p.Yf); 132 | } 133 | 134 | private static bool IsCCW(List polygon) 135 | { 136 | for (int i = 2; i < polygon.Count; i++) 137 | { 138 | var p0 = polygon[i - 2]; 139 | var p1 = polygon[i - 1]; 140 | var p2 = polygon[i]; 141 | 142 | var cross = (p1.X - p0.X) * (p2.Y - p1.Y) - (p2.X - p1.X) * (p1.Y - p0.Y); 143 | if (cross > 0) 144 | return true; 145 | else if (cross < 0) 146 | return false; 147 | } 148 | 149 | return false; //点都在一条直线上 150 | } 151 | 152 | struct Edge 153 | { 154 | public Vector2 v0; 155 | public Vector2 v1; 156 | 157 | public Edge(TriangulationPoint p0, TriangulationPoint p1) 158 | { 159 | v0 = Convert(p0); 160 | v1 = Convert(p1); 161 | } 162 | 163 | public override int GetHashCode() 164 | { 165 | return v0.GetHashCode() + v1.GetHashCode(); 166 | } 167 | } 168 | } 169 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Navmesh/NavmeshGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39a3bf2a6c3fbe648acacc1fe90a568a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/ThetaStar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57d1c3dbb63ba2343bcee605673c7b9c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/ThetaStar/LazyThetaStar.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | public class LazyThetaStar : ThetaStar 4 | { 5 | public LazyThetaStar(SearchNode start, SearchNode goal, SearchNode[,] nodes, float weight, float showTime) 6 | : base(start, goal, nodes, weight, showTime) 7 | { } 8 | 9 | protected override void ComputeCost(SearchNode curtNode, SearchNode nextNode) 10 | { 11 | //起点没有Parent,所以特殊处理为自己 12 | //原Paper将起点的父节点设置为起点,但我不喜欢图里有个自环,所以这样处理 13 | var parent = curtNode == m_mapStart ? m_mapStart : curtNode.Parent; 14 | 15 | //Path 2 16 | //假设都通过了LOS检查 17 | float newG = parent.G + c(parent, nextNode); 18 | if (newG < nextNode.G) 19 | nextNode.SetParent(parent, newG); 20 | } 21 | 22 | protected override void SetVertex(SearchNode node) 23 | { 24 | //起点没有Parent 25 | //原Paper将起点的父节点设置为起点,但我不喜欢图里有个自环,所以这样处理 26 | if (node == m_mapStart) 27 | return; 28 | 29 | if(LineOfSign(node.Parent, node) == false) 30 | { 31 | //Path 1 32 | //实际并没有通过LOS检查,就找已关闭邻居中最小的 33 | node.SetParent(null, float.MaxValue); 34 | 35 | List neighbors = GetNeighbors(node); 36 | for(int i = 0; i < neighbors.Count; i++) 37 | { 38 | SearchNode neighbor = neighbors[i]; 39 | if(neighbor.Closed) 40 | { 41 | float newG = neighbor.G + c(neighbor, node); 42 | if (newG < node.G) 43 | node.SetParent(neighbor, newG); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/ThetaStar/LazyThetaStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 103aaf23f7ea1674db33c47e04e1a88e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/ThetaStar/ThetaStar.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class ThetaStar : AStar 4 | { 5 | public ThetaStar(SearchNode start, SearchNode goal, SearchNode[,] nodes, float weight, float showTime) 6 | : base(start, goal, nodes, weight, showTime) 7 | { } 8 | 9 | protected override void ComputeCost(SearchNode curtNode, SearchNode nextNode) 10 | { 11 | if(LineOfSign(curtNode.Parent, nextNode)) 12 | { 13 | //Path 2 14 | float newG = curtNode.Parent.G + c(curtNode.Parent, nextNode); 15 | if (newG < nextNode.G) 16 | nextNode.SetParent(curtNode.Parent, newG); 17 | } 18 | else 19 | { 20 | //Path 1 21 | base.ComputeCost(curtNode, nextNode); 22 | } 23 | } 24 | 25 | protected bool LineOfSign(SearchNode startNode, SearchNode endNode) 26 | { 27 | if (startNode == null || endNode == null) 28 | return false; 29 | 30 | if (startNode == endNode) 31 | return true; 32 | 33 | Vector2Int start = startNode.Pos; 34 | Vector2Int end = endNode.Pos; 35 | int dx = end.x - start.x; 36 | int dy = end.y - start.y; 37 | int ux = dx > 0 ? 1 : -1; 38 | int uy = dy > 0 ? 1 : -1; 39 | int x = start.x; 40 | int y = start.y; 41 | int eps = 0; 42 | dx = Mathf.Abs(dx); 43 | dy = Mathf.Abs(dy); 44 | if(dx > dy) 45 | { 46 | for(x = start.x; x != end.x; x += ux) 47 | { 48 | if (GetNode(x, y).IsObstacle()) 49 | return false; 50 | 51 | eps += dy; 52 | if((eps << 1) >= dx) 53 | { 54 | if(x != start.x) //处理斜线移动的可移动性判断 55 | { 56 | //如果附近两个都是障碍,那么不可以走 57 | if (GetNode(x + ux, y).IsObstacle() && GetNode(x - ux, y + uy).IsObstacle()) 58 | return false; 59 | } 60 | 61 | y += uy; 62 | eps -= dx; 63 | } 64 | } 65 | } 66 | else 67 | { 68 | for(y = start.y; y != end.y; y += uy) 69 | { 70 | if (GetNode(x, y).IsObstacle()) 71 | return false; 72 | 73 | eps += dx; 74 | if((eps << 1) >= dy) 75 | { 76 | if(y != start.y) 77 | { 78 | if (GetNode(x, y + uy).IsObstacle() && GetNode(x + ux, y - uy).IsObstacle()) 79 | return false; 80 | } 81 | 82 | x += ux; 83 | eps -= dy; 84 | } 85 | } 86 | } 87 | 88 | return true; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/ThetaStar/ThetaStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0f4fbd9cae92e6439baf47676e74082 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Utils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e6f126a115072f9468fdb124ad9cfc6c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Utils/GraphicsTool.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: de5a99349f4ddd74d8d91369f832761d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/Utils/Utils.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public static class Utils 4 | { 5 | #region Vector2 6 | /// 7 | /// 假设圆心在原点,求出特定角度对应的圆边上的点 8 | /// 9 | /// 圆半径 10 | /// 所求角度 11 | /// 特定角度对应的圆边上的点 12 | public static Vector2 Polar(float radius, float angle) 13 | { 14 | return new Vector2(radius * Mathf.Cos(angle), radius * Mathf.Sin(angle)); 15 | } 16 | 17 | /// 18 | /// 假设圆心在start,求出特定角度对应的圆边上的点 19 | /// 20 | public static Vector2 DirectionStep(Vector2 start, float distance, float angle) 21 | { 22 | return start + Polar(distance, angle); 23 | } 24 | 25 | public static float Cross(Vector2 p, Vector2 q) 26 | { 27 | return p.x * q.y - p.y * q.x; 28 | } 29 | 30 | /// 31 | /// 向量 p->q 与x轴正向的夹角 32 | /// 33 | public static float Facing(Vector2 p, Vector2 q) 34 | { 35 | float dx = q.x - p.x; 36 | float dy = q.y - p.y; 37 | return Mathf.Atan2(dy, dx); 38 | } 39 | 40 | public static Vector2 Interpolate(Vector2 p, Vector2 q, float t) 41 | { 42 | float x = p.x + (q.x - p.x) * t; 43 | float y = p.y + (q.y - p.y) * t; 44 | return new Vector2(x, y); 45 | } 46 | #endregion 47 | 48 | #region 交点 49 | public static bool SegmentCircleIntersection(Vector2 a, Vector2 b, Vector2 center, float radius) 50 | { 51 | float u = Vector2.Dot(center - a, b - a) / Vector2.Dot(b - a, b - a); 52 | Vector2 e = a + Mathf.Clamp01(u) * (b - a); 53 | float d = Vector2.Distance(e, center); 54 | return Vector2.Distance(e, center) < radius; 55 | } 56 | #endregion 57 | 58 | public static float AngleDifference(float a, float b) 59 | { 60 | return Mathf.Abs(b - a) % (2 * Mathf.PI); 61 | } 62 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/Utils/Utils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dce7572f2280aab4da7735c012b1152a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4d2674a5b6ad4d446b8d52cc08dbe6f1 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/CircleObstacles.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: db574af3815a7b043b037fd136ca3887 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/CircleObstacles/CircleGraphAStar.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Pathfinding.VisibilityGraph 4 | { 5 | public class CircleGraphAStar : GraphAStar 6 | { 7 | public CircleGraphAStar(CircleGraphNode startNode, CircleGraphNode endNode) : base(startNode, endNode) { } 8 | 9 | protected override void ComputeCost(GraphNode curtNode, GraphNode nextNode) 10 | { 11 | float cost = curtNode.G + EdgeCost(curtNode, nextNode); 12 | if (cost < nextNode.G) 13 | nextNode.SetParent(curtNode, cost); 14 | } 15 | 16 | private float EdgeCost(GraphNode n1, GraphNode n2) 17 | { 18 | var a = n1 as CircleGraphNode; 19 | var b = n2 as CircleGraphNode; 20 | 21 | if(a.BelongCircle != null && a.BelongCircle == b.BelongCircle) 22 | { 23 | var circle = a.BelongCircle; 24 | float aAngle = Utils.Facing(circle.center, a.Center); 25 | float bAngle = Utils.Facing(circle.center, b.Center); 26 | float deltaAngle = Utils.AngleDifference(aAngle, bAngle); 27 | return deltaAngle * circle.radius; 28 | } 29 | else 30 | { 31 | return Vector2.Distance(a.Center, b.Center); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/CircleObstacles/CircleGraphAStar.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 864dc0ec7887efd48aa0c556ccceab50 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/CircleObstacles/CircleGraphNode.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Pathfinding.VisibilityGraph 4 | { 5 | public class CircleGraphNode : GraphNode 6 | { 7 | public Circle BelongCircle { get; private set; } 8 | 9 | public CircleGraphNode(Vector2 center, Circle c) : base(center) 10 | { 11 | BelongCircle = c; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/CircleObstacles/CircleGraphNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b9a5c01ed107e4488490406cd410e71 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/CircleObstacles/CircleVisibilityGraphDemo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8524a00d9e25ae24f8791bb581d3fccf 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/CircleObstacles/CircleVisibilityGraphGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d776e5b8c57b2374880537de419fff6a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/VisibilityGraphDemo.cs: -------------------------------------------------------------------------------- 1 | using Pathfinding.VisibilityGraph; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class VisibilityGraphDemo : MonoBehaviour 6 | { 7 | private Material m_mat; 8 | private Vector2 m_start = new Vector2(50, 10); 9 | private Vector2 m_end = new Vector2(300, 300); 10 | 11 | void Update() 12 | { 13 | if (Input.GetMouseButtonDown(0)) 14 | m_start = Input.mousePosition; 15 | else if (Input.GetMouseButtonDown(1)) 16 | m_end = Input.mousePosition; 17 | } 18 | 19 | void OnDrawGizmos() 20 | { 21 | if (m_mat == null) 22 | m_mat = new Material(Shader.Find("Unlit/Color")); 23 | 24 | m_mat.SetColor("_Color", Color.black); 25 | List obstacles = new List() 26 | { 27 | new Polygon(new Vector2[] 28 | { 29 | new Vector2(100, 50), 30 | new Vector2(100, 100), 31 | new Vector2(180, 100), 32 | new Vector2(180, 50), 33 | }), 34 | new Polygon(new Vector2[] 35 | { 36 | new Vector2(250, 120), 37 | new Vector2(230, 140), 38 | new Vector2(250, 160), 39 | new Vector2(290, 150), 40 | }), 41 | new Polygon(new Vector2[] 42 | { 43 | new Vector2(90, 130), 44 | new Vector2(70, 150), 45 | new Vector2(110, 150), 46 | }), 47 | new Polygon(new Vector2[] 48 | { 49 | new Vector2(150, 200), 50 | new Vector2(150, 250), 51 | new Vector2(280, 250), 52 | new Vector2(280, 200), 53 | }), 54 | }; 55 | for(int i = 0; i < obstacles.Count; i++) 56 | GraphicsTool.DrawPolygon(obstacles[i].Points, m_mat, true, true); 57 | 58 | m_mat.SetColor("_Color", Color.yellow); 59 | List nodes = VisibilityGraphGenerator.Generate(m_start, m_end, obstacles); 60 | for(int a = 0; a < nodes.Count; a++) 61 | { 62 | var n = nodes[a]; 63 | GraphicsTool.DrawPoint(nodes[a].Center, 3, m_mat); 64 | for (int i = 0; i < n.Neighbors.Count; i++) 65 | GraphicsTool.DrawLine(n.Center, n.Neighbors[i].Center, m_mat); 66 | } 67 | 68 | m_mat.SetColor("_Color", Color.red); 69 | GraphicsTool.DrawPoint(m_start, 4, m_mat); 70 | GraphicsTool.DrawPoint(m_end, 4, m_mat); 71 | GraphNode startNode = nodes[nodes.Count - 2]; 72 | GraphNode endNode = nodes[nodes.Count - 1]; 73 | GraphAStar astar = new GraphAStar(startNode, endNode); 74 | astar.Process(); 75 | List path = new List(); 76 | while (endNode != null) 77 | { 78 | path.Add(endNode.Center); 79 | endNode = endNode.Parent; 80 | } 81 | GraphicsTool.DrawPolygon(path, m_mat, false); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/VisibilityGraphDemo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cd8894d677d0364a9ee127481c40e50 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/VisibilityGraphGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Pathfinding.VisibilityGraph 5 | { 6 | /// 7 | /// 生成可见性图 8 | /// 参考: 9 | /// * 简单介绍:http://www.cs.kent.edu/~dragan/ST-Spring2016/visibility%20graphs.pdf 10 | /// * Lee's O(n^2 logn)算法:《计算几何算法与应用》第15章、http://dav.ee/papers/Visibility_Graph_Algorithm.pdf 11 | /// * Ghosh等人发明了 O(|e| + n logn)的算法 12 | /// * Reduced Visibility Graph:可以去掉中间一些多余的线段,简化整张寻路图 13 | /// 14 | public class VisibilityGraphGenerator 15 | { 16 | public static List Generate(Vector2 start, Vector2 end, List obstalces) 17 | { 18 | return BruteForce(start, end, obstalces); 19 | } 20 | 21 | #region 蛮力算法 22 | /// 23 | /// 蛮力:直接两两判断 24 | /// 复杂度:O(n^3) 25 | /// 26 | private static List BruteForce(Vector2 start, Vector2 end, List obstacles) 27 | { 28 | List result = new List(); 29 | 30 | //生成所有节点 31 | for (int m = 0; m < obstacles.Count; m++) 32 | { 33 | var polygon = obstacles[m]; 34 | for (int i = 0; i < polygon.Points.Length; i++) 35 | result.Add(new GraphNode(polygon.Points[i])); 36 | } 37 | result.Add(new GraphNode(start)); 38 | result.Add(new GraphNode(end)); 39 | 40 | //两两判断顶点是否直接可见 41 | for (int u = 0; u < result.Count; u++) 42 | { 43 | var node1 = result[u]; 44 | for (int v = u + 1; v < result.Count; v++) 45 | { 46 | var node2 = result[v]; 47 | Line line = new Line(node1.Center, node2.Center); 48 | 49 | bool isIntersect = false; 50 | for (int w = 0; w < obstacles.Count; w++) 51 | { 52 | if (obstacles[w].IsIntersect(line)) 53 | { 54 | isIntersect = true; 55 | break; 56 | } 57 | } 58 | 59 | if (!isIntersect) 60 | { 61 | node1.AddNeighbor(node2); 62 | node2.AddNeighbor(node1); 63 | } 64 | } 65 | } 66 | 67 | return result; 68 | } 69 | #endregion 70 | } 71 | 72 | public struct Polygon 73 | { 74 | public readonly Vector2[] Points; 75 | private readonly Dictionary PointDict; 76 | 77 | public Polygon(Vector2[] arr) 78 | { 79 | Points = arr; 80 | 81 | PointDict = new Dictionary(); 82 | for (int i = 0; i < arr.Length; i++) 83 | PointDict[arr[i]] = i; 84 | } 85 | 86 | /// 87 | /// 障碍是开放集,即其边缘不视为障碍 88 | /// 89 | public bool IsIntersect(Line other) 90 | { 91 | //处理线段在障碍内部的特殊情况 92 | int aIndex, bIndex; 93 | if (PointDict.TryGetValue(other.a, out aIndex) && PointDict.TryGetValue(other.b, out bIndex)) 94 | return Mathf.Abs(aIndex - bIndex) != 1; 95 | 96 | //线段在障碍外部的正常情况 97 | for (int i = 0; i < Points.Length - 1; i++) 98 | { 99 | Line line = new Line(Points[i], Points[i + 1]); 100 | if (line.IsIntersect(other)) 101 | return true; 102 | } 103 | Line last = new Line(Points[0], Points[Points.Length - 1]); 104 | return last.IsIntersect(other); 105 | } 106 | } 107 | 108 | public struct Line 109 | { 110 | public Vector2 b; 111 | public Vector2 a; 112 | 113 | public Line(Vector2 a, Vector2 b) 114 | { 115 | this.a = a; 116 | this.b = b; 117 | } 118 | 119 | public bool IsIntersect(Line other) 120 | { 121 | Vector2 c = other.a, d = other.b; 122 | 123 | float u = (c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y); 124 | float v = (d.x - a.x) * (b.y - a.y) - (b.x - a.x) * (d.y - a.y); 125 | float w = (a.x - c.x) * (d.y - c.y) - (d.x - c.x) * (a.y - c.y); 126 | float z = (b.x - c.x) * (d.y - c.y) - (d.x - c.x) * (b.y - c.y); 127 | return u * v < 0 && w*z < 0; 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /Project/Assets/Scripts/VisibilityGraph/VisibilityGraphGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f098c937be5308429e61b9e32f67469 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Project/Assets/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 76b587748f052884ebeaada65a6a5e68 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Shaders/TransparentColor.shader: -------------------------------------------------------------------------------- 1 | Shader "Unlit/TransparentColor" 2 | { 3 | Properties 4 | { 5 | _Color("Color", Color) = (1,1,1,1) 6 | _MainTex("Texture", 2D) = "white" {} 7 | } 8 | SubShader 9 | { 10 | ZWrite Off 11 | Tags { "Queue"="Transparent" } 12 | 13 | Pass 14 | { 15 | Blend SrcAlpha OneMinusSrcAlpha 16 | 17 | CGPROGRAM 18 | #pragma vertex vert 19 | #pragma fragment frag 20 | 21 | #include "UnityCG.cginc" 22 | 23 | struct appdata 24 | { 25 | float4 vertex : POSITION; 26 | float2 uv : TEXCOORD0; 27 | }; 28 | 29 | struct v2f 30 | { 31 | float2 uv : TEXCOORD0; 32 | float4 vertex : SV_POSITION; 33 | }; 34 | 35 | sampler2D _MainTex; 36 | float4 _MainTex_ST; 37 | float4 _Color; 38 | 39 | v2f vert (appdata v) 40 | { 41 | v2f o; 42 | o.vertex = UnityObjectToClipPos(v.vertex); 43 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 44 | return o; 45 | } 46 | 47 | fixed4 frag(v2f i) : SV_Target 48 | { 49 | fixed4 col = tex2D(_MainTex, i.uv); 50 | return _Color * col; 51 | } 52 | ENDCG 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Project/Assets/Shaders/TransparentColor.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5e05940326c3a514b997f7d02516a058 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Project/Assets/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b97844355d191224fab11dd27e8cbeed 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Project/Assets/Textures/Rect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KaimaChen/Pathfinding/ee1010d13f7b2a87f4fe2806de660cb5e81f0fd1/Project/Assets/Textures/Rect.png -------------------------------------------------------------------------------- /Project/Assets/Textures/Rect.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3216cead1acc3c847b73eb08085b7dc7 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 10 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 3 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | forceMaximumCompressionQuality_BC6H_BC7: 0 73 | spriteSheet: 74 | serializedVersion: 2 75 | sprites: [] 76 | outline: [] 77 | physicsShape: [] 78 | bones: [] 79 | spriteID: 80 | internalID: 0 81 | vertices: [] 82 | indices: 83 | edges: [] 84 | weights: [] 85 | secondaryTextures: [] 86 | spritePackingTag: 87 | pSDRemoveMatte: 0 88 | pSDShowRemoveMatteOption: 0 89 | userData: 90 | assetBundleName: 91 | assetBundleVariant: 92 | -------------------------------------------------------------------------------- /Project/Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.collab-proxy": "1.2.16", 4 | "com.unity.ide.rider": "1.1.4", 5 | "com.unity.ide.vscode": "1.1.4", 6 | "com.unity.test-framework": "1.1.9", 7 | "com.unity.textmeshpro": "2.0.1", 8 | "com.unity.timeline": "1.2.10", 9 | "com.unity.ugui": "1.0.0", 10 | "com.unity.modules.ai": "1.0.0", 11 | "com.unity.modules.androidjni": "1.0.0", 12 | "com.unity.modules.animation": "1.0.0", 13 | "com.unity.modules.assetbundle": "1.0.0", 14 | "com.unity.modules.audio": "1.0.0", 15 | "com.unity.modules.cloth": "1.0.0", 16 | "com.unity.modules.director": "1.0.0", 17 | "com.unity.modules.imageconversion": "1.0.0", 18 | "com.unity.modules.imgui": "1.0.0", 19 | "com.unity.modules.jsonserialize": "1.0.0", 20 | "com.unity.modules.particlesystem": "1.0.0", 21 | "com.unity.modules.physics": "1.0.0", 22 | "com.unity.modules.physics2d": "1.0.0", 23 | "com.unity.modules.screencapture": "1.0.0", 24 | "com.unity.modules.terrain": "1.0.0", 25 | "com.unity.modules.terrainphysics": "1.0.0", 26 | "com.unity.modules.tilemap": "1.0.0", 27 | "com.unity.modules.ui": "1.0.0", 28 | "com.unity.modules.uielements": "1.0.0", 29 | "com.unity.modules.umbra": "1.0.0", 30 | "com.unity.modules.unityanalytics": "1.0.0", 31 | "com.unity.modules.unitywebrequest": "1.0.0", 32 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 33 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 34 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 35 | "com.unity.modules.unitywebrequestwww": "1.0.0", 36 | "com.unity.modules.vehicles": "1.0.0", 37 | "com.unity.modules.video": "1.0.0", 38 | "com.unity.modules.vr": "1.0.0", 39 | "com.unity.modules.wind": "1.0.0", 40 | "com.unity.modules.xr": "1.0.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Project/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Volume: 1 8 | Rolloff Scale: 1 9 | Doppler Factor: 1 10 | Default Speaker Mode: 2 11 | m_SampleRate: 0 12 | m_DSPBufferSize: 1024 13 | m_VirtualVoiceCount: 512 14 | m_RealVoiceCount: 32 15 | m_SpatializerPlugin: 16 | m_AmbisonicDecoderPlugin: 17 | m_DisableAudio: 0 18 | m_VirtualizeEffects: 1 19 | m_RequestedDSPBufferSize: 1024 20 | -------------------------------------------------------------------------------- /Project/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /Project/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 11 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 0 23 | m_ReuseCollisionCallbacks: 1 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | m_FrictionType: 0 32 | m_EnableEnhancedDeterminism: 0 33 | m_EnableUnifiedHeightmaps: 1 34 | m_DefaultMaxAngluarSpeed: 7 35 | -------------------------------------------------------------------------------- /Project/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: [] 8 | m_configObjects: {} 9 | -------------------------------------------------------------------------------- /Project/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 0 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 1 16 | m_EtcTextureFastCompressor: 1 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 4 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInEditMode: 1 24 | m_EnableTextureStreamingInPlayMode: 1 25 | m_AsyncShaderCompilation: 1 26 | m_EnterPlayModeOptionsEnabled: 0 27 | m_EnterPlayModeOptions: 3 28 | m_ShowLightmapResolutionOverlay: 1 29 | m_UseLegacyProbeSampleCount: 1 30 | m_AssetPipelineMode: 1 31 | m_CacheServerMode: 0 32 | m_CacheServerEndpoint: 33 | m_CacheServerNamespacePrefix: default 34 | m_CacheServerEnableDownload: 1 35 | m_CacheServerEnableUpload: 1 36 | -------------------------------------------------------------------------------- /Project/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 13 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | m_PreloadedShaders: [] 39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 40 | type: 0} 41 | m_CustomRenderPipeline: {fileID: 0} 42 | m_TransparencySortMode: 0 43 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 44 | m_DefaultRenderingPath: 1 45 | m_DefaultMobileRenderingPath: 1 46 | m_TierSettings: [] 47 | m_LightmapStripping: 0 48 | m_FogStripping: 0 49 | m_InstancingStripping: 0 50 | m_LightmapKeepPlain: 1 51 | m_LightmapKeepDirCombined: 1 52 | m_LightmapKeepDynamicPlain: 1 53 | m_LightmapKeepDynamicDirCombined: 1 54 | m_LightmapKeepShadowMask: 1 55 | m_LightmapKeepSubtractive: 1 56 | m_FogKeepLinear: 1 57 | m_FogKeepExp: 1 58 | m_FogKeepExp2: 1 59 | m_AlbedoSwatchInfos: [] 60 | m_LightsUseLinearIntensity: 0 61 | m_LightsUseColorTemperature: 0 62 | m_LogWhenShaderIsCompiled: 0 63 | m_AllowEnlightenSupportForUpgradedProject: 0 64 | -------------------------------------------------------------------------------- /Project/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /Project/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_AutoSimulation: 1 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 1 46 | m_AutoSyncTransforms: 0 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /Project/ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_DefaultPresets: {} 8 | -------------------------------------------------------------------------------- /Project/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2019.3.0f6 2 | m_EditorVersionWithRevision: 2019.3.0f6 (27ab2135bccf) 3 | -------------------------------------------------------------------------------- /Project/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /Project/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /Project/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /Project/ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_StripUpdateShader: {fileID: 0} 10 | m_RenderPipeSettingsPath: 11 | m_FixedTimeStep: 0.016666668 12 | m_MaxDeltaTime: 0.05 13 | -------------------------------------------------------------------------------- /Project/ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pathfinding 2 | Many pathfinding algorithm 3 | 4 | 5 | 6 | ## Contents 7 | 8 | * 【Data Structure】 9 | * Grid 10 | * Navmesh 11 | * Visibility Graph 12 | * CircleVisibilityGraph 13 | 14 | 15 | 16 | * 【Basic】 17 | * A* 18 | * BFS 19 | * Dijkstra 20 | * 【Bidirectional Search】 21 | * Bidirection A* 22 | * 【Any-Angle Search】 23 | * Theta* 24 | * Lazy Theta* 25 | * 【Incremental Search】 26 | * D* 27 | * LPA* 28 | * D* Lite 29 | * Path Adaptive A* 30 | * Tree Adaptive A* 31 | * 【Moving Target】 32 | * Generalized Adaptive A* (GAA*) 33 | * Generalized Fringe-Retrieving A* (G-FRA*) 34 | * Moving Target D* Lite (MT-D* Lite) 35 | * 【Hierarchical Search】 36 | * HPA* 37 | * 【Other Search】 38 | * Flow Field 39 | * Jump Point Search 40 | - JPS Plus 41 | 42 | 43 | 44 | ## How to play 45 | 46 | ### Choose scene 47 | 48 | * [HPA] scene for HPA* algorithm, press space key to run the algorithm. 49 | * [Pathfinding] scene for other search algorithm, select GameObject [Search], choose algorithm in Inspector, press space key to run the algorithm. 50 | * [FlowField] scene for flowfield algorithm, you can see the result immediately without any operation. 51 | 52 | ### Handle grid 53 | 54 | - You can drag the start and goal node 55 | - Left click can add obstacle 56 | - Right click can remove obstacle 57 | 58 | 59 | 60 | ## Reference 61 | 62 | [Github PathFinding.js](https://github.com/qiao/PathFinding.js) 63 | 64 | [Github HierarchicalPathfinder](https://github.com/Rydra/HierarchicalPathfinder) 65 | --------------------------------------------------------------------------------