public CellPath(CellPath existedPath, CellContent newConnection) { this.start = existedPath.start; this.connections = new List <CellContent>(existedPath.connections); this.connections.Add(newConnection); this.path = new List <Cell>(existedPath.path); this.path.Add(newConnection.connection); }
public override void Work() { GetStartValues(); CheckChunkPath(); if (ReferenceEquals(startCell, endCell)) { Path path = new Path(start_v3, (MoveState)(int)startCell.passability); path.AddMove(end_v3, (MoveState)(int)startCell.passability); path.RemoveFirst(); agent.ReceivePath(path); callBack.Invoke(); return; } GeneratePaths(); if (potentialPaths.Count == 0) { Debug.Log("no path"); callBack.Invoke(); return; } CellPath targetCellPath = potentialPaths.OrderBy(val => val.gh).First(); funnelPath = new Path(start_v3, (MoveState)(int)targetCellPath.path.First().passability); if (applyRaycast) { RaycastHitNavMesh rhnm; Cell c = targetCellPath.connections[0].from; Raycast(start_v3, end_v3 - start_v3, out rhnm, Vector3.Distance(start_v3, end_v3), raycastIterations, c.passability, c.area, c); if (!rhnm.isOnGraph) { //Debuger_K.AddLine(start_v3, rhnm.point, Color.green); //Debuger_K.AddDot(rhnm.point, Color.green, 0.2f); funnelPath.AddMove(end_v3, (MoveState)(int)c.passability); } else { FunnelPath(targetCellPath, end_v3); //Debuger_K.AddLine(start_v3, rhnm.point, Color.red); //Debuger_K.AddDot(rhnm.point, Color.red, 0.2f); } } else { FunnelPath(targetCellPath, end_v3); } //FunnelPath(targetCellPath, end_v3); agent.ReceivePath(funnelPath); callBack.Invoke(); }
protected void AddCellNode(CellPath node) { LinkedListNode <CellPath> targetNode = null; for (LinkedListNode <CellPath> currentPath = linkedPaths.First; currentPath != null && currentPath.Value.gh < node.gh; currentPath = currentPath.Next) { targetNode = currentPath; } if (targetNode == null) { linkedPaths.AddFirst(node); } else { linkedPaths.AddAfter(targetNode, node); } }
protected void FunnelPath(CellPath path, Vector3 endV3) { List <Cell> cellPath = path.path; List <CellContent> cellPathConnections = path.connections; #if UNITY_EDITOR if (Debuger_K.debugPath) { for (int i = 0; i < cellPath.Count - 1; i++) { Debuger_K.AddPath(cellPath[i].centerV3 + Vector3.up, cellPath[i + 1].centerV3 + Vector3.up, Color.magenta, 0.1f); } } #endif int keyGate = 0; while (true) { if (keyGate >= cellPathConnections.Count) { break; } int curKeyGate; List <CellContentGenericConnection> gateSiquence = new List <CellContentGenericConnection>(); for (curKeyGate = keyGate; curKeyGate < cellPathConnections.Count; curKeyGate++) { var c = cellPathConnections[curKeyGate]; if (c is CellContentGenericConnection) { gateSiquence.Add((CellContentGenericConnection)c); } else { break; } } if (keyGate != curKeyGate) { DoFunnelIteration(funnelPath.lastV3, curKeyGate == cellPathConnections.Count ? endV3 : (cellPathConnections[curKeyGate] as CellContentPointedConnection).enterPoint, gateSiquence); } if (curKeyGate != cellPathConnections.Count) { if (cellPathConnections[curKeyGate] is CellContentPointedConnection) { CellContentPointedConnection ju = cellPathConnections[curKeyGate] as CellContentPointedConnection; if (ju.jumpState == ConnectionJumpState.jumpUp) { funnelPath.AddMove(ju.lowerStandingPoint, (MoveState)(int)ju.from.passability); funnelPath.AddJumpUp(ju.lowerStandingPoint, ju.axis); funnelPath.AddMove(ju.exitPoint, (MoveState)(int)ju.connection.passability); } else { funnelPath.AddMove(ju.enterPoint, (MoveState)(int)ju.from.passability); funnelPath.AddMove(ju.axis, (MoveState)(int)ju.from.passability); funnelPath.AddJumpDown(ju.axis, ju.lowerStandingPoint); funnelPath.AddMove(ju.exitPoint, (MoveState)(int)ju.connection.passability); } } else { Debug.LogErrorFormat("idk type of CellConnectionAbstract node {0}", cellPathConnections[curKeyGate].GetType().Name); } } keyGate = curKeyGate + 1; } funnelPath.AddMove(endV3, (MoveState)(int)cellPath[cellPath.Count - 1].passability); #if UNITY_EDITOR if (Debuger_K.debugPath) { var resultNodes = funnelPath.nodes; for (int i = 0; i < resultNodes.Count - 1; i++) { Debuger_K.AddPath(resultNodes[i].positionV3, resultNodes[i + 1].positionV3, Color.green); } //for (int i = 0; i < resultNodes.Count; i++) { // Debuger3.AddDot(resultNodes[i].positionV3, Color.green, 0.03f, DebugGroup.path); // Debuger3.AddLabel(resultNodes[i].positionV3, resultNodes[i].ToString(), DebugGroup.path); //} } #endif funnelPath.RemoveFirst(); }
private void GeneratePaths() { CellPath path = new CellPath(startCell, start_v3); if (startCell == endCell) { potentialPaths.Add(path); return; } #if UNITY_EDITOR float totalDist = Debuger_K.doDebug ? Vector3.Distance(start_v3, end_v3) : 0f; #endif path.h = EuclideanDistance(start_v3); excluded.Clear(); excluded.Add(startCell); foreach (var connection in startCell.connections) { CellPath newPath = new CellPath(path, connection); newPath.g = connection.Cost(properties, ignoreCrouchCost); if (connection is CellContentPointedConnection) { newPath.h = EuclideanDistance((connection as CellContentPointedConnection).exitPoint); } else { newPath.h = EuclideanDistance(connection.connection); } AddCellNode(newPath); } int limit = 0; while (true) { limit++; if (limit > 1500) { Debug.Log("limit > 1500"); break; } CellPath current = TakeCellNode(); if (current == null) { break; } Cell currentCell = current.last; if (currentCell == endCell) { potentialPaths.Add(current); #if UNITY_EDITOR if (Debuger_K.doDebug) { float lerped = Mathf.InverseLerp(0, totalDist, Vector3.Distance(end_v3, currentCell.centerV3)); Debuger_K.AddPath(current.path[current.path.Count - 2].centerV3 + Vector3.up, current.path[current.path.Count - 1].centerV3 + Vector3.up, new Color(lerped, 1 - lerped, 0, 1f)); } #endif if (potentialPaths.Count >= maxPaths) { break; } else { continue; } } if (excluded.Contains(currentCell)) { continue; } else { excluded.Add(currentCell); } #if UNITY_EDITOR if (Debuger_K.doDebug) { float lerped = Mathf.InverseLerp(0, totalDist, Vector3.Distance(end_v3, currentCell.centerV3)); Debuger_K.AddPath(current.path[current.path.Count - 2].centerV3 + (Vector3.up * 0.3f), current.path[current.path.Count - 1].centerV3 + (Vector3.up * 0.3f), new Color(lerped, 1 - lerped, 0, 1f)); } #endif foreach (var connection in currentCell.connections) { Cell newCell = connection.connection; if (current.Contains(newCell) == false) { CellPath newPath = new CellPath(current, connection); #if UNITY_EDITOR if (Debuger_K.debugPath) { Debuger_K.AddLabel(SomeMath.MidPoint(current.last.centerV3, newCell.centerV3), connection.Cost(properties, ignoreCrouchCost), DebugGroup.path); } #endif newPath.g = current.g + connection.Cost(properties, ignoreCrouchCost); if (connection is CellContentPointedConnection) { newPath.h = EuclideanDistance((connection as CellContentPointedConnection).exitPoint); //Debuger3.AddLabel((connection as CellPointedConnection).exitPoint, newPath.h); } else { newPath.h = EuclideanDistance(connection.connection); } AddCellNode(newPath); } } } }
//just use Dijkstra to find nearest cover private List <NodeCoverPoint> SearchCover() { List <NodeCoverPoint> result = new List <NodeCoverPoint>(); CellPath path = new CellPath(startCell, start_v3); if (startCell.covers != null) { result.AddRange(startCell.covers); } excluded.Add(startCell); foreach (var connection in startCell.connections) { CellPath newPath = new CellPath(path, connection); newPath.g = connection.Cost(start_v3, properties, ignoreCrouchCost); AddCellNode(newPath); } while (true) { CellPath current = TakeCellNode(); if (current == null || current.g > maxMoveCost) { break; } Cell currentCell = current.last; if (excluded.Contains(currentCell)) { continue; } else { excluded.Add(currentCell); } #if UNITY_EDITOR if (Debuger_K.debugPath) { Debuger_K.AddPath(current.path[current.path.Count - 2].centerV3, current.path[current.path.Count - 1].centerV3, Color.green); } #endif if (currentCell.covers != null) { result.AddRange(currentCell.covers); } foreach (var connection in currentCell.connections) { Cell newCell = connection.connection; if (current.Contains(newCell) == false) { CellPath newPath = new CellPath(current, connection); newPath.g = current.g + connection.Cost(properties, ignoreCrouchCost); AddCellNode(newPath); } } } return(result); }