public override IEnumerator Traverse(NavCell nav) { List <NavCell> path = new List <global::NavCell>(); while (nav != null) { path.Insert(0, nav); nav = nav.parent; } unit.animation.SetBool("Run", true); for (int i = 1; i < path.Count; ++i) { NavCell target = path[i]; yield return(StartCoroutine(Turn(target))); yield return(StartCoroutine(Walk(target))); if (target.cell.UnitEnter(unit)) { unit.NoActive(); target.cell.SetUnit(unit); Manage.Instance.Battle.ClearCurrent(); Manage.Instance.Battle.ChangeState <BattleState.SelectUnitBattleState>(null); break; } } unit.animation.SetBool("Run", false); yield return(null); }
public NavCell Copy() { NavCell cell = new NavCell(this.cell, parent); cell.consume = consume; return(cell); }
void MoveRange() { HexCell cell = BattleManager.SelectedCell(); if (cell == null) { return; } NavCell target = path.Find(a => a.cell == cell); if (target != null) { foreach (var item in path) { item.cell.State = HexCellState.none; } do { target.cell.State = HexCellState.Move; target = target.parent; } while (target != null); } else { path = HexGrid.Instantiate.GetMoveRangePath(cell, range, IsMove); foreach (var item in path) { item.cell.State = HexCellState.Move; } } }
private NavCell[] ConstructPath(NavCell destination, ref int newTState, NavCell[] overrideStart = null) { var path = new List <NavCell>() { destination }; var current = destination; while (current.parent != null) { current = current.parent; path.Add(current); } path.Reverse(); // C0 and C1 set if (overrideStart != null) { //curPath 0 and curPath 1 are p0 and p1 if (overrideStart[1].position == path[0].position) // if c1 == p0 { if (overrideStart[0].position != path[1].position) // Not returning from next cell in path { // Forward traversal path.Insert(0, overrideStart[0]); // New t = t newTState = 0; } else { // New t = 1 - t newTState = 1; } } else if (overrideStart[0].position == path[0].position) { if (overrideStart[1].position == path[1].position) { // New t = t newTState = 0; } else { // Inverse traversal //path.Insert(0, overrideStart[0]); path.Insert(0, overrideStart[1]); // New t = 1 - t newTState = 1; } } } return(path.ToArray()); }
public void ReviseParent(NavCell parent) { this.parent = parent; if (this.parent == null) { consume = 0; } consume = cell.Consume() + parent.consume; }
IEnumerator Walk(NavCell target) { unit.tweener.open = target.cell.transform.position; unit.tweener.close = unit.transform.position; unit.tweener.OnOpen(); while (unit.tweener.IsPlay) { yield return(null); } }
public static NavCellDefinition Create(NavCell navCell) { var def = new NavCellDefinition { Min = navCell.Min, Max = navCell.Max, Flags = navCell.Flags }; return def; }
public static NavCellDefinition Create(NavCell navCell) { var def = new NavCellDefinition { Min = navCell.Min, Max = navCell.Max, Flags = navCell.Flags }; return(def); }
public WorldSceneCell(NavCell navCell, Vector2 zoneMin) { MinX = zoneMin.X + navCell.Min.X; MinY = zoneMin.Y + navCell.Min.Y; MaxX = zoneMin.X + navCell.Max.X; MaxY = zoneMin.Y + navCell.Max.Y; NavCellFlags = navCell.Flags; IsWalkable = NavCellFlags.HasFlag(NavCellFlags.AllowWalk); Z = Math.Max(navCell.Min.Z, navCell.Max.Z); }
public List <NavCell> GetPath() { NavCell _cell = this; List <NavCell> path = new List <global::NavCell>(); while (_cell != null) { path.Add(_cell); _cell = parent; } return(path); }
/// <summary> /// /// </summary>返回移动范围(range里面可能加了攻击范围) /// <param name="startCell">起点</param> /// <param name="range">移动范围+攻击范围</param> /// <param name="func">判断是否加入移动列表,海陆空移动范围不一样,非机械单位可以移动到载具里面</param> /// <returns></returns> public List <NavCell> GetMoveRangePath(HexCell startCell, int range, Func <HexCell, bool> func) { List <NavCell> path = new List <NavCell>(); //返回的范围 NavCell start = new NavCell(startCell); //起点 start.consume = 0; //起点的移动消耗 path.Add(start); //把起点添加到查找列表 Queue <NavCell> openNav = new Queue <global::NavCell>(); //已经找到的范围 openNav.Enqueue(start); NavCell navCell = null; while (openNav.Count > 0) { navCell = openNav.Dequeue(); for (int i = 0; i < 6; i++) { HexCell cell = navCell.cell.GetNeighbor(i);//返回一个附近的格子 if (cell == null) { continue; } if (!func(cell)) { continue; //判断是否满足移动条件 } NavCell nav = path.Find(a => a.cell == cell); //已经找到的范围判断当前格子走过去是否消耗更小 if (nav != null) { if (navCell.consume + cell.Consume() >= nav.consume) { continue; } nav.ReviseParent(navCell); } else { nav = new NavCell(cell, navCell); //新找到的范围,构造函数里面有移动消耗叠加的操作 } if (nav.consume <= range) //如果距离没有超过移动距离 { path.Add(nav); if (nav.consume < range) { openNav.Enqueue(nav); } } } } return(path); }
public NavCell[] GetMooreNeighbours(NavCell current) { var result = new NavCell[4]; int x = current.position.x - shipPiece.Position.x; int y = current.position.y - shipPiece.Position.y; int[] indices = new int[] { x *height + (y + 1), (x + 1) * height + y, x *height + (y - 1), (x - 1) * height + y, }; if ((current.Cell.CurWallState & WallState.Up) == WallState.None) { // Up if (y < height - 1) { result[0] = cells[indices[0]]; } } if ((current.Cell.CurWallState & WallState.Right) == WallState.None) { // Right if (x < width - 1) { result[1] = cells[indices[1]]; } } if ((current.Cell.CurWallState & WallState.Down) == WallState.None) { // Down if (y > 0) { result[2] = cells[indices[2]]; } } if ((current.Cell.CurWallState & WallState.Left) == WallState.None) { // Left if (x > 0) { result[3] = cells[indices[3]]; } } return(result); }
public WorldSceneCell(NavCell navCell, Vector2 zoneMin) { MinX = zoneMin.X + navCell.Min.X; MinY = zoneMin.Y + navCell.Min.Y; MaxX = zoneMin.X + navCell.Max.X; MaxY = zoneMin.Y + navCell.Max.Y; NavCellFlags = navCell.Flags; IsWalkable = NavCellFlags.HasFlag(NavCellFlags.AllowWalk); Z = navCell.Min.Z; if (Z < 0.1f) { Z = 0; } }
public void Generate() { cells = new NavCell[width * height]; for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { int index = w * height + h; CellTemplate shipCell = shipPiece.GetShipCell(w, h); var navCell = new NavCell(this, new Vector2Int(w, h) + shipPiece.Position, shipCell); cells[index] = navCell; } } }
public List <HexCell> GetRange(HexCell start, int range, int minRange, Func <HexCell, bool> movefunc) { List <HexCell> path = new List <HexCell>(); Queue <HexCell> close = new Queue <global::HexCell>(); path.Add(start); Queue <NavCell> openNav = new Queue <global::NavCell>(); NavCell startNav = new NavCell(start); startNav.consume = 0; openNav.Enqueue(startNav); NavCell navCell = null; while (openNav.Count > 0) { navCell = openNav.Dequeue(); for (int i = 0; i < 6; i++) { HexCell cell = navCell.cell.GetNeighbor(i); if (cell == null) { continue; } if (close.Contains(cell)) { continue; } if (!movefunc(cell)) { continue; } if (path.Contains(cell)) { continue; } NavCell nav = new NavCell(cell, navCell); if (nav.consume <= range && nav.consume >= minRange) { path.Add(cell); close.Enqueue(cell); openNav.Enqueue(nav); } } } return(path); }
private NavCell GetBestCell() { NavCell result = null; float currentF = float.PositiveInfinity; for (int i = 0; i < openList.Count; i++) { var cell = openList[i]; if (cell.f < currentF) { currentF = cell.f; result = cell; } } return(result); }
public override void Enter(object[] obj) { base.Enter(obj); MoveTargetCell = obj[0] as NavCell; if (obj.Length > 1) { AtkTarget = obj[1] as HexCell; seleSkill = obj[2] as SkillAttribute; } if (MoveTargetCell.cell == owner.CurrentUnit.cell) { MoveEnd(); } else { BattleManager.ChangeState(GameState.moveing); StartCoroutine(Swquence()); } }
protected override void OnClick() { HexCell cell = ClickCell(); if (cell == null || (cell.State != HexCellState.Move && cell.State != HexCellState.MovePath) || cell == owner.CurrentUnit.cell ) { moveTarget = null; SeleCell = null; if (path != null) { HexGrid.Instantiate.ChangeCellState(path, HexCellState.Move); } path.Clear(); BattlePanel.Instance.downMenu.UpdateAp(owner.CurrentUnit, 0); Extend.ClosePrompt(); return; } if (SeleCell == null || SeleCell != cell) { SeleCell = cell; Extend.UpdatePrompt("再次点击确定移动目标"); moveTarget = range.Find(a => a.cell == cell); if (path != null) { HexGrid.Instantiate.ChangeCellState(path, HexCellState.Move); } path = new List <NavCell>(); NavCell nav = moveTarget.Copy(); while (nav != null) { path.Insert(0, nav); nav = nav.parent; } HexGrid.Instantiate.ChangeCellState(path, HexCellState.MovePath); BattlePanel.Instance.downMenu.UpdateAp(owner.CurrentUnit, moveTarget.consume); return; } owner.ChangeState <MoveBattleState>(moveTarget); }
private void BuildNavCellPotentiallyVisibleSet() { if (m_nonEmptyNavCellCount > 0) { // Only need PVS information on non-empty nav cells m_pvs = new PotentiallyVisibleSet(m_nonEmptyNavCellCount); // Raycast from each non-empty nav cell... for (int startNavCellIndex = 0; startNavCellIndex < m_navCells.Length; ++startNavCellIndex) { NavRef startNavRef = new NavRef(startNavCellIndex, m_roomKey); NavCell startNavCell = m_navCells[startNavCellIndex]; if (startNavCell.connectivityId != EMPTY_NAV_CELL) { // ... to every other non-empty nav cell for (int endNavCellIndex = 0; endNavCellIndex < m_navCells.Length; ++endNavCellIndex) { NavCell endNavCell = m_navCells[endNavCellIndex]; if (startNavCellIndex != endNavCellIndex && endNavCell.connectivityId != EMPTY_NAV_CELL) { NavRef endNavRef = new NavRef(endNavCellIndex, m_roomKey); Point3d start = ComputeNavCellCenter((uint)startNavCellIndex); Point3d end = ComputeNavCellCenter((uint)endNavCellIndex); float t; bool hit = Raycast(start, startNavRef, end, endNavRef, out t); // Mark visibility in the PVS where the raycast succeeds if (!hit) { m_pvs.SetCellCanSeeOtherCell((uint)startNavCell.pvsCellIndex, (uint)endNavCell.pvsCellIndex); } } } } } } }
private void NavCellsToString(StringBuilder report) { if (m_navCells != null) { int cellIndex = 0; report.AppendLine("NavCells:"); for (int row = 0; row < m_rowCount; row++) { for (int col = 0; col < m_colomnCount; col++) { NavCell navCell = m_navCells[cellIndex++]; report.Append(navCell.connectivityId != EMPTY_NAV_CELL ? '1' : '0'); } report.Append('\n'); } } }
private void DrawCells(Graphics graphics, Scene scene) { for (int i = 0; i < scene.NavCells.Length; i++) { NavCell cell = scene.NavCells[i]; if ((cell.Flags & NavCellFlags.AllowWalk) != NavCellFlags.AllowWalk) { continue; } float x = scene.BoundingBox.Min.X + cell.BoundingBox.Min.X; float y = scene.BoundingBox.Min.Y + cell.BoundingBox.Min.Y; float width = cell.BoundingBox.Max.X - cell.BoundingBox.Min.X; float height = cell.BoundingBox.Max.Y - cell.BoundingBox.Min.Y; var rect = new Rectangle((int)x, (int)y, (int)width, (int)height); graphics.DrawRectangle(walkablePen, rect); //graphics.FillRectangle(walkableBrush, rect); } }
public bool NavRefCanSeeOtherNavRef(NavRef navRefA, NavRef navRefB) { bool canSee = false; if (navRefA.IsValid && navRefB.IsValid) { canSee = true; if (m_pvs != null) { NavCell navCellA = m_navCells[navRefA.NavCellIndex]; NavCell navCellB = m_navCells[navRefB.NavCellIndex]; canSee = m_pvs.CanCellSeeOtherCell( (uint)navCellA.pvsCellIndex, (uint)navCellB.pvsCellIndex); } } return(canSee); }
private static bool TryGetValidNeighborNavCellIndex( NavCell[] navCells, uint colomnCount, uint rowCount, uint navCellIndex, MathConstants.eDirection direction, out uint neighborCellIndex) { bool hasNeighbor = false; neighborCellIndex = 0; if (navCells.Length > 1) { uint colomn = GetNavCellColomn(colomnCount, navCellIndex); uint row = GetNavCellRow(colomnCount, navCellIndex); switch (direction) { case MathConstants.eDirection.down: if ((row + 1) < rowCount) { neighborCellIndex = GetNavCellIndex(colomnCount, row + 1, colomn); hasNeighbor = true; } break; case MathConstants.eDirection.up: if ((row - 1) > 0) { neighborCellIndex = GetNavCellIndex(colomnCount, row - 1, colomn); hasNeighbor = true; } break; case MathConstants.eDirection.left: if ((colomn - 1) >= 0) { neighborCellIndex = GetNavCellIndex(colomnCount, row, colomn - 1); hasNeighbor = true; } break; case MathConstants.eDirection.right: if ((colomn + 1) >= 0) { neighborCellIndex = GetNavCellIndex(colomnCount, row, colomn + 1); hasNeighbor = true; } break; } if (hasNeighbor && navCells[neighborCellIndex].connectivityId == EMPTY_NAV_CELL) { neighborCellIndex = 0; hasNeighbor = false; } } return hasNeighbor; }
/// <summary> /// Gets the center of a given Navigation Cell /// </summary> /// <param name="cell"></param> /// <param name="zone"></param> /// <returns></returns> private Vector3 GetNavCellCenter(NavCell cell, NavZone zone) { return GetNavCellCenter(cell.Min, cell.Max, zone); }
public TrinityNavCell(NavCell navCell, AABB zoneBounds) { RelativeBounds = navCell.Bounds; Flags = navCell.Flags; Min = navCell.Min; Max = navCell.Max; ZoneBounds = zoneBounds; AbsBounds = new AABB { Max = new Vector3(ZoneBounds.Min.X + navCell.Max.X, ZoneBounds.Min.Y + navCell.Max.Y, 0), Min = new Vector3(ZoneBounds.Min.X + navCell.Min.X, ZoneBounds.Min.Y + navCell.Min.Y, 0) }; }
//Create an instance of a pathfinding node public NavNode(NavCell cell, NavNode parent, float movingCost) : base(cell.Id, cell.IsWalkable, cell.Center) { m_parent = parent; m_movingCost = movingCost; }
/// <summary> /// Finds a navigable point in a priority scene /// </summary> private void FindPrioritySceneTarget() { if (SceneId == 0 && SceneName == String.Empty) { return; } gp.Update(); if (PrioritySceneTarget != Vector3.Zero) { return; } bool foundPriorityScene = false; // find any matching priority scenes in scene manager - match by name or SNOId List <Scene> PScenes = ZetaDia.Scenes.GetScenes() .Where(s => s.SceneInfo.SNOId == SceneId).ToList(); PScenes.AddRange(ZetaDia.Scenes.GetScenes() .Where(s => SceneName.Trim() != String.Empty && s.Name.ToLower().Contains(SceneName.ToLower())).ToList()); List <Scene> foundPriorityScenes = new List <Scene>(); Dictionary <int, Vector3> foundPrioritySceneIndex = new Dictionary <int, Vector3>(); foreach (Scene scene in PScenes) { if (PriorityScenesInvestigated.Contains(scene.SceneInfo.SNOId)) { continue; } foundPriorityScene = true; NavZone navZone = scene.Mesh.Zone; NavZoneDef zoneDef = navZone.NavZoneDef; Vector2 zoneMin = navZone.ZoneMin; Vector2 zoneMax = navZone.ZoneMax; Vector3 zoneCenter = GetNavZoneCenter(navZone); List <NavCell> NavCells = zoneDef.NavCells.Where(c => c.Flags.HasFlag(NavCellFlags.AllowWalk)).ToList(); if (!NavCells.Any()) { continue; } NavCell bestCell = NavCells.OrderBy(c => GetNavCellCenter(c.Min, c.Max, navZone).Distance2D(zoneCenter)).FirstOrDefault(); if (bestCell != null) { foundPrioritySceneIndex.Add(scene.SceneInfo.SNOId, GetNavCellCenter(bestCell, navZone)); foundPriorityScenes.Add(scene); } else { DbHelper.Log(TrinityLogLevel.Normal, LogCategory.ProfileTag, "Found Priority Scene but could not find a navigable point!", true); } } if (foundPrioritySceneIndex.Any()) { KeyValuePair <int, Vector3> nearestPriorityScene = foundPrioritySceneIndex.OrderBy(s => s.Value.Distance2D(myPos)).FirstOrDefault(); PrioritySceneSNOId = nearestPriorityScene.Key; PrioritySceneTarget = nearestPriorityScene.Value; CurrentPriorityScene = foundPriorityScenes.FirstOrDefault(s => s.SceneInfo.SNOId == PrioritySceneSNOId); DbHelper.Log(TrinityLogLevel.Normal, LogCategory.ProfileTag, "Found Priority Scene {0} - {1} Center {2} Distance {3:0}", CurrentPriorityScene.Name, CurrentPriorityScene.SceneInfo.SNOId, PrioritySceneTarget, PrioritySceneTarget.Distance2D(myPos)); } if (!foundPriorityScene) { PrioritySceneTarget = Vector3.Zero; } }
public bool Navigate(ShipRuntime targetShip, Vector2Int globalStartPos, Vector2Int globalEndPos) { if (globalStartPos == globalEndPos) { return(false); } NavCell[] overrideStart = null; // Cur, prev and T evaluation if (curPath != null) { if (nextIndex < curPath.Length) { overrideStart = new NavCell[2]; // Store C0 and C1 overrideStart[0] = curPath[nextIndex - 1]; overrideStart[1] = curPath[nextIndex]; } } nextIndex = 1; CellTemplate startCell = targetShip.GetCellByGlobalPos(globalStartPos); CellTemplate endCell = targetShip.GetCellByGlobalPos(globalEndPos); // Invalid path supplied if (startCell == null || endCell == null || startCell.CellState == 0 || endCell.CellState == 0) { return(false); } ShipPiece startPiece = targetShip.GetPieceByGlobalCellPos(globalStartPos); ShipPiece endPiece = targetShip.GetPieceByGlobalCellPos(globalEndPos); NavGrid startGrid = new NavGrid(startPiece); startGrid.Generate(); NavGrid goalGrid = startGrid; if (startPiece != endPiece) { goalGrid = new NavGrid(endPiece); goalGrid.Generate(); } AStarAlgorithm aStarAlgorithm = new AStarAlgorithm(startGrid, goalGrid, globalStartPos, globalEndPos); int newTState = -1; curPath = aStarAlgorithm.AStarSearch(ref newTState, overrideStart); // Either reset, invert or leave move timer switch (newTState) { case -1: moveTimer = 0; break; case 1: moveTimer = 1 - moveTimer; break; } pathTracer.SetPositions(GetNavArray()); return(curPath != null); }
public abstract IEnumerator Traverse(NavCell nav);
private static void BuildNavCellConnectivityGrid( uint colomnCount, uint rowCount, BitArray navMeshData, out NavCell[] navCells, out uint nonEmptyNavCellCount) { UnionFind<uint> navCellUnion = new UnionFind<uint>(); // Create an initial set of nav cells // Any valid cell gets a connectivity id of 0 // Any invalid cell gets a connectivity id of EMPTY_NAV_CELL // Valid nav cells get added to the nav cell union set navCells = new NavCell[rowCount * colomnCount]; nonEmptyNavCellCount = 0; for (int navCellIndex = 0; navCellIndex < navMeshData.Length; ++navCellIndex) { if (navMeshData[navCellIndex]) { uint pvsCellIndex = nonEmptyNavCellCount++; navCells[navCellIndex] = new NavCell(0, pvsCellIndex); navCellUnion.AddElement((uint)navCellIndex); } else { navCells[navCellIndex] = new NavCell(); } } // Union together all neighboring nav cells for (int unionElementIndex = 0; unionElementIndex < navCellUnion.SetSize; ++unionElementIndex) { uint navCellIndex = navCellUnion.GetElement(unionElementIndex); for (MathConstants.eDirection direction = MathConstants.eDirection.first; direction < MathConstants.eDirection.count; ++direction) { uint neighborNavCellIndex; if (TryGetValidNeighborNavCellIndex( navCells, colomnCount, rowCount, navCellIndex, direction, out neighborNavCellIndex)) { navCellUnion.Union(navCellIndex, neighborNavCellIndex); } } } // Write the final connectivity IDs back into the nav cells for (int unionElementIndex = 0; unionElementIndex < navCellUnion.SetSize; ++unionElementIndex) { uint navCellIndex = navCellUnion.GetElement(unionElementIndex); int connectivityID = navCellUnion.FindRootIndex(unionElementIndex); navCells[navCellIndex].connectivityId = (short)connectivityID; } }
/// <summary> /// Gets the center of a given Navigation Cell /// </summary> /// <param name="cell"></param> /// <param name="zone"></param> /// <returns></returns> private Vector3 GetNavCellCenter(NavCell cell, NavZone zone) { return(GetNavCellCenter(cell.Min, cell.Max, zone)); }
public NavZoneDef(MpqFileStream stream) { long x; int NavCellCount = stream.ReadInt32(); stream.Position += 12; var serNavCells = new SerializeData(stream); x = stream.Position; stream.Position = serNavCells.Offset + 16; //Navcells NavCells = new NavCell[NavCellCount]; for (int i = 0; i < NavCellCount; i++) { NavCells[i] = new NavCell(stream); } stream.Position = x; //NavCellLookups int NeighbourCount = stream.ReadInt32(); stream.Position += 12; var serNavCellNeighbours = new SerializeData(stream); x = stream.Position; stream.Position = serNavCellNeighbours.Offset + 16; NavCellNeighbours = new NavCellLookup[NeighbourCount]; for (int i = 0; i < NeighbourCount; i++) { NavCellNeighbours[i] = new NavCellLookup(stream); } stream.Position = x; //NavGridSquares float f0 = stream.ReadFloat(); float f1 = stream.ReadFloat(); int i2 = stream.ReadInt32(); var v0 = new Vector2D(stream); stream.Position += 12; var serGridSquares = new SerializeData(stream); x = stream.Position; stream.Position = serGridSquares.Offset + 16; GridSquares = new NavGridSquare[serGridSquares.Size/6]; for (int i = 0; i < serGridSquares.Size/6; i++) { GridSquares[i] = new NavGridSquare(stream); } stream.Position = x; //cell lookups int i3 = stream.ReadInt32(); stream.Position += 12; var serCellLookups = new SerializeData(stream); x = stream.Position; stream.Position = serCellLookups.Offset + 16; CellLookups = new NavCellLookup[serCellLookups.Size/4]; for (int i = 0; i < serCellLookups.Size/4; i++) { CellLookups[i] = new NavCellLookup(stream); } stream.Position = x; //borderdata int i4 = stream.ReadInt32(); stream.Position += 12; var serBorderData = new SerializeData(stream); x = stream.Position; stream.Position = serBorderData.Offset + 16; BorderData = new NavCellBorderData[serBorderData.Size/4]; for (int i = 0; i < serBorderData.Size/4; i++) { BorderData[i] = new NavCellBorderData(stream); } }
public void ClearCurrent() { CurrentUnit = null; currentNavCell = null; currentHexcell = null; }
public CachedMapCell(NavCell cell) { Passable = cell.Flags.HasFlag(NavCellFlags.AllowWalk); Min = new Vector3(cell.Min.X, cell.Min.Y, cell.Min.Z); Max = new Vector3(cell.Max.X, cell.Max.Y, cell.Max.Z); }
/// <summary> /// /// </summary>找到一条到目标的路径 /// <param name="start">起点</param> /// <param name="end">目标点</param> /// <param name="move">移动力,搜索深度达到一定值就不在搜索</param> /// <returns></returns> public List <NavCell> GetPath(HexCell start, HexCell end, int move, Func <HexCell, bool> func) { int depth = (int)(move * Config.pathDepth); Queue <NavCell> open = new Queue <NavCell>(); List <HexCell> close = new List <HexCell>(); List <NavCell> path = new List <NavCell>(); NavCell startNav = new NavCell(start); startNav.consume = 0; open.Enqueue(startNav); NavCell nav = null; HexCell cell = null; NavCell EndNav = null; while (open.Count > 0) { if (EndNav != null) { break; } nav = open.Dequeue(); if (close.Contains(nav.cell)) { continue; } if (nav.consume > depth) { continue; } for (int i = 0; i < 6; i++) { cell = nav.cell.GetNeighbor(i); if (cell == null) { continue; } if (cell == end) { EndNav = new NavCell(cell, nav); break; } if (!func(cell)) { continue; } NavCell _nav = null; if (open.Count > 0) { _nav = open.FirstOrDefault(a => a.cell == cell); } if (_nav != null) { if (_nav.consume > cell.Consume() + nav.consume) { _nav.ReviseParent(nav); } } else { _nav = new NavCell(cell, nav); open.Enqueue(_nav); } } close.Add(nav.cell); } if (EndNav != null) { while (EndNav.consume > move) { EndNav = EndNav.parent; } while (EndNav != null) { path.Add(EndNav); EndNav = EndNav.parent; } return(path); } return(path); }
/// <summary> /// Gets the center of a given Navigation Cell /// </summary> /// <param name="cell"></param> /// <param name="zone"></param> /// <returns></returns> internal static Vector3 GetNavCellCenter(NavCell cell, NavZone zone) { return GetNavCellCenter(cell.Min, cell.Max, zone); }
/// <summary> /// Gets the size of the nav cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns>System.Double.</returns> public static double GetNavCellSize(this NavCell cell) { var diff = cell.Max.ToVector2() - cell.Min.ToVector2(); return(diff.X * diff.Y); }
/// <summary> /// Gets the center of a given Navigation Cell /// </summary> /// <param name="cell"></param> /// <param name="zone"></param> /// <returns></returns> internal static Vector3 GetNavCellCenter(NavCell cell, NavZone zone) { return(GetNavCellCenter(cell.Min, cell.Max, zone)); }
public bool Equals(NavCell other) { return connectivityId == other.connectivityId && pvsCellIndex == other.pvsCellIndex; }