自动寻路方案
2015-07-01 18:56 糯米粥 阅读(474) 评论(0) 编辑 收藏 举报这里是用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 }