本文共 7688 字,大约阅读时间需要 25 分钟。
链接:https://pan.baidu.com/s/15j770Uf5IVp3lDskSI-0TA 密码:xq10
using System.Collections;using System.Collections.Generic;using UnityEngine;////// 格子的类型/// public enum NodeType{ Walk, Stop,}////// 格子类/// public class AStarNode{ //格子的坐标 public int x; public int y; //寻路消耗 public float f; //距离起点的距离 public float g; //距离终点的距离(曼哈顿距离) public float h; //格子的父物体 public AStarNode Father; //格子的类型 public NodeType Type; public AStarNode(int x,int y,NodeType nodeType) { this.x = x; this.y = y; this.Type = nodeType; } }
using System.Collections;using System.Collections.Generic;using UnityEngine;////// 格子管理器/// public class AStarMgr { private AStarMgr() { } private static AStarMgr _instance; public static AStarMgr Instance { get { if (_instance==null) { _instance=new AStarMgr(); } return _instance; } } //地图的宽高 private int mapW; private int mapH; //地图相关所有的格子对象容器 public AStarNode[,] nodes; //开启列表 private ListopenList=new List (); //关闭列表 private List closeList=new List (); public void InitMapInfo(int w,int h) { this.mapW = w; this.mapH = h; nodes=new AStarNode[w,h]; for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { AStarNode node=new AStarNode(i,j,UnityEngine.Random.Range(0,100)<20?NodeType.Stop:NodeType.Walk); nodes[i, j] = node; } } } //寻路方法 public List FindPath(Vector2 startPos, Vector2 endPos) { //首先判断传入的点上方合法 //01. 在地图的范围内 if (startPos.x < 0 || startPos.x >= mapW || startPos.y < 0 || startPos.y >= mapH) { return null; } if (endPos.x<0||endPos.x>=mapW||endPos.y<0||endPos.y>=mapH) { return null; } //02.不是阻挡 //得到起点和终点对应的格子 AStarNode start = nodes[(int)startPos.x, (int)startPos.y]; AStarNode end = nodes[(int)endPos.x, (int)endPos.y]; //如果不合法,自己返回为空不能寻路 if (start.Type==NodeType.Stop||end.Type== NodeType.Stop) { return null; } //清空开启和关闭列表 上一次寻路的数据给清除掉 openList.Clear(); closeList.Clear(); //将开始点放入关闭列表 start.Father = null; start.f = 0; start.g = 0; start.h = 0; closeList.Add(start); while (true) { //从起点开始 找周围的点 并放入开启列表中 //左上 x-1 y-1 FinNearlyNodeToOpenList(start.x - 1, start.y - 1, 1.4f, start, end); //上 x y-1 FinNearlyNodeToOpenList(start.x, start.y - 1, 1f, start, end); //右上 x+1 y-1 FinNearlyNodeToOpenList(start.x + 1, start.y - 1, 1.4f, start, end); //左 x-1 y FinNearlyNodeToOpenList(start.x - 1, start.y, 1f, start, end); //右 x+1 y FinNearlyNodeToOpenList(start.x + 1, start.y, 1f, start, end); //左下 x-1 y+1 FinNearlyNodeToOpenList(start.x - 1, start.y + 1, 1.4f, start, end); //下 x y+1 FinNearlyNodeToOpenList(start.x, start.y + 1, 1f, start, end); //右下 x+1 y+1 FinNearlyNodeToOpenList(start.x + 1, start.y + 1, 1.4f, start, end); //死路判断 开启列表为空 if (openList.Count==0) { return null; } //选出开启列表中寻路消耗最小的点 openList.Sort(SortOpenList); //放入关闭列表中 然后再从开启列表中移除 closeList.Add(openList[0]); //找到这个最近的点openList[0],进行下一次的寻路计算 start = openList[0]; openList.RemoveAt(0); //如果这个点已经是终点了 那么得到最终结果返回出去 if (start == end) { //找到了 List path=new List (); path.Add(end); while (end.Father!=null) { path.Add(end.Father); end = end.Father; } path.Reverse(); return path; } //如果这个点 不是终点 那么继续寻路 } } //找到一个相邻的点放入OpenList中 //判断这些点 是否是边界 是否是阻挡 是否在开启和关闭列表中如果不是 才计算 private void FinNearlyNodeToOpenList(int x,int y,float g,AStarNode father, AStarNode end) { if (x<0||x>=mapW||y<0||y>=mapH) { return; } AStarNode node = nodes[x, y]; //OpenList和CloseList中是否包含这个点 if (node==null||node.Type==NodeType.Stop||openList.Contains(node)||closeList.Contains(node)) { return; } node.Father = father; //计算f值 node.g = father.g + g; node.h = Mathf.Abs(end.x - node.x) + Mathf.Abs(end.y - node.y); node.f = node.g + node.f; openList.Add(node); } private int SortOpenList(AStarNode a,AStarNode b) { if (a.f>b.f) { return 1; } else if (a.f==b.f) { return 1; } else { return -1; } }}
using System.Collections;using System.Collections.Generic;using System.Runtime.CompilerServices;using UnityEngine;public enum ColorType{ Normal, Yellow, Red, Green,}public class GameManager : MonoBehaviour{ private GameManager(){ } private static GameManager _instance; public static GameManager Instance { get { if (_instance==null) { _instance = GameObject.FindObjectOfType(); } return _instance; } } public int beginX=3; public int beginY=5; public int offsetX=2; public int offsetY=-2; public int mapW=5; public int mapH=8; public Dictionary materialDic; private Dictionary starNodeDic; List nodes=new List (); void Awake() { materialDic =new Dictionary (); starNodeDic=new Dictionary (); materialDic.Add(ColorType.Normal, Resources.Load ("Normal")); materialDic.Add(ColorType.Red,Resources.Load ("Red")); materialDic.Add(ColorType.Yellow, Resources.Load ("Yellow")); materialDic.Add(ColorType.Green, Resources.Load ("Green")); AStarMgr.Instance.InitMapInfo(mapW,mapH); for (int i = 0; i < mapW; i++) { for (int j = 0; j < mapH; j++) { GameObject item = GameObject.CreatePrimitive(PrimitiveType.Cube); item.transform.SetParent(this.transform); item.transform.position=new Vector3(beginX+i*offsetX,beginY+j* offsetY); item.name = i + "_" + j; AStarNode node = AStarMgr.Instance.nodes[i, j]; switch (node.Type) { case NodeType.Stop: item.transform.GetComponent ().material = materialDic[ColorType.Red]; break; } starNodeDic.Add(item,node); } } } private int pos = 1; private Vector2 begin; private GameObject beginObj; private List list; void Update() { if (Input.GetMouseButtonDown(0)) { RaycastHit info; Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray,out info,1000)) { pos += 1; if (pos%2==0) { //清空之前的颜色 if (list!=null) { for (int i = 0; i < list.Count; i++) { foreach (var nodes in starNodeDic) { if (nodes.Value == list[i]) { nodes.Key.gameObject.transform.GetComponent ().material = materialDic[ColorType.Normal]; } } } } beginObj = info.collider.gameObject; begin = new Vector2(starNodeDic[info.collider.gameObject].x, starNodeDic[info.collider.gameObject].y); info.collider.gameObject.transform.GetComponent ().material = materialDic[ColorType.Yellow]; } else { Vector2 end = new Vector2(starNodeDic[info.collider.gameObject].x, starNodeDic[info.collider.gameObject].y); list =AStarMgr.Instance.FindPath(begin, end); if (list!=null) { for (int i = 0; i < list.Count; i++) { foreach (var nodes in starNodeDic) { if (nodes.Value==list[i]) { nodes.Key.gameObject.transform.GetComponent ().material = materialDic[ColorType.Green]; } } } } else { //是死路的时候 清空开始点的颜色 beginObj.gameObject.transform.GetComponent ().material = materialDic[ColorType.Normal]; } } } } }}
转载地址:http://ayrxo.baihongyu.com/