Unity游戏开发AI-A*寻路算法
2019-01-17 13:44
351 查看
Unity3d利用A*寻路算法实现寻路模拟
https://www.geek-share.com/detail/2720697758.html
【Unity】【C#】A*寻路算法-学习心得
https://blog.csdn.net/Terrell21/article/details/82584634
自己实现效果
设置point点
[code]using System.Collections; using System.Collections.Generic; using UnityEngine; public class Point { public Point Parent { get; set; }//父 public float F { get; set; } public float G { get; set; } public float H { get; set; } public int X { get; set; } public int Y { get; set; } /// <summary> /// 是否是障碍物 /// </summary> public bool IsWall { get; set; } /// <summary> /// 构造 初始化 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="parent"></param> public Point(int x, int y, Point parent = null) { this.X = x; this.Y = y; this.Parent = parent; this.IsWall = false; } /// <summary> /// 更新父亲 /// </summary> /// <param name="parent"></param> /// <param name="g"></param> public void UpdateParent(Point parent, float g) { this.Parent = parent; this.G = g; this.F = G + H; } }
A*寻路算法实现
[code]using System.Collections.Generic; using UnityEngine; public class AStart : MonoBehaviour { private const int mapWhith = 8; private const int mapHight = 6; private Point[,] map = new Point[mapWhith, mapHight];//二维数组 // Use this for initialization void Start() { InitMap(); Point start = map[2, 3];//开始点 Point end = map[6, 3];//结束点 FindPath(start, end); ShowPath(start, end); //List<Point> l = GetSurroundPoints(new Point(3, 3)); //foreach (var item in l) //{ // Debug.Log(item.X + "-" + item.Y); //} } /// <summary> /// 构建虚拟地图 /// </summary> private void InitMap() { for (int x = 0; x < mapWhith; x++) { for (int y = 0; y < mapHight; y++) { map[x, y] = new Point(x, y); } } //设置障碍物 map[4, 2].IsWall = true; map[4, 3].IsWall = true; map[4, 4].IsWall = true; } /// <summary> /// 现实路径 /// </summary> /// <param name="start"></param> /// <param name="end"></param> public void ShowPath(Point start, Point end) { Point temp = end; while (true) { Debug.Log(temp.X + "--" + temp.Y); CreateCube(temp.X, temp.Y, Color.red); if (temp.Parent == null) { break; } temp = temp.Parent; } for (int x = 0; x < mapWhith; x++) { for (int y = 0; y < mapHight; y++) { if (map[x, y].IsWall == true) { CreateCube(x, y, Color.gray); } } } } public void CreateCube(float x, float y, Color color) { GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube); go.transform.position = new Vector3(x, y, 0); go.GetComponent<MeshRenderer>().material.color = color; } /// <summary> /// 路径的计算 /// </summary> /// <param name="start">开始点</param> /// <param name="end">结束点</param> private void FindPath(Point start, Point end) { List<Point> openList = new List<Point>();//开始集合 List<Point> closeList = new List<Point>();//关闭集合 openList.Add(start); //将开始点加入集合 ///这个while有两个终止条件 1,openlist为空 2, 找到目标位置 //在开集合找到距离最短的点 F最小 while (openList.Count > 0) { Point point = FindMinFPoint(openList);//找到最小的F openList.Remove(point); //在开集合中移除 closeList.Add(point); //在关集合中添加 List<Point> surroundPoints = GetSurroundPoints(point);//得到周围点的集合 PointsFilter(surroundPoints, closeList);//检查集合是否在闭 在关闭列表就不往开启列表添加数据了 foreach (Point surroundPoint in surroundPoints) { if (openList.IndexOf(surroundPoint) > -1) { float nowG = CalcG(surroundPoint, point);//更新G值,加上父的G值 if (nowG < surroundPoint.G) { surroundPoint.UpdateParent(point, nowG);//更新父亲 } } else { surroundPoint.Parent = point;//设置父亲 CalcF(surroundPoint, end);//计算F值 openList.Add(surroundPoint);//加入开集合 } } // 判断结束条件 判断end 是否在结束列表中 if (openList.IndexOf(end) > -1) { break; } } } /// <summary> /// 检查集合是否在关闭列表中 (目的)如果 在关闭列表就不往开启列表添加数据了 /// </summary> /// <param name="src"> 需要检查的集合</param> /// <param name="closePoint"> 已经加入关闭列表的集合</param> /// <returns></returns> private void PointsFilter(List<Point> src, List<Point> closePoint) { foreach (Point p in closePoint) { if (src.IndexOf(p) > -1)//若p不存在,返回-1 src.IndexOf(p) > -1 { src.Remove(p); } } } /// <summary> /// 返回一个点附近的点的集合 /// </summary> /// <param name="point"></param> /// <returns></returns> public List<Point> GetSurroundPoints(Point point) { Point up = null, down = null, left = null, right = null; Point lu = null, ru = null, ld = null, rd = null; //上、下 if (point.Y < mapHight - 1) //边界判断, { up = map[point.X, point.Y + 1]; } if (point.Y > 0) { down = map[point.X, point.Y - 1]; } //左、右 if (point.X > 0) { left = map[point.X - 1, point.Y]; } if (point.X < mapWhith - 1) { right = map[point.X + 1, point.Y]; } //左上、右上 if (up != null && left != null) { lu = map[point.X - 1, point.Y + 1]; } if (up != null && right != null) { ru = map[point.X + 1, point.Y + 1]; } //左下,右下 if (down != null && left != null) { ld = map[point.X - 1, point.Y - 1]; } if (down != null && right != null) { rd = map[point.X + 1, point.Y - 1]; } //将可到达的点加入集合 List<Point> list = new List<Point>(); //上下左右 if (down != null && down.IsWall == false) { list.Add(down); } if (up != null && up.IsWall == false) { list.Add(up); } if (left != null && left.IsWall == false) { list.Add(left); } if (right != null && right.IsWall == false) { list.Add(right); } //四个斜角 if (lu != null && lu.IsWall == false && left.IsWall == false && up.IsWall == false) { list.Add(lu); } if (ld != null && ld.IsWall == false && left.IsWall == false && down.IsWall == false) { list.Add(ld); } if (ru != null && ru.IsWall == false && right.IsWall == false && up.IsWall == false) { list.Add(ru); } if (rd != null && rd.IsWall == false && right.IsWall == false && down.IsWall == false) { list.Add(rd); } return list; } /// <summary> /// 找寻Point最小的F值 /// </summary> /// <param name="openList"></param> /// <returns></returns> private Point FindMinFPoint(List<Point> openList) { float f = float.MaxValue;//设置最大值 Point temp = null; foreach (Point p in openList) { if (p.F < f) { temp = p; f = p.F; } } return temp; } /// <summary> /// 计算G值 /// </summary> /// <param name="now"></param> /// <param name="parent"></param> /// <returns></returns> public float CalcG(Point now, Point parent) { return Vector2.Distance(new Vector2(now.X, now.Y), new Vector2(parent.X, parent.Y)) + parent.G; } /// <summary> /// 计算F值 /// </summary> /// <param name="now"></param> /// <param name="end"></param> private void CalcF(Point now, Point end) { // F = G + H // 求得F值 float h = Mathf.Abs(end.X - now.X) + Mathf.Abs(end.Y - now.Y); //预计到达目标点的距离 float g = 0; if (now.Parent == null)//即为开始点 { g = 0; } else { g = Vector2.Distance(new Vector2(now.X, now.Y), new Vector2(now.Parent.X, now.Parent.Y)) + now.Parent.G; } float f = g + h; now.F = f; now.G = g; now.H = h; } }
最终效果
相关文章推荐
- 关于游戏开发中的A*/A-star的寻路算法的问题
- unity开发 斗地主算法—提示AI(提示出牌)
- 【游戏编程】AI-迷宫寻路算法-深度优先搜索和广度优先搜索
- [Unity游戏开发]自动寻路NavMash
- Unity实战 RTS3D即时战略游戏开发(六) Navigation Mesh 自动寻路
- Unity游戏开发 怪物巡逻AI
- 【游戏编程】AI-迷宫寻路算法-深度优先搜索和广度优先搜索
- Unity Game Programming AI(5)A Star寻路算法
- 【AI】A star(A 星)算法在手机游戏开发中的使用
- Unity实战 RTS3D即时战略游戏开发(十二) 战斗AI的控制
- 【游戏开发】A*寻路算法
- 游戏开发A*寻路算法C++实现
- Unity实战 RTS3D即时战略游戏开发(十一) 建造AI、生产AI
- 游戏寻路算法的简单实现
- Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机
- 吴昊品游戏核心算法 Round 9 (引子)—— 正统黑白棋AI(李开复的Othello)
- 麻将游戏结构与AI算法
- 棋牌游戏开发之斗地主算法点选牌
- 游戏开发中的数学和物理算法(7):角度 vs 弧度