AStarItem[] FindNearFloors(GameObject obj) { Vector3[] dirs = new Vector3[]{ Vector3.forward, Vector3.right, Vector3.back, Vector3.left, }; AStarItem[] items = new AStarItem[dirs.Length]; Vector3 object_pos = obj.transform.position; Vector3 object_floor = FloorFunc (object_pos); for (int i = 0; i < dirs.Length; i++) { Vector3 dir = dirs[i]; Vector3 arranged_dir = ArrangeDir(dir); Vector3 floor_value_offset = FloorFuncWithoutArrange(dir); Vector3 next_floor = object_floor + floor_value_offset; next_floor.z = 1024; if (obj.name[0] == 'S') { SlopeType type = GetSlopeType(obj, arranged_dir); if (type == SlopeType.half) continue; else if (type == SlopeType.slope_down) { next_floor.x -= 1; next_floor.y -= 1; object_floor.z -= 1; } } GameObject other; Vector3 other_floor = Vector3.zero; while (other = FindFloorWithFloorValue(next_floor, true)) { other_floor = FloorFunc(other.transform.position); if (other_floor.z > object_floor.z && next_floor.x + next_floor.y > object_floor.x + object_floor.y && !(other.name[0] == 'S' && GetSlopeType(other, arranged_dir) == SlopeType.floor_down)) { next_floor.z = other_floor.z; continue; } else if (other_floor.z < object_floor.z && next_floor.x + next_floor.y < object_floor.x + object_floor.y && !(obj.name[0] == 'S' && GetSlopeType(obj, arranged_dir) == SlopeType.floor_up)) { next_floor.z = other_floor.z; continue; } break; } if (other) { items[i] = new AStarItem(other, other_floor, 0, 0, arranged_dir); continue; } next_floor.x += 1; next_floor.y += 1; next_floor.z = 1024; while (other = FindFloorWithFloorValue(next_floor, true)) { other_floor = FloorFunc(other.transform.position); if (other.name[0] == 'S' && GetSlopeType(other, arranged_dir) == SlopeType.slope_up) { break; } next_floor.z = other_floor.z; } if (other) { items[i] = new AStarItem(other, other_floor, 0, 0, arranged_dir); continue; } } return items; }
public int CompareItem(AStarItem a, AStarItem b) { return a.Weight.CompareTo (b.Weight); }
void FindPathTo(GameObject dest) { ArrayList open_list = new ArrayList(); ArrayList closed_list = new ArrayList(); IComparer compare = new ItemComparer(); open_list.Add(new AStarItem(standingFloor, FloorFunc(standingFloor.transform.position), 0, 0, Vector3.zero)); Vector3 dest_floor = FloorFunc(dest.transform.position); AStarItem dest_item = null; while (open_list.Count > 0) { open_list.Sort(compare); AStarItem item = (AStarItem)open_list[0]; open_list.RemoveAt(0); closed_list.Add(item); if (item.Obj == dest) { dest_item = item; break; } AStarItem[] near_items = FindNearFloors(item.Obj); for (int i = 0; i < near_items.Length; i++) { if (near_items[i] == null) { continue; } AStarItem near_item = near_items[i]; bool ok = true; foreach (AStarItem it in closed_list) { if (it.Obj == near_item.Obj) { ok = false; break; } } if (!ok) { continue; } near_item.G = item.G + 1; near_item.H = (int)(Mathf.Abs(dest_floor.x - near_item.FloorValue.x) + Mathf.Abs(dest_floor.y - near_item.FloorValue.y)); near_item.parent = item; for (int j = 0; j < open_list.Count; j++) { AStarItem it = (AStarItem)open_list[j]; if (it.Obj == near_item.Obj) { ok = false; it.G = Mathf.Max(it.G, near_item.G); break; } } if (!ok) { continue; } open_list.Add(near_item); } } if (dest_item != null) { ArrayList move_list = new ArrayList(); AStarItem item = dest_item; while (item.Weight > 0) { move_list.Add(new MoveData(item.dir, item.Obj)); item = item.parent; } move_list.Reverse(); if (moving > 0) { StopMoving(); RecalcPlayerPos(); } moveList = new MoveData[move_list.Count]; for (int i = 0; i < move_list.Count; i++) { moveList[i] = (MoveData)move_list[i]; } MoveTo(moveList[0].destFloor, moveList[0].dir); } }
AStarItem[] FindNearFloors(GameObject obj) { Vector3[] dirs = new Vector3[] { Vector3.forward, Vector3.right, Vector3.back, Vector3.left, }; AStarItem[] items = new AStarItem[dirs.Length]; Vector3 object_pos = obj.transform.position; Vector3 object_floor = FloorFunc(object_pos); for (int i = 0; i < dirs.Length; i++) { Vector3 dir = dirs[i]; Vector3 arranged_dir = ArrangeDir(dir); Vector3 floor_value_offset = FloorFuncWithoutArrange(dir); Vector3 next_floor = object_floor + floor_value_offset; next_floor.z = 1024; if (obj.name[0] == 'S') { SlopeType type = GetSlopeType(obj, arranged_dir); if (type == SlopeType.half) { continue; } else if (type == SlopeType.slope_down) { next_floor.x -= 1; next_floor.y -= 1; object_floor.z -= 1; } } GameObject other; Vector3 other_floor = Vector3.zero; while (other = FindFloorWithFloorValue(next_floor, true)) { other_floor = FloorFunc(other.transform.position); if (other_floor.z > object_floor.z && next_floor.x + next_floor.y > object_floor.x + object_floor.y && !(other.name[0] == 'S' && GetSlopeType(other, arranged_dir) == SlopeType.floor_down)) { next_floor.z = other_floor.z; continue; } else if (other_floor.z < object_floor.z && next_floor.x + next_floor.y < object_floor.x + object_floor.y && !(obj.name[0] == 'S' && GetSlopeType(obj, arranged_dir) == SlopeType.floor_up)) { next_floor.z = other_floor.z; continue; } break; } if (other) { items[i] = new AStarItem(other, other_floor, 0, 0, arranged_dir); continue; } next_floor.x += 1; next_floor.y += 1; next_floor.z = 1024; while (other = FindFloorWithFloorValue(next_floor, true)) { other_floor = FloorFunc(other.transform.position); if (other.name[0] == 'S' && GetSlopeType(other, arranged_dir) == SlopeType.slope_up) { break; } next_floor.z = other_floor.z; } if (other) { items[i] = new AStarItem(other, other_floor, 0, 0, arranged_dir); continue; } } return(items); }
public int CompareItem(AStarItem a, AStarItem b) { return(a.Weight.CompareTo(b.Weight)); }