public override Goal Suggest(LineSegmentPath path, KinematicData character, Goal goal) { // procurar ponto do segmento mais próximo ao centro da esfera Vector3 closest = path.GetPosition(MathHelper.closestParamInLineSegmentToPoint(path.StartPosition, path.EndPosition, Troll.KinematicData.position)); // Check if we pass through the center point Vector3 newPt; if (closest.sqrMagnitude == 0) { // Get any vector at right angles to the segment Vector3 dirn = path.EndPosition - path.StartPosition; //pode nao ser esta func TO DO Vector3 newdirn = Vector3.Cross(dirn, Vector3.Cross(dirn, Vector3.forward)); newPt = Troll.KinematicData.position + newdirn * TrollRadius * margin; } else { // Otherwise project the point out beyond the radius newPt = (Troll.KinematicData.position + (closest - Troll.KinematicData.position) * TrollRadius * margin) / closest.sqrMagnitude; } // Set up the goal and return goal.position = newPt; return goal; }
public override Goal Suggest(LineSegmentPath path, KinematicData character, Goal goal) { if (this.chars.KinematicData.velocity.sqrMagnitude > 1.5f) { this.chars.KinematicData.velocity *= 0.01f; } return goal; /* // procurar ponto do segmento mais próximo ao centro da esfera Vector3 closest = path.GetPosition(MathHelper.closestParamInLineSegmentToPoint(path.StartPosition, path.EndPosition, chars.KinematicData.position)); // Check if we pass through the center point Vector3 newPt; float i = 1.0f; while (i < 25.0f) { for(int a = 0; a < 360; a++) { float nx = (float) (closest.sqrMagnitude * i * Math.Cos((a * (Math.PI / 180)))); float ny = (float) (closest.sqrMagnitude * i * Math.Sin((a * (Math.PI / 180)))); newPt = new Vector3(nx, closest.y,ny); if (navMeshP.IsPointOnGraph(newPt)) { goal.position = newPt; return goal; } } i = i + 0.25f; } return goal; // Set up the goal and return*/ }
public DynamicFollowPath(KinematicData character, Path path) { this.Target = new KinematicData(); this.Character = character; this.Path = path; this.EmptyMovementOutput = new MovementOutput(); }
public override TargetGoal GetGoal(KinematicData character) { TargetGoal g = new TargetGoal() { position = Target.position + (Target.velocity * LookAhead )}; g.hasPosition = true; return g; }
public DynamicFollowPath(KinematicData character, GlobalPath path) { this.Target = new KinematicData(); this.Character = character; this.globalPath = path; this.CurrentParam = 0.0f; this.PathOffset = 0.2f; this.PredictTime = 0.05f; }
public DynamicFollowPath(KinematicData character) { PathOffset = 0.4f; Target = new KinematicData(); Character = character; EmptyMovementOutput = new MovementOutput { linear = Vector3.zero }; }
public override TargetGoal GetGoal(KinematicData character) { if (!this.hasTarget) return new TargetGoal(); TargetGoal g = new TargetGoal() { position = this.Target.position }; g.hasPosition = true; return g; }
public override TargetGoal Decompose(KinematicData character, TargetGoal goal) { if (!goal.hasPosition) return new TargetGoal(); if (lastGoal == null || !lastGoal.position.Equals(goal.position)) { Astar = new NodeArrayAStarPathFinding(Graph, Heuristic); Astar.InitializePathfindingSearch(character.position, goal.position); CurrentParam = 0.0f; this.lastGoal = goal; } GlobalPath currentSolution; if (Astar.InProgress) { var finished = Astar.Search(out currentSolution, true); if (finished && currentSolution != null) { this.AStarSolution = currentSolution; this.GlobalPath = StringPullingPathSmoothing.SmoothPath(character, currentSolution); this.GlobalPath.CalculateLocalPathsFromPathPositions(character.position); // gets first node goal.position = this.GlobalPath.LocalPaths[0].EndPosition; return goal; } /* else if(currentSolution != null && currentSolution.IsPartial) { goal.position = currentSolution.PathPositions[0]; return goal; }*/ } else { if (GlobalPath.PathEnd(CurrentParam)) { goal.position = GlobalPath.LocalPaths[GlobalPath.LocalPaths.Count - 1].GetPosition(1.0f); return goal; } CurrentParam = GlobalPath.GetParam(character.position, CurrentParam); CurrentParam += GlobalPath.CalculateOffset(CurrentParam); goal.position = GlobalPath.GetPosition(CurrentParam); return goal; } return new TargetGoal(); }
public DynamicFollowPath(KinematicData character, Path path) { //arrive properties this.SlowRadius = 5.0f; this.TimeToTarget = 0.5f; this.TargetRadius = 1.0f; this.MaxAcceleration = 40.0f; this.Target = new KinematicData(); this.Character = character; this.Path = path; this.CurrentParam = 0.0f; this.PathOffset = 0.5f; this.EmptyMovementOutput = new MovementOutput(); }
public override MovementOutput GetMovement() { /*if (targets == null) return new MovementOutput();*/ float shortestTime = Mathf.Infinity; Vector3 deltaPos, deltaVel, closestDeltaPos = new Vector3(), closestDeltaVel = new Vector3(); float closestDistance = 0f, deltaSpeed = 0f, timeToClosest = 0f, closestMinSeparation = 0f; KinematicData closestTarget = new KinematicData(); deltaPos = Target.position - Character.position; deltaVel = Target.velocity - Character.velocity; deltaSpeed = deltaVel.magnitude; if (deltaSpeed == 0) return new MovementOutput(); ; timeToClosest = -(Vector3.Dot(deltaPos,deltaVel))/(deltaSpeed*deltaSpeed); if (timeToClosest > MaxTimeLookAhead) return new MovementOutput(); ; float distance = deltaPos.magnitude; float minSeparation = distance - deltaSpeed*timeToClosest; if (minSeparation > 2 * collisionRadius) return new MovementOutput(); ; if(timeToClosest > 0 && timeToClosest < shortestTime){ shortestTime = timeToClosest; closestTarget = Target; closestMinSeparation = minSeparation; closestDistance = distance; closestDeltaPos = deltaPos; closestDeltaVel = deltaVel; } if(shortestTime == Mathf.Infinity) return new MovementOutput(); Vector3 avoidanceDirection; if(closestMinSeparation <= 0 || closestDistance < 2*collisionRadius) avoidanceDirection = Character.position - closestTarget.position; else avoidanceDirection = (closestDeltaPos + closestDeltaVel * shortestTime)*-1; MovementOutput output = new MovementOutput(); output.linear = avoidanceDirection.normalized*MaxAcceleration; if (PriorityManager.debugMode) Debug.DrawRay(Character.position, avoidanceDirection.normalized * MaxAcceleration, Color.black); return output; }
public override MovementOutput GetMovement() { Direction = this.Target.position - this.Character.position; Distance = Direction.magnitude; if (Distance < StopRadius) { return null; } if (Distance > SlowRadius) { this.TargetSpeed = MaxSpeed; } else { this.TargetSpeed = (MaxSpeed * (Distance / SlowRadius)); } MovingTarget = new KinematicData(); MovingTarget.velocity = Direction.normalized * TargetSpeed; return base.GetMovement(); }
public override Goal Decompose(KinematicData character, Goal goal) { AStarPathfinding Astar = new NodeArrayAStarPathFinding(Graph, Heuristic); Astar.InitializePathfindingSearch(character.position, goal.position); // In goal, ends if (Astar.StartNode.Equals(Astar.GoalNode)) { return goal; } // else, plan GlobalPath currentSolution; if (Astar.InProgress) { var finished = Astar.Search(out currentSolution, true); if (finished && currentSolution != null) { // gets first node goal.position = currentSolution.PathNodes[0].Position; return goal; } } return goal; }
public DynamicAvoidCharacter(KinematicData target) { this.Target = target; this.MaxTimeLookAhead = 1.0f; this.AvoidMargin = 1.0f; }
public void Update() { foreach (var member in this.FlockMembers) { member.Update(); } if (this.Target != null) { var direction = this.Target.position - this.FlockMembers.FirstOrDefault().KinematicData.position; if (direction.sqrMagnitude < 16) { this.Target = null; } } }
public DynamicAvoidObstacle(GameObject collider) { collisionDetector = collider.GetComponent <Collider> (); this.Target = new KinematicData(); }
public DynamicAvoidObstacle(GameObject obstacle) { Target = new KinematicData(); AvoidObstacle = obstacle; }
public DynamicAvoidCharacter(KinematicData otherCharacter) { this.OtherCharacter = otherCharacter; this.MaxTimeLookAhead = 0.005f; }
// Use this for initialization void Start() { var textObj = GameObject.Find("InstructionsText"); if (textObj != null) { textObj.GetComponent <Text>().text = "Instructions\n\n" + "Blue Character\n" + "Q - Stationary\n" + "W - Seek\n" + "E - Flee\n" + "R - Arrive\n" + "T - Wander\n\n" + "Green Character\n" + "A - Stationary\n" + "S - Seek\n" + "D - Flee\n" + "F - Arrive\n" + "G - Wander\n"; } // Associating and intializing the movement to the Game Objects in the scene var blueObj = GameObject.Find("Blue"); if (blueObj != null) { this.BlueCharacter = new DynamicCharacter(blueObj) { Drag = DRAG, MaxSpeed = MAX_SPEED } } ; var greenObj = GameObject.Find("Green"); if (greenObj != null) { this.GreenCharacter = new DynamicCharacter(greenObj) { Drag = DRAG, MaxSpeed = MAX_SPEED } } ; this.BlueMovementText = GameObject.Find("BlueMovement").GetComponent <Text>(); this.GreenMovementText = GameObject.Find("GreenMovement").GetComponent <Text>(); #region movement initialization var blueKinematicData = new KinematicData(new StaticData(this.BlueCharacter.GameObject.transform.position)); var greenKinematicData = new KinematicData(new StaticData(this.GreenCharacter.GameObject.transform.position)); this.BlueDynamicSeek = new DynamicSeek { Character = blueKinematicData, Target = this.GreenCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION }; this.BlueDynamicFlee = new DynamicFlee { Character = blueKinematicData, Target = this.GreenCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION }; this.BlueDynamicWander = new DynamicWander { Character = blueKinematicData, DebugTarget = this.blueDebugTarget, WanderRate = MathConstants.MATH_PI_2, WanderOffset = 4, WanderRadius = 5, MaxAcceleration = MAX_ACCELERATION }; this.BlueDynamicArrive = new DynamicArrive { Character = blueKinematicData, Target = this.GreenCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION, stopRadius = 5, slowRadius = 15 }; this.GreenDynamicSeek = new DynamicSeek { Character = greenKinematicData, Target = this.BlueCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION }; this.GreenDynamicFlee = new DynamicFlee { Character = greenKinematicData, Target = this.BlueCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION }; this.GreenDynamicWander = new DynamicWander { Character = greenKinematicData, DebugTarget = greenDebugTarget, WanderRate = MathConstants.MATH_2_PI, WanderOffset = 10, WanderRadius = 5, MaxAcceleration = MAX_ACCELERATION }; this.GreenDynamicArrive = new DynamicArrive { Character = greenKinematicData, Target = this.BlueCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION, stopRadius = 5, slowRadius = 15 }; #endregion } void Update() { if (Input.GetKeyDown(KeyCode.Q)) { this.BlueCharacter.Movement = null; } else if (Input.GetKeyDown(KeyCode.W)) { this.BlueCharacter.Movement = this.BlueDynamicSeek; } else if (Input.GetKeyDown(KeyCode.E)) { this.BlueCharacter.Movement = this.BlueDynamicFlee; } else if (Input.GetKeyDown(KeyCode.T)) { this.BlueCharacter.Movement = this.BlueDynamicWander; } else if (Input.GetKeyDown(KeyCode.R)) { this.BlueCharacter.Movement = this.BlueDynamicArrive; } if (Input.GetKeyDown(KeyCode.A)) { this.GreenCharacter.Movement = null; } else if (Input.GetKeyDown(KeyCode.S)) { this.GreenCharacter.Movement = this.GreenDynamicSeek; } else if (Input.GetKeyDown(KeyCode.D)) { this.GreenCharacter.Movement = this.GreenDynamicFlee; } else if (Input.GetKeyDown(KeyCode.G)) { this.GreenCharacter.Movement = this.GreenDynamicWander; } else if (Input.GetKeyDown(KeyCode.F)) { this.GreenCharacter.Movement = this.GreenDynamicArrive; } this.UpdateMovingGameObject(this.BlueCharacter); this.UpdateMovingGameObject(this.GreenCharacter); // Debugging objects if (this.blueDebugTarget != null && this.BlueCharacter.Movement != null) { this.blueDebugTarget.transform.position = this.BlueCharacter.Movement.Target.position; } if (this.greenDebugTarget != null && this.GreenCharacter.Movement != null) { this.greenDebugTarget.transform.position = this.GreenCharacter.Movement.Target.position; } this.UpdateMovementText(); }
public RVOMovement(DynamicMovement.DynamicMovement goalMovement, List <KinematicData> movingCharacters, List <KinematicData> obstacles, KinematicData character) { this.DesiredMovement = goalMovement; this.CharacterSize = 3f; this.NumberOfSamples = 5; this.Weight = 2; this.IgnoreDistance = 5f; this.Character = character; this.Characters = movingCharacters; this.Characters.Remove(this.Character); this.ObsStart = this.Characters.Count; this.Characters.AddRange(obstacles); base.Target = new KinematicData(); this.Output = new MovementOutput(); this.samples = new List <Vector3>(); //initialize other properties if you think is relevant }
public DynamicAvoidCharacter(KinematicData target) { Target = target; this.Output = new MovementOutput(); LookAhead = 2.0f; }
public DynamicFollowPath(KinematicData character, Path path) : this() { this.Character = character; this.Path = path; }
public DynamicWander() { this.TurnAngle = 0.5f; Target = new KinematicData(); }
public DynamicAvoidCharacter(KinematicData target) { this.Target = target; this.Output = new MovementOutput(); }
public SteeringPipeline InitializeSteeringPipeline(DynamicCharacter orig, KinematicData dest) { //Pipeline SteeringPipeline pipe = new SteeringPipeline(orig.KinematicData) { MaxAcceleration = 15.0f }; //Targeter Targeter MouseClickTargeter = new Targeter() { Target = dest }; pipe.Targeters.Add(MouseClickTargeter); //Decomposer pathfindingDecomposer = new PathfindingDecomposer() { Graph = this.navMesh, Heuristic = new EuclideanDistanceHeuristic() }; pipe.Decomposers.Add(pathfindingDecomposer); //Actuator - Default: Car behaviour Actuator actuator = new CarActuator() { MaxAcceleration = 15.0f, Character = orig.KinematicData }; if (orig.GameObject.tag.Equals("Enemies")) { actuator = new TrollActuator() { MaxAcceleration = 10.0f, Character = orig.KinematicData }; } pipe.Actuator = actuator; //Constraints foreach (DynamicCharacter troll in enemies) { TrollConstraint trollConstraint = new TrollConstraint() { Troll = troll, margin = 1.0f }; pipe.Constraints.Add(trollConstraint); } MapConstraint mapConstraint = new MapConstraint() { chars = character, navMeshP = navMesh, margin = 1.0f }; pipe.Constraints.Add(mapConstraint); return(pipe); }
public DynamicAvoidCharacter(KinematicData t) { this.Target = t; }
public DynamicCohesion() { Target = new KinematicData(); }
public DynamicArrive() { MovingTarget = new KinematicData (); this.SlowRadius = 20.0f; this.StopRadius = 1.0f; }
public DynamicFlockVelocityMatch() { MovingTarget = new KinematicData(); }
public abstract Goal Suggest(LineSegmentPath path, KinematicData character, Goal goal);
public DynamicStop(KinematicData character) { this.Target = character; this.Character = character; this.Delta = 0.05f; }
public DynamicAvoidCharacter(KinematicData OtherCharacter) { this.OtherCharacter = OtherCharacter; this.Target = OtherCharacter; this.Output = new MovementOutput(); }
public DynamicAvoidSphere(GameObject obstacle, KinematicData target) { this.Obstacle = obstacle; this.Target = target; }
private Vector3 getBestSample(Vector3 desiredVelocity, List <Vector3> samples) { Vector3 bestSample = Vector3.zero; Vector3 charPos = Character.Position; Vector3 charVel = Character.velocity; float minimumPenalty = Mathf.Infinity; float maximumTimePenalty = 0f; float timePenalty = 0f; int CharacterCount = Characters.Count; foreach (Vector3 sample in samples) { float distancePenalty = (desiredVelocity - sample).magnitude; Vector3 sample_charVel = 2 * sample - charVel; maximumTimePenalty = 0f; for (int i = 0; i < CharacterCount; i++) { KinematicData b = Characters[i]; Vector3 bPos = b.Position; bool isObstacle = i >= ObsStart; if ((bPos - charPos).magnitude > IgnoreDistance) { continue; } float TimeToCollision = MathHelper.TimeToCollisionBetweenRayAndCircle(charPos, sample_charVel - (isObstacle ? charVel.normalized : b.velocity), bPos, CharacterSize * (isObstacle ? 1.5f : 1f)); if (TimeToCollision > TTC_TOLERANCE) { timePenalty = (Weight * (isObstacle ? 3f : 1f)) / TimeToCollision; } else if (TimeToCollision >= 0f) { timePenalty = Mathf.Infinity; } else { timePenalty = 0f; } maximumTimePenalty = timePenalty > maximumTimePenalty ? timePenalty : maximumTimePenalty; float penalty = distancePenalty + maximumTimePenalty; if (penalty <= 0.1f) { return(sample); } if (penalty < minimumPenalty) { minimumPenalty = penalty; bestSample = sample; } } } return(bestSample); }
public override MovementOutput GetMovement() { var output = new MovementOutput(); float shortestTime = 99999999f; float closestMinSeparation = 999990f; float closestDistance = 9999999f; Vector3 closestDeltaPos = new Vector3(); Vector3 closestDeltaVel = new Vector3(); KinematicData closestTarget = new KinematicData(); Vector3 avoidanceDirection = new Vector3(); foreach (DynamicCharacter obstacle in obstacles) { if (obstacle.KinematicData != this.Character) { Vector3 tpos = obstacle.KinematicData.position; Vector3 deltapos = tpos - Character.position; Vector3 deltavel = tpos - Character.velocity; float deltaSpeed = deltavel.sqrMagnitude; if (deltaSpeed == 0) { continue; } float timetoclosest = -Vector3.Dot(deltapos, deltavel) / (deltaSpeed * deltaSpeed); if (timetoclosest > MaxLookAhead) { continue; } float distance = deltapos.sqrMagnitude; float minSeparation = distance - deltaSpeed * timetoclosest; if (minSeparation > 2 * AvoidMargin) { continue; } if (timetoclosest > 0 && timetoclosest < shortestTime) { shortestTime = timetoclosest; closestTarget = obstacle.KinematicData; closestMinSeparation = minSeparation; closestDistance = distance; closestDeltaPos = deltapos; closestDeltaVel = deltavel; } } } if (shortestTime == 99999999f) { return new MovementOutput(); } if ((closestMinSeparation <= 0f) || closestDistance < 2f * AvoidMargin) { avoidanceDirection = Character.position - closestTarget.position; } else { avoidanceDirection = (closestDeltaPos + closestDeltaVel * shortestTime) * -1; } output = new MovementOutput(); output.linear = avoidanceDirection.normalized * MaxAcceleration; return output; }
public abstract TargetGoal GetGoal(KinematicData character);
public override MovementOutput GetMovement() { Vector3 averageVelocity = new Vector3(); float closeBoids = 0; foreach (DynamicCharacter boid in Flock) { if (this.Character != boid.KinematicData) { Direction = boid.KinematicData.position - this.Character.position; if (Direction.magnitude <= Radius) { float angle = Util.MathHelper.ConvertVectorToOrientation(Direction); AngleDifference = Util.MathHelper.ShortestAngleDifference(Character.orientation, angle); if (Mathf.Abs(AngleDifference) <= FanAngle) { averageVelocity += boid.KinematicData.velocity; closeBoids++; } } } } if (closeBoids == 0) { return new MovementOutput(); } averageVelocity /= closeBoids; MovingTarget = new KinematicData(); this.MovingTarget.velocity = averageVelocity; return base.GetMovement(); }
public abstract TargetGoal Decompose(KinematicData character, TargetGoal goal);
public DynamicAvoidCharacter(KinematicData target) { this.Other = target; }
public DynamicAvoidCharacter(KinematicData NewTarget) { AvoidMargin = 1f; CollisionRadius = 3f; TargetCharacter = NewTarget; }
public void InitializeMovement(GameObject[] obstacles, List <DynamicCharacter> characters) { target = new KinematicData(); foreach (var obstacle in obstacles) { //TODO: add your AvoidObstacle movement here var avoidObstacleMovement = new DynamicAvoidObstacle(obstacle) { MaxAcceleration = MAX_ACCELERATION, MaxLookAhead = MAX_LOOK_AHEAD, AvoidMargin = AVOID_MARGIN, Character = this.character.KinematicData, DebugColor = Color.magenta }; this.blendedMovement.Movements.Add(new MovementWithWeight(avoidObstacleMovement, 1000000000000000000000000000000000000.0f)); } //foreach (var boid in characters) //{ //TODO: add your AvoidObstacle movement here var separationMovement = new DynamicSeparation() { MaxAcceleration = MAX_ACCELERATION, Character = this.character.KinematicData, Radius = RADIUS_SEPARATION, Flock = characters, SeparationFactor = SEPARATION_FACTOR }; this.blendedMovement.Movements.Add(new MovementWithWeight(separationMovement, 5.0f)); var cohesionMovement = new DynamicCohesion() { MaxAcceleration = MAX_ACCELERATION, Character = this.character.KinematicData, radius = RADIUS_COHESION, flock = characters, fanAngle = FAN_ANGLE, Target = target }; this.blendedMovement.Movements.Add(new MovementWithWeight(cohesionMovement, 0.2f)); var velocityMatchingMovement = new FlockVelocityMatching() { MaxAcceleration = MAX_ACCELERATION, Character = this.character.KinematicData, Radius = RADIUS_VELOCITY_MATCHING, Flock = characters, FanAngle = FAN_ANGLE, Target = target }; this.blendedMovement.Movements.Add(new MovementWithWeight(velocityMatchingMovement, 0.5f)); //} this.character.Movement = this.blendedMovement; }
public DynamicAvoidCharacter(KinematicData otherChar) { OtherCharaterData = otherChar; }
public PriorityMovement(KinematicData character, List <DynamicMovement.DynamicMovement> movements) { Character = character; Movements = movements; }
public DynamicAvoidCharacter(KinematicData target) { Target = target; }
public DynamicVelocityMatch() { MovingTarget = new KinematicData(); this.TimeToTargetSpeed = 0.5f; }
public DynamicAvoidCharacter(KinematicData other) { this.Output = new MovementOutput(); this.OtherCharacter = other; }
public PriorityMovement(KinematicData character, List<DynamicMovement.DynamicMovement> movements) { Character = character; Movements = movements; }
public abstract Goal Decompose(KinematicData character, Goal goal);