自动寻路方案

这里是用cube模拟的自动寻路。还不是最优的寻路方案

  1 using UnityEngine;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 
  5 class Point //代表人
  6 {
  7     public int X { get; set; }
  8     public int Y { get; set; }
  9 
 10     public Point Parent { get; set; }
 11 
 12     public Point(int x, int y)
 13     {
 14         X = x;
 15         Y = y;
 16     }
 17 }
 18 
 19 public class ANavition : MonoBehaviour
 20 {
 21 
 22     List<Point> nowList; //正在访问的集合 讲台
 23     List<Point> visitendList; //已经访问过的集合 ,白板
 24 
 25     //玩家和目标
 26     GameObject player;
 27     GameObject target;
 28 
 29     bool canReach; //能否到达目标点
 30 
 31     bool[,] maps; //地图 二维数组
 32 
 33     int[,] dir = new int[,] { { 0, 1 }/*up*/, { 0, -1 }/*down*/, { -1, 0 }/*left*/, { 1, 0 }/*right*/ };
 34 
 35     Vector3 moveDir; //玩家自动寻路的方向
 36 
 37 
 38     // Use this for initialization
 39     void Start()
 40     {
 41         LoadGameMap();
 42         InitGameMap();
 43         FindTarget();
 44 
 45     }
 46 
 47     void OnGUI()
 48     {
 49         if (GUILayout.Button("刷新"))
 50         {
 51             Application.LoadLevel("03ANav");
 52         }
 53     }
 54 
 55     // Update is called once per frame
 56     void Update()
 57     {
 58         if (canReach)
 59         {
 60             AntoMove();
 61         }
 62     }
 63 
 64     /// <summary>
 65     /// 角色自动导航
 66     /// </summary>
 67     private void AntoMove()
 68     {
 69         if (ways.Count > 0)
 70         {
 71             moveDir = (ways.Peek() - player.transform.position).normalized;
 72 
 73             player.transform.Translate(moveDir * Time.deltaTime);
 74 
 75             //
 76             if (Vector3.Distance(ways.Peek(), player.transform.position) < 0.1f)
 77             {
 78                 ways.Pop();//弹出栈顶元素
 79             }
 80         }
 81     }
 82 
 83     /// <summary>
 84     /// 找目标
 85     /// </summary>
 86     void FindTarget()
 87     {
 88         //初始化集合
 89         nowList = new List<Point>();
 90         visitendList = new List<Point>();
 91 
 92         Point yangbo = new Point(0, 0);
 93         //yangbo.X = 0;
 94         //yangbo.Y = 0;
 95 
 96         nowList.Add(yangbo);
 97         visitendList.Add(yangbo);
 98 
 99 
100         Point first;
101         int x, y;
102         //只要有人,游戏一直继续玩下去
103         while (nowList.Count > 0)
104         {
105             first = nowList[0];
106 
107             //dir-> 前 (0,1) 后(0,-1)
108             for (int i = 0; i < 4; i++)
109             {
110                 x = first.X + dir[i, 0]; //第i个方向的x
111                 y = first.Y + dir[i, 1]; //第i个方向的y
112 
113                 if (IsOk(x, y))
114                 {
115                     Point person = new Point(x, y);
116                     person.Parent = first;
117 
118                     nowList.Add(person);//上讲台
119                     visitendList.Add(person); //写上名字
120                 }
121 
122                 //找到了目标点
123                 if (IsFindTarGet(first))
124                 {
125                     break;
126                 }
127             }
128 
129             nowList.Remove(first); //移除上了讲台的人
130         }
131     }
132     Stack<Vector3> ways; //栈,存路径
133     bool IsFindTarGet(Point person)
134     {
135         if (person.X == 5 && person.Y == 5)
136         {
137             ways = new Stack<Vector3>();
138             while (person.Parent != null) //链表查找父亲
139             {
140                 Vector3 pos = new Vector3(person.X, 1, person.Y);
141 
142                 ways.Push(pos);
143 
144                 person = person.Parent;
145             }
146             canReach = true;
147             return canReach;
148         }
149         return false;
150     }
151 
152     bool IsOk(int x, int y)
153     {
154         //数组越界
155         if (x < 0 || y < 0 || x > 5 || y > 5) return false;
156 
157         //访问过的节点不能再次访问
158         foreach (Point p in visitendList)
159         {
160             if (p.X == x && p.Y == y) return false;
161         }
162 
163         return maps[x, y];
164     }
165 
166     /// <summary>
167     /// 生成游戏地图数组
168     /// </summary>
169     public void LoadGameMap()
170     {
171         maps = new bool[6, 6]; //6行6列的游戏地图
172 
173         for (int i = 0; i < maps.GetLength(0); i++)
174         {
175             for (int j = 0; j < maps.GetLength(1); j++)
176             {
177                 //70% true  30% false
178                 maps[i, j] = Random.Range(1, 11) <= 7 ? true : false;
179             }
180         }
181 
182         //都必须是绿色 即为true
183         maps[0, 0] = true; //玩家起点位置 
184         maps[5, 5] = true; //目标点位置
185     }
186 
187     /// <summary>
188     /// 初始化地图
189     /// </summary>
190     void InitGameMap()
191     {
192         for (int i = 0; i < 6; i++)
193         {
194             for (int j = 0; j < 6; j++)
195             {
196                 GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
197                 //cube.transform.position = new Vector3(j, i, 0);
198 
199                 cube.transform.position = new Vector3(i, 0, j); //从顶部看  xz平面上
200 
201                 //true为绿色。即可以走。false为红色。即不可以走
202                 cube.transform.renderer.material.color = maps[i, j] ? Color.green : Color.red;
203 
204                 cube.transform.localScale = Vector3.one * 0.8f; //缩放cube
205 
206                 cube.transform.SetParent(transform); //设置父对象,便于管理
207             }
208         }
209 
210         //玩家和目标
211         player = GameObject.CreatePrimitive(PrimitiveType.Capsule);
212 
213         target = GameObject.CreatePrimitive(PrimitiveType.Sphere);
214 
215         player.transform.position = new Vector3(0, 1, 0); //玩家的初始位置
216 
217         player.transform.localScale = Vector3.one * 0.5f; //缩放玩家
218 
219         target.transform.position = new Vector3(5, 1, 5); //目标点的位置
220 
221     }
222 
223 
224 }
原文地址:https://www.cnblogs.com/nsky/p/4614304.html