public bool FindShortestPath(NavMeshPoint startPosition, NavMeshPoint endPosition, List <NavMeshLine> pathLines = null) { if (!startPosition.Walkable(this) || !endPosition.Walkable(this)) { return(false); } var startFace = startPosition.face; var endFace = endPosition.face; if (startFace != endFace && pathMatrix[area, startFace, endFace] == null) { return(false); } if (pathLines != null) { pathEdges.Clear(); while (startFace != endFace) { var pathEdge = pathMatrix[area, startFace, endFace]; pathEdges.Add(pathEdge); startFace = pathEdge.face.id; } this.startPosition = startPosition; this.endPosition = endPosition; this.pathLines = pathLines; FindPathCorners(0, pathEdges.Count); this.pathLines = null; } return(true); }
public void MoveTowards(float rotation, float distance) { ClearPathLines(); targetRotation = NavMesh.NearestRotation(targetRotation, rotation); pathEndPoint = navigation.FindTowardsPath(position, rotation, distance, true, pathLines); StartMove(1); }
public NavMeshLine(NavMeshPoint startPoint, float distance, float deltaX, float deltaY, float deltaZ) { this.startPoint = startPoint; this.distance = distance; this.deltaX = deltaX; this.deltaY = deltaY; this.deltaZ = deltaZ; }
public Actor(NavMeshPoint position, float rotation) { this.position = position; this.rotation = rotation; this.targetRotation = rotation; navigation = position.navigation; transform = new GameObject("Actor").transform; RefreshTransformRotation(); RefreshTransformPosition(); }
public void MoveTo(NavMeshPoint position) { ClearPathLines(); navigation.FindShortestPath(this.position, position, pathLines); pathEndPoint = position; if (pathLines.Count > 0) { RefreshTargetRotationFromPathLine(); } StartMove(2); }
private void MoveTowards(NavMeshPoint position, float distance) { if (pathLines != null) { var deltaX = position.x - startPosition.x; var deltaY = position.y - startPosition.y; var deltaZ = position.z - startPosition.z; pathLines.Add(new NavMeshLine(startPosition, distance, deltaX, deltaY, deltaZ)); } endDistance -= distance; startPosition = position; endPosition = position; }
private void MoveTo(NavMeshPoint position) { var deltaX = position.x - startPosition.x; var deltaY = position.y - startPosition.y; var deltaZ = position.z - startPosition.z; if (deltaX != 0 || deltaZ != 0) { var distance = NavMesh.Distance(deltaX, deltaZ); pathLines.Add(new NavMeshLine(startPosition, distance, deltaX, deltaY, deltaZ)); } startPosition = position; }
public NavMeshPoint FindPositionFrom(NavMeshPoint position, float x, float z) { FindFaces(x, x, z, z); foreach (var face in foundFaces) { if (face.Walkable(this)) { if (face.Contains(x, z)) { return(GetPosition(face.id, x, z)); } } } var minX = position.x < x?position.x:x; var maxX = position.x > x?position.x:x; var minZ = position.z < z?position.z:z; var maxZ = position.z > z?position.z:z; FindFaces(minX, maxX, minZ, maxZ); maxCrossEdge = null; maxCrossEdgeRatio = 0; maxCrossStartRatio = 0; var startX = position.x; var startZ = position.z; var deltaX = x - startX; var deltaZ = z - startZ; foreach (var face in foundFaces) { if (face.Walkable(this)) { foreach (var edge in face.edges) { if (!edge.Walkable(this)) { FindMaxCross(edge, startX, startZ, deltaX, deltaZ); } } } } if (maxCrossEdge != null) { return(maxCrossEdge.GetPoint(this, maxCrossEdgeRatio)); } return(position); }
private void FindPathCrosses(NavMeshPoint position, int pathIndex, int pathStart) { for (; pathStart < pathIndex; pathStart++) { var edge = pathEdges[pathStart]; var deltaX = position.x - this.startPosition.x; var deltaZ = position.z - this.startPosition.z; var cross = Cross(edge.deltaX, edge.deltaZ, deltaX, deltaZ); NavMeshPoint crossPosition; if (MinZeroEpsilon < cross && cross < MaxZeroEpsilon) { crossPosition = edge.vert.GetPosition(this, edge.face.id); } else { var startDeltaX = this.startPosition.x - edge.vert.x; var startDeltaZ = this.startPosition.z - edge.vert.z; var startCross = Cross(startDeltaX, startDeltaZ, deltaX, deltaZ); crossPosition = edge.GetPoint(this, startCross / cross); } MoveTo(crossPosition); } MoveTo(position); }
public NavMeshPoint FindTowardsPath(NavMeshPoint position, float rotation, float distance, bool slope, List <NavMeshLine> pathLines = null) { if (!position.Walkable(this)) { return(position); } Vert pathVert = null; Edge pathEdge = null; var pathEdgeRatio = 0f; var pathFace = faces[position.face]; NormalizeRotation(rotation); startPosition = position; endPosition = position; endDistance = distance; this.pathLines = pathLines; while (endDistance > MaxZeroEpsilon) { var deltaX = sinRotation * endDistance; var deltaZ = cosRotation * endDistance; var endX = startPosition.x + deltaX; var endZ = startPosition.z + deltaZ; if (pathVert != null) { foreach (var edge in pathVert.edges) { if (edge.face.Walkable(this)) { var next = edge.next; var edgeRight = edge.Right(endX, endZ); var nextRight = next.Right(endX, endZ); if (edgeRight && nextRight) { pathFace = edge.face; startPosition.face = pathFace.id; pathVert = null; break; } if (!edgeRight && !edge.Walkable(this)) { if (Dot(next.vert.x - endX, next.vert.z - endZ, edge.deltaX, edge.deltaZ) > MaxZeroEpsilon) { pathEdge = edge; pathEdgeRatio = 1; } } else if (!nextRight && !next.Walkable(this)) { if (Dot(endX - next.vert.x, endZ - next.vert.z, next.deltaX, next.deltaZ) > MaxZeroEpsilon) { pathEdge = next; pathEdgeRatio = 0; } } if (pathEdge != null) { pathFace = pathEdge.face; startPosition.face = pathFace.id; pathVert = null; break; } } } if (pathVert != null) { if (slope && pathLines != null) { pathLines.Add(new NavMeshLine(endPosition, endDistance, 0, 0, 0)); } break; } } if (pathEdge != null) { if (!slope) { break; } var ratio = Projection(pathEdge.vert.x, pathEdge.vert.z, pathEdge.deltaX, pathEdge.deltaZ, endX, endZ); if (ratio < MaxZeroEpsilon) { pathVert = pathEdge.vert; ratio = pathEdgeRatio / (pathEdgeRatio - ratio); } else if (MinOneEpsilon < ratio) { pathVert = pathEdge.next.vert; ratio = (1 - pathEdgeRatio) / (ratio - pathEdgeRatio); } else { MoveTowards(pathEdge.GetPoint(this, ratio), endDistance); break; } MoveTowards(pathVert.GetPosition(this, pathFace.id), endDistance * ratio); pathEdge = null; continue; } if (pathFace.Contains(endX, endZ)) { MoveTowards(new NavMeshPoint(this, pathFace.id, endX, pathFace.GetY(endX, endZ), endZ), endDistance); break; } maxCrossEdge = null; maxCrossEdgeRatio = 0; maxCrossStartRatio = 0; foreach (var edge in pathFace.edges) { FindMaxCross(edge, startPosition.x, startPosition.z, deltaX, deltaZ); } if (maxCrossEdge == null) { break; } if (maxCrossEdgeRatio < MaxZeroEpsilon) { pathVert = maxCrossEdge.vert; MoveTowards(pathVert.GetPosition(this, pathFace.id), endDistance * maxCrossStartRatio); } else if (MinOneEpsilon < maxCrossEdgeRatio) { pathVert = maxCrossEdge.next.vert; MoveTowards(pathVert.GetPosition(this, pathFace.id), endDistance * maxCrossStartRatio); } else { MoveTowards(maxCrossEdge.GetPoint(this, maxCrossEdgeRatio), endDistance * maxCrossStartRatio); if (maxCrossEdge.Walkable(this)) { pathFace = maxCrossEdge.pair.face; startPosition.face = pathFace.id; } else { pathEdge = maxCrossEdge; pathEdgeRatio = maxCrossEdgeRatio; } } } this.pathLines = null; return(endPosition); }