protected List <Point> UseAstar(Vector3 origin, Vector3 destination, int range) { int[,] array = new int[BattleFieldManager.GetInstance().GridX, BattleFieldManager.GetInstance().GridY]; //可优化为更小的地图。 path.Clear(); for (int i = 0; i < BattleFieldManager.GetInstance().GridX; i++) { for (int j = 0; j < BattleFieldManager.GetInstance().GridY; j++) { array[i, j] = 1; } } var minX = origin.x - range; var minY = origin.z - range; var maxX = origin.x + range; var maxY = origin.z + range; minX = minX > 0 ? minX : 0.5f; minY = minY > 0 ? minY : 0.5f; maxX = maxX < BattleFieldManager.GetInstance().GridX ? maxX : BattleFieldManager.GetInstance().GridX - 0.5f; maxY = maxY < BattleFieldManager.GetInstance().GridY ? maxY : BattleFieldManager.GetInstance().GridY - 0.5f; //检测整张地图的地板块激活情况,判断障碍物,存入数组。 for (int i = (int)minX; i <= (int)maxX; i++) { for (int j = (int)minY; j <= (int)maxY; j++) { floorPosition = Vector3.zero; floorPosition.x += (i + anchorPoint); floorPosition.z += (j + anchorPoint); GameObject floor = BFM.GetFloor(floorPosition); //AI做预判时会有限制,不能用activeSelf,基于哈希表的Dictionary,ContainsKey比ContainsValue的效率高很多100ms <---> 400ms if (floor && rangeDic.ContainsKey(floor.transform.position) /* floor.activeSelf */ && (floor.transform.position == destination || !floorAroundEnemy.Contains(floor.transform.position))) //地板是激活的且不在敌人周围,可用作寻路路径。如果是目的地且在激活的状态下,一定可以作为寻路路径。 { array[i, j] = 0; } else { array[i, j] = 1; } } } //调用A*。 Astar astar = new Astar(array); Point start = new Point((int)origin.x, (int)origin.z); Point end = new Point((int)destination.x, (int)destination.z); var parent = astar.FindPath(start, end, false); while (parent != null) { path.Add(parent); parent = parent.ParentPoint; } path.Reverse(); //里面的元素顺序是反的,即从目的指向起点,这里变为由起点指向目的。 return(path); }
protected List <Point> UseAstar(Vector3 origin, Vector3 destination, int range) { path.Clear(); for (int i = 0; i < BattleFieldManager.GridX; i++) { for (int j = 0; j < BattleFieldManager.GridY; j++) { array[i, j] = 1; } } var minX = origin.x - range; var minY = origin.z - range; var maxX = origin.x + range; var maxY = origin.z + range; //检测整张地图的地板块激活情况,判断障碍物,存入数组。 for (int i = (int)minX; i <= (int)maxX; i++) { for (int j = (int)minY; j <= (int)maxY; j++) { floorPosition = Vector3.zero; floorPosition.x += (i + anchorPoint); floorPosition.z += (j + anchorPoint); GameObject floor = BFM.GetFloor(floorPosition); if (floor && floor.activeSelf && (floor.transform.position == destination || !floorAroundEnemy.Contains(floor.transform.position))) //地板是激活的且不在敌人周围,可用作寻路路径。如果是目的地且在激活的状态下,一定可以作为寻路路径。 { array[i, j] = 0; } else { array[i, j] = 1; } } } //调用A*。 Astar astar = new Astar(array); Point start = new Point((int)origin.x, (int)origin.z); Point end = new Point((int)destination.x, (int)destination.z); var parent = astar.FindPath(start, end, false); while (parent != null) { path.Add(parent); parent = parent.ParentPoint; } path.Reverse(); //里面的元素顺序是反的,即从目的指向起点,这里变为由起点指向目的。 return(path); }