当前位置:网站首页>Unity a* road finding force planning
Unity a* road finding force planning
2022-06-30 04:48:00 【Your wig classmate Z】
Unity A* Pathfinding
namespace AStar
{
// Lattice type
public enum AStarType
{
WALK,
STOP
}
public class AStarNode
{
public AStarNode() { }
public AStarNode(int x, int y, AStarType type)
{
this.x = x;
this.y = y;
this.type = type;
}
// Parent lattice
public AStarNode father;
// Grid location
public int x;
public int y;
//public Vector2 pos;
// Map grid type
public AStarType type;
// Pathfinding costs Euler distance + Manhattan distance
public float f;
// Distance from starting point Euler distance
public float g;
// Distance from the end point Manhattan distance
public float h;
// Reset node information
public void ResetNode()
{
this.father = null;
this.f = 0;
this.g = 0;
this.h = 0;
}
}
}
using System.Collections.Generic;
using UnityEngine;
namespace AStar
{
public class AStarMgr
{
private static AStarMgr instance = new AStarMgr();
public static AStarMgr Instance { get => instance; set => instance = value; }
private int mapW;
private int mapH;
// Map information
public AStarNode[,] nodes;
// Open list
private List<AStarNode> openList;
// Close list
private List<AStarNode> closeList;
private List<AStarNode> path = new List<AStarNode>();
// Load map information
public void InitMaps(int w, int h)
{
mapW = w;
mapH = h;
openList = new List<AStarNode>();
closeList = new List<AStarNode>();
nodes = new AStarNode[w, h];
for (var i = 0; i < w; i++)
{
for (var j = 0; j < h; j++)
{
var node = new AStarNode(i, j, Random.Range(0, 100) < 20 ? AStarType.STOP : AStarType.WALK);
nodes[i, j] = node;
}
}
}
// Pathfinding
public List<AStarNode> FindPath(Vector2 startPos, Vector2 endPos)
{
var startNode = GetNode(startPos);
var endNode = GetNode(endPos);
if (!CheckNode(startNode.x, startNode.y) || !CheckNode(endNode.x, endNode.y) || !CheckType(startNode) || !CheckType(endNode)) return null;
startNode.ResetNode();
openList.Clear();
closeList.Clear();
AddCloseList(startNode);
while (true)
{
FineNearNodeToOpenList((int)startNode.x - 1, (int)startNode.y - 1, 1.4f, startNode, endNode);
FineNearNodeToOpenList((int)startNode.x, (int)startNode.y - 1, 1f, startNode, endNode);
FineNearNodeToOpenList((int)startNode.x + 1, (int)startNode.y - 1, 1.4f, startNode, endNode);
FineNearNodeToOpenList((int)startNode.x - 1, (int)startNode.y, 1f, startNode, endNode);
FineNearNodeToOpenList((int)startNode.x + 1, (int)startNode.y, 1f, startNode, endNode);
FineNearNodeToOpenList((int)startNode.x - 1, (int)startNode.y + 1, 1.4f, startNode, endNode);
FineNearNodeToOpenList((int)startNode.x, (int)startNode.y + 1, 1f, startNode, endNode);
FineNearNodeToOpenList((int)startNode.x + 1, (int)startNode.y + 1, 1.4f, startNode, endNode);
// Dead end
if (openList.Count == 0) return null;
openList.Sort(SortOpenList);
AddCloseList(openList[0]);
startNode = openList[0];
openList.RemoveAt(0);
if (startNode == endNode)
{
path.Clear();
path.Add(endNode);
while (endNode.father != null)
{
path.Add(endNode.father);
endNode = endNode.father;
}
path.Reverse();
return path;
}
}
}
// Get the corresponding... From the map information AStarNode
private AStarNode GetNode(Vector2 pos)
{
return nodes[(int)pos.x, (int)pos.y];
}
// Judge legally
private bool CheckNode(int x, int y)
{
// In scope
if (x < 0 || x >= mapW || y < 0 || y >= mapH) return false;
return true;
}
// Judgment type
private bool CheckType(AStarNode node)
{
if (node.type == AStarType.WALK) return true;
return false;
}
// Add to open list
private void AddOpenList(AStarNode node)
{
if (!openList.Contains(node))
openList.Add(node);
}
// Add to close list
private void AddCloseList(AStarNode node)
{
if (!closeList.Contains(node))
closeList.Add(node);
}
// Get the surrounding points and add them to the open list
private void FineNearNodeToOpenList(int x, int y, float g, AStarNode father, AStarNode end)
{
if (!CheckNode(x, y)) return;
var tempNode = nodes[x, y];
if (tempNode == null || !CheckType(tempNode) || openList.Contains(tempNode) || closeList.Contains(tempNode))
return;
// Calculate pathfinding consumption
tempNode.father = father;
tempNode.g = father.g + g;
tempNode.h = Mathf.Abs(end.x - tempNode.x) + Mathf.Abs(end.y - tempNode.y);
tempNode.f = tempNode.g + tempNode.h;
openList.Add(tempNode);
}
private int SortOpenList(AStarNode a, AStarNode b)
{
if (a.f > b.f) return 1;
else return -1;
}
}
}
using System.Collections.Generic;
using UnityEngine;
namespace AStar
{
public class AStarTest : MonoBehaviour
{
public int BeginX = 3;
public int BeginY = -5;
public int MapW = 5;
public int MapH = 5;
public int OffetX = 2;
public int OffetY = 2;
private Vector2 beginPos = Vector2.right * -1;
private Dictionary<string, GameObject> cubes = new Dictionary<string, GameObject>();
private List<AStarNode> path;
private void Start()
{
path = new List<AStarNode>();
AStarMgr.Instance.InitMaps(MapW, MapH);
for (int i = 0; i < MapW; i++)
{
for (int j = 0; j < MapH; j++)
{
var obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
obj.transform.position = new Vector3(BeginX + i * OffetX, BeginY + j * OffetY, 0);
obj.name = i + "_" + j;
cubes.Add(obj.name, obj);
var node = AStarMgr.Instance.nodes[i, j];
if (node.type == AStarType.STOP)
{
obj.GetComponent<MeshRenderer>().material.color = Color.red;
}
}
}
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit hitInfo;
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hitInfo, 1000))
{
if (beginPos == Vector2.right * -1)
{
if (path != null)
{
foreach (var item in path)
{
cubes[item.x + "_" + item.y].GetComponent<MeshRenderer>().material.color = Color.white;
}
}
string[] strs = hitInfo.collider.gameObject.name.Split('_');
beginPos = new Vector2(int.Parse(strs[0]), int.Parse(strs[1]));
hitInfo.collider.gameObject.GetComponent<MeshRenderer>().material.color = Color.yellow;
}
else
{
string[] strs = hitInfo.collider.gameObject.name.Split('_');
var endPos = new Vector2(int.Parse(strs[0]), int.Parse(strs[1]));
hitInfo.collider.gameObject.GetComponent<MeshRenderer>().material.color = Color.green;
// Pathfinding
path = AStarMgr.Instance.FindPath(beginPos, endPos);
if (path != null)
{
foreach (var item in path)
{
cubes[item.x + "_" + item.y].GetComponent<MeshRenderer>().material.color = Color.green;
}
}
beginPos = Vector2.right * -1;
}
}
}
}
}
}
边栏推荐
- 【Paper】2020_ Research on defense and evaluation strategy of heterogeneous UAV formation_ Zuojiankai
- QT creator 8 beta2 release
- 為什麼win10開熱點後電腦沒有網絡?
- Connect to the database and run node JS running database shows that the database is missing
- Brew install NVM command not found solution
- Malignant bug: 1252 of unit MySQL export
- One interview question a day - the underlying implementation of synchronize and the lock upgrade process
- File system and directory operations
- [control] multi agent system summary. 5. system consolidation.
- My idea configuration
猜你喜欢

Arsenal Stadium Tour - take you to the front and back of Arsenal Stadium

What is multimodal interaction?

Connect to the database and run node JS running database shows that the database is missing

EasyRecovery数据恢复软件 恢复了我两年前的照片视频数据

Imile uses Zadig's multi cloud environment to deploy thousands of times a week to continuously deliver global business across clouds and regions

Transport layer protocol tcp/udp

什么是光耦电路,实际使用中应该注意些什么?

PBR material: basic principle and simple fabrication

SCM learning notes: interrupt learning

Window10 jar double click to run without response
随机推荐
【Paper】2016_ A Learning-Based Fault Tolerant Tracking Control of an Unmanned Quadrotor Helicopter
Unreal 4 learning notes - data storage using blueprints
力扣292周赛题解
How to renew an SSL certificate
My idea configuration
Unreal 4 learning notes - Animated Montage
【Paper】2019_ Distributed Cooperative Control of a High-speed Train
Bean creation process and lazy init delay loading mechanism
Imile uses Zadig's multi cloud environment to deploy thousands of times a week to continuously deliver global business across clouds and regions
Redis实现短信登入功能(二)Redis实现登入功能
力扣周赛293题解
Connect to the database and run node JS running database shows that the database is missing
What is an optocoupler circuit and what should be paid attention to in actual use?
PS1 Contemporary Art Center, Museum of modern art, New York
史上最全的Redis基础+进阶项目实战总结笔记
破局存量客群营销,试一下客户分群管理(含聚类模型等实操效果评估)
Threejs realizes the simulation of river, surface flow, pipe flow and sea surface
Tea mall system based on SSM framework [project source code + database script + report]
Bean创建流程 与 lazy-init 延迟加载机制原理
Redis implements SMS login function (II) redis implements login function