public DeterministicVector2 Steer(Unit unit, List <Unit> neighbors, List <NavigationEdge> path, Map map) { DeterministicVector2 result = new DeterministicVector2(); foreach (NavigationPolygon poly in map.FloorWithDynamicObjects) { var aabbDist = poly.GetBoundingDistance(unit.Position); if (aabbDist > unit.FunnelSize) { continue; } foreach (var edge in poly.ConstraintedEdges) { var distanceResult = edge.GetDistance(unit.Position); if (distanceResult.Distance < unit.FunnelSize) { var direction = unit.Position - distanceResult.ClosestPoint; var toMove = unit.FunnelSize - distanceResult.Distance; result += direction.Normalize() * toMove; } } } return(result); }
public void Update() { if (map == null) { return; } newPosition = new DeterministicVector2(this.Position); OldPosition = new DeterministicVector2(this.Position); Steering(steeringBehaviours, true); Steering(steeringBehavioursAfterMove, false); if (Path != null) { if ((this.Position - Path[Path.Count - 1].B).GetLength() <= FunnelSize) { Idle(); } else { if (RecalcPathOnNextUpdate) { UnityEngine.Debug.Log("Recalc Path!"); RecalculatePath(lastTo); } } } RecalcPathOnNextUpdate = false; }
public List <AStarNode> CalculatePath(DeterministicVector2 a, DeterministicVector2 b) { AStarContext context = new AStarContext() { A = a, B = b }; var result = constrainedEdgePolygons.CalculateAnyIntersection(new NavigationEdge(context.A, context.B)); if (!result.SegmentsIntersect) { return(new List <AStarNode>() { new AStarNode(a, b), new AStarNode(b, b), }); } List <AStarNode> path = CalculateNaivePath(context); if (path == null) { return(null); } path.Add(new AStarNode(b, b)); path.Insert(0, new AStarNode(a, b)); var resultPath = new List <AStarNode>(path); OptimizePath(resultPath); return(resultPath); }
public DeterministicVector2 Steer(Unit unit, List <Unit> neighbors, List <NavigationEdge> path, Map map) { if (neighbors.Count == 0) { return(new DeterministicVector2()); } DeterministicVector2 toMove = new DeterministicVector2(); foreach (var neighbor in neighbors) { var direction = unit.Position - neighbor.Position; var neededDistance = unit.FunnelSize + neighbor.FunnelSize; var distance = direction.GetLength(); if (distance >= neededDistance) { continue; } var toMoveDistance = (neededDistance - distance) / 10; toMove += direction.Normalize() * toMoveDistance; } return(toMove); }
public Unit(Map map, int id, DeterministicVector2 startingPosition, int playerId) { this.Id = id; Position = startingPosition; OldPosition = startingPosition; PlayerId = playerId; this.newPosition = startingPosition; this.map = map; }
public List <NavigationTriangle> GetTrianglesWithPoint(DeterministicVector2 p) { if (triangleMapping.ContainsKey(p)) { return(triangleMapping[p]); } return(new List <NavigationTriangle>()); }
void UpdateTriangulation(NavigationTriangle t, DeterministicVector2 p) { var v = new DeterministicVector2(p); AllTriangle.Add(new NavigationTriangle(t.U, t.V, v)); AllTriangle.Add(new NavigationTriangle(t.V, t.W, v)); AllTriangle.Add(new NavigationTriangle(t.W, t.U, v)); AllTriangle.Remove(t); }
private void AddTriangleToPointMap(DeterministicVector2 p, NavigationTriangle tri) { if (!triangleMapping.ContainsKey(p)) { triangleMapping.Add(p, new List <NavigationTriangle>()); } triangleMapping[p].Add(tri); }
public AStarNode(DeterministicVector2 position, DeterministicVector2 destination, AStarNode parent = null) { this.Position = position; this.destination = destination; // Using the setter of Parent makes an endless loop! this.parent = parent; if (this.parent != null) { this.G = parent.G + (this.Position - parent.Position).ManhattanHeuristic(); } ConstraintedEdgeNormal = new DeterministicVector2(0, 0); }
public DeterministicVector2 Steer(Unit unit, List <Unit> neighbors, List <NavigationEdge> path, Map map) { if (path == null || path.Count == 0) { return(new DeterministicVector2()); } bool isLastMovementPossible = unit.LastSteering.GetLengthSquared() != 0; DeterministicVector2 naiveNewPosition = unit.Position; DeterministicVector2 lastSteering = unit.LastSteering; if (isLastMovementPossible) { lastSteering = lastSteering.Normalize(); naiveNewPosition += lastSteering; } DeterministicFloat shortestDistance = new DeterministicFloat(long.MaxValue, false); NavigationEdge nearestEdge = new NavigationEdge(); DeterministicVector2 closestPoint = new DeterministicVector2(); for (var i = 0; i < path.Count; i++) { var pathEdge = path[i]; var distanceResult = pathEdge.GetDistance(naiveNewPosition); if (distanceResult.Distance < shortestDistance) { shortestDistance = distanceResult.Distance; nearestEdge = pathEdge; closestPoint = distanceResult.ClosestPoint; if (i > 0) { unit.RecalcPathOnNextUpdate = true; } // naive positioning is on path, we don't need to steer if (isLastMovementPossible && shortestDistance <= PathSize) { return(lastSteering); } } } var dir = nearestEdge.B - nearestEdge.A; return(closestPoint + dir.Normalize() - unit.Position); }
public DeterministicVector2 Steer(Unit unit, List <Unit> neighbors, List <NavigationEdge> path, Map map) { if (neighbors.Count == 0) { return(new DeterministicVector2()); } var smallestDistanceFound = new DeterministicFloat(long.MaxValue, false); var myNewPosition = unit.Position + unit.LastSteering; DeterministicVector2 toMove = new DeterministicVector2(); foreach (var neighbor in neighbors) { // we ignore Units that go the same direction like we do if (unit.LastSteering.DotProduct(neighbor.LastSteering) > new DeterministicFloat(0)) { continue; } var neighborNewPosition = neighbor.Position + neighbor.LastSteering; var distance = (myNewPosition - neighborNewPosition).GetLength(); var fullFunnelSize = unit.FunnelSize + neighbor.FunnelSize; if (distance >= fullFunnelSize) { continue; } if (smallestDistanceFound < distance) { continue; } smallestDistanceFound = distance; var meToNeighbour = neighborNewPosition - myNewPosition; var steeringPerp = unit.LastSteering.PerpendicularClockwise(); var dotMeToNeighbourAndAvade = steeringPerp.DotProduct(meToNeighbour); if (dotMeToNeighbourAndAvade < 0) { steeringPerp *= -1; } var toMoveDistance = fullFunnelSize * 2 - distance; toMove = steeringPerp.Normalize() * toMoveDistance; } return(toMove); }
private void RecalculatePath(DeterministicVector2 to) { this.Path = null; var path = map.Pathfinding.CalculatePath(new DeterministicVector2(Position), to); lastTo = to; if (path != null) { this.Path = new List <NavigationEdge>(); for (int i = 0; i < path.Count - 1; i++) { this.Path.Add(new NavigationEdge(path[i].Position + path[i].ConstraintedEdgeNormal * FunnelSize, path[i + 1].Position + path[i + 1].ConstraintedEdgeNormal * FunnelSize)); } } }
public void MoveTo(DeterministicVector2 moveTarget) { if (map.Pathfinding != null) { var to = new DeterministicVector2(moveTarget); if (Path != null && Path.Count > 0) { if (Path[Path.Count - 1].B == to) { return; } } RecalculatePath(to); } }
private void Steering(List <ISteerBehaviour> behaviours, bool applySpeed) { DeterministicVector2 newSteering = new DeterministicVector2(); foreach (var steeringBehaviour in behaviours) { newSteering += steeringBehaviour.Steer(this, Neighbours, Path, map); } if (applySpeed) { newSteering = newSteering.Normalize(); newSteering *= Speed; } newPosition += newSteering; }
public DeterministicVector2 Steer(Unit unit, List <Unit> neighbors, List <NavigationEdge> path, Map map) { if (neighbors.Count == 0) { return(new DeterministicVector2()); } DeterministicVector2 toMove = new DeterministicVector2(); foreach (var neighbor in neighbors) { toMove += neighbor.LastSteering; } toMove /= neighbors.Count; return(toMove); }
public DeterministicVector2 Steer(Unit unit, List <Unit> neighbors, List <NavigationEdge> path, Map map) { if (neighbors.Count == 0) { return(new DeterministicVector2()); } DeterministicVector2 position = unit.Position; foreach (var neighbor in neighbors) { position += neighbor.Position; } position /= (neighbors.Count + 1); return(position - unit.Position); }
private void AddPointToQueue(DeterministicVector2 trianglePoint, AStarNode parent, AStarContext context) { if (context.AllNodes.ContainsKey(trianglePoint)) { bool readdNeeded = context.NodeQueue.Remove(context.AllNodes[trianglePoint]); context.AllNodes[trianglePoint].Parent = parent; if (readdNeeded) { context.NodeQueue.Add(context.AllNodes[trianglePoint]); } return; } var newNode = new AStarNode(trianglePoint, context.B, parent); context.AllNodes.Add(trianglePoint, newNode); context.NodeQueue.Add(newNode); }
public NavigationTriangle SearchTriangleForPoint(DeterministicVector2 p) { if (searchCache.ContainsKey(p)) { return(searchCache[p]); } for (int i = 0; i < AllTriangle.Count; i++) { var tri = AllTriangle[i]; if (tri.IsPointInTriangle(p)) { searchCache.Add(p, tri); return(tri); } } return(null); }
public void OnDrawGizmos() { if (Map == null) { return; } if (DebugClipper) { DrawPolygons(Map.FloorWithDynamicObjects, Color.green); } if (DebugTriangulation) { Gizmos.color = Color.magenta; for (int i = 0; i < Map.NavigationMesh.AllTriangle.Count; i++) { Gizmos.DrawLine(ToVector(Map.NavigationMesh.AllTriangle[i].U), ToVector(Map.NavigationMesh.AllTriangle[i].V)); Gizmos.DrawLine(ToVector(Map.NavigationMesh.AllTriangle[i].V), ToVector(Map.NavigationMesh.AllTriangle[i].W)); Gizmos.DrawLine(ToVector(Map.NavigationMesh.AllTriangle[i].W), ToVector(Map.NavigationMesh.AllTriangle[i].U)); } } if (DebugPolygons) { for (int i = 0; i < Map.FloorWithDynamicObjects.Count; i++) { Gizmos.color = new Color(i % 2 == 0 ? 0 : 1, i >> 1 % 2 == 0 ? 0 : 1, i >> 2 % 2 == 0 ? 0 : 1); for (var j = 0; j < Map.FloorWithDynamicObjects[i].Count - 1; j++) { Gizmos.DrawLine(ToVector(Map.FloorWithDynamicObjects[i][j]), ToVector(Map.FloorWithDynamicObjects[i][j + 1])); } if (Map.FloorWithDynamicObjects[i].Count > 1) { Gizmos.DrawLine(ToVector(Map.FloorWithDynamicObjects[i][Map.FloorWithDynamicObjects[i].Count - 1]), ToVector(Map.FloorWithDynamicObjects[i][0])); } } } if (DebugPolygonsAABBs) { for (int i = 0; i < Map.FloorWithDynamicObjects.Count; i++) { Gizmos.color = new Color(i % 2 == 0 ? 0 : 1, i >> 1 % 2 == 0 ? 0 : 1, i >> 2 % 2 == 0 ? 0 : 1); var bounding = Map.FloorWithDynamicObjects[i].GetBounding(); var topRight = new DeterministicVector2(bounding.B.X, bounding.A.Y); var bottomLeft = new DeterministicVector2(bounding.A.X, bounding.B.Y); Gizmos.DrawLine(ToVector(bounding.A), ToVector(topRight)); Gizmos.DrawLine(ToVector(topRight), ToVector(bounding.B)); Gizmos.DrawLine(ToVector(bounding.A), ToVector(bottomLeft)); Gizmos.DrawLine(ToVector(bottomLeft), ToVector(bounding.B)); } } if (DebugGrid) { foreach (var cell in Map.Grid.Cells) { if (cell.Type == GridCellType.Free) { Gizmos.color = Color.green; } else if (cell.Type == GridCellType.Building) { Gizmos.color = Color.blue; } else { Gizmos.color = Color.red; } Gizmos.DrawLine(ToVector(new DeterministicVector2(cell.X, cell.Y)), ToVector(new DeterministicVector2(cell.X + 1, cell.Y))); Gizmos.DrawLine(ToVector(new DeterministicVector2(cell.X, cell.Y)), ToVector(new DeterministicVector2(cell.X, cell.Y + 1))); Gizmos.DrawLine(ToVector(new DeterministicVector2(cell.X + 1, cell.Y + 1)), ToVector(new DeterministicVector2(cell.X + 1, cell.Y))); Gizmos.DrawLine(ToVector(new DeterministicVector2(cell.X + 1, cell.Y + 1)), ToVector(new DeterministicVector2(cell.X, cell.Y + 1))); } } }
private Vector3 ToVector(DeterministicVector2 point) { return(new Vector3(point.X.ToFloat(), 0, point.Y.ToFloat())); }
public void CopyNewValuesAfterUpdate() { this.Position = newPosition; this.LastSteering = Position - OldPosition; }