/// <summary> /// Evade using the target's position and it's velocity /// </summary> public SteeringOutput Evade(AutonomousAgent character, Vector3 targetPosition, Vector3 velocityOfTarget) { SteeringOutput output = new SteeringOutput(); // it calculates how long it would take the agent to get to the postion of the target // with the current speed. If that is too much it limits that down to maxPrediction. // We need that time to calculate where the target will be in the future in that time // so we can set the target to that position and flee from it. float distance = (targetPosition - character.transform.position).magnitude; float agentSpeed = character.Velocity.magnitude; float prediction; if (agentSpeed <= distance / maxPrediction) { prediction = maxPrediction; } else { prediction = distance / agentSpeed; } // in which direction to evade Vector3 evadeDirection = character.transform.position - (targetPosition + velocityOfTarget * prediction); // what velocity we want to reach Vector3 targetVelocity; // target is out of detection radius if (distance > detectionRadius) { targetVelocity = new Vector3(); } else { targetVelocity = evadeDirection.normalized * character.maxSpeed; } // make acceleration output.linear = targetVelocity - character.Velocity; output.linear /= timeToTarget; return(output); }
public SteeringOutput Seperate(AutonomousAgent character, Vector3 targetPostion) { SteeringOutput steering = new SteeringOutput(); int count = Physics2D.OverlapCircleNonAlloc(character.transform.position, targetRadius, collidedWith, 1 << layerMask); for (int i = 0; i < count; i++) { // not the same gameobject tht we are currently inspecting if (!collidedWith[i].gameObject.Equals(character.gameObject)) { float distance = Vector3.Distance(character.transform.position, collidedWith[i].transform.position); float strength = Mathf.Min(character.maxAcceleration, decayCoefficient * distance * distance); steering.linear += strength * (character.transform.position - collidedWith[i].transform.position).normalized; } } return(steering); }
public SteeringOutput Seek(AutonomousAgent character, Vector3 targetPostion) { SteeringOutput steering = new SteeringOutput(); // Get the direction Vector3 direction = targetPostion - character.transform.position; float distance = direction.magnitude; // We are inside stopping radius if (distance < targetRadius) { steering.linear = -character.Velocity; return(steering); } float targetSpeed; // We are inside the slowdown radius but not the stopping radius if (distance < slowDownRadius) { // start slowing down linearly targetSpeed = distance / (slowDownRadius - targetRadius) * character.maxSpeed; } else // we are outside of slow down radius { targetSpeed = character.maxSpeed; } // combines the direction and the speed Vector3 targetVelocity = direction.normalized; targetVelocity *= targetSpeed; // Calculate acceleration because we can't just change speed immediatly // Calculate delta v then divide it by t because a = v / t steering.linear = targetVelocity - character.Velocity; steering.linear /= timeToTarget; return(steering); }
public SteeringOutput Wander(AutonomousAgent character, WeightedSteeringBehaviour agentLocalBehaviour) { SteeringOutput output = new SteeringOutput(); // update wander angle with [-wanderRate;wanderRate] agentLocalBehaviour.wanderAngle += (UnityEngine.Random.value * 2f - 1f) * wanderRate; Vector3 targetCircleCenter = character.transform.position + character.transform.up * wanderOffset; // move from center of circle by a vector with wanderAngle angle and wanderRadius length Vector3 targetOnCircleLocation = targetCircleCenter + Quaternion.Euler(0, 0, agentLocalBehaviour.wanderAngle) * character.transform.up * wanderRadius; if (character.showGizmos) { Debug.DrawLine(character.transform.position, targetOnCircleLocation, Color.red); } // get rotation output = Face(character, targetOnCircleLocation); // set linear to full acceleration ahead output.linear = character.transform.up * character.maxAcceleration; return(output); }
public SteeringOutput FollowPath(AutonomousAgent character, WeightedSteeringBehaviour agentLocalBehaviour) { SteeringOutput output = new SteeringOutput(); // Debug.Log(agentLocalBehaviour.currentPathStation + " " + agentLocalBehaviour.path.GetNextStationIndex(agentLocalBehaviour.currentPathStation)); switch (followType) { case FollowType.Station: #region Station // in agentLocalBehaviour we store the current station that is being followed // so we need to check whether the agent is closer to that station or the next one // to check that we need to get the position // if the current path is farther away then the next path if ((agentLocalBehaviour.path.GetDistanceFromPathTo(character.transform.position, agentLocalBehaviour.currentPathStation) > agentLocalBehaviour.path.GetDistanceFromPathTo(character.transform.position, agentLocalBehaviour.path.GetNextStationIndex(agentLocalBehaviour.currentPathStation))) // or we have reached the station || Vector3.Distance(character.transform.position, agentLocalBehaviour.path.GetStationPosition(agentLocalBehaviour.currentPathStation)) <= targetRadius) { // make the next station the target agentLocalBehaviour.currentPathStation = agentLocalBehaviour.path.GetNextStationIndex(agentLocalBehaviour.currentPathStation); } output = Seek(character, agentLocalBehaviour.path.GetStationPosition(agentLocalBehaviour.currentPathStation)); #endregion break; case FollowType.AlwaysReachStation: #region AlwaysReachStation // we have reached the station if (Vector3.Distance(character.transform.position, agentLocalBehaviour.path.GetStationPosition(agentLocalBehaviour.currentPathStation)) <= targetRadius) { // make the next station the target agentLocalBehaviour.currentPathStation = agentLocalBehaviour.path.GetNextStationIndex(agentLocalBehaviour.currentPathStation); } output = Seek(character, agentLocalBehaviour.path.GetStationPosition(agentLocalBehaviour.currentPathStation)); #endregion break; case FollowType.Path: #region Path // here we look ahead on the path with followAheadPercent and set that as a target float percent = agentLocalBehaviour.path.GetClosestPointOnPathPercent(character.transform.position); Vector3 target = agentLocalBehaviour.path.GetPointOnPathPercent(percent + followAheadPercent); output = Seek(character, target); if (character.showGizmos) { Debug.DrawLine(character.transform.position, target, Color.green); } #endregion break; case FollowType.PredictivePath: #region Predictive Path percent = agentLocalBehaviour.path.GetClosestPointOnPathPercent(character.transform.position + character.Velocity * predictTime); target = agentLocalBehaviour.path.GetPointOnPathPercent(percent + followAheadPercent); output = Seek(character, target); if (character.showGizmos) { Debug.DrawLine(character.transform.position, character.transform.position + character.Velocity * predictTime, Color.yellow); Debug.DrawLine(character.transform.position, target, Color.green); } #endregion break; } return(output); }
public void Update(SteeringOutput steering, GameTime time, Game game) { newState = Keyboard.GetState(); bool keyPressed = false; if (game.playerHunter.health > 0 && game.playerHunter.spearJab == false && game.playerHunter.spearThrow == false) { if (Game.keyboard.IsKeyDown(Keys.A)) { velocity.X -= maxAcceleration; keyPressed = true; } if (Game.keyboard.IsKeyDown(Keys.D)) { velocity.X += maxAcceleration; keyPressed = true; } if (Game.keyboard.IsKeyDown(Keys.W)) { velocity.Y -= maxAcceleration; keyPressed = true; } if (Game.keyboard.IsKeyDown(Keys.S)) { velocity.Y += maxAcceleration; keyPressed = true; } } if (game.playerHunter.spearJab == true || game.playerHunter.spearThrow == true) { for (int i = 0; i < game.deerManager.GetDeerCount(); i++) { Deer d = (Deer)game.deerManager.deers[i]; dirFromSpear = (d.Position - this.Position); float distance = dirFromSpear.Length(); if (distance < 30) { game.deerManager.KillDeer(d); game.playerHunter.spearJab = false; game.playerHunter.spearThrow = false; break; } } float distStoL = (game.lion.Position - this.Position).Length(); if (distStoL < 30) { if (game.playerHunter.spearJab) { game.lion.health -= 2; game.playerHunter.spearJab = false; } if (game.playerHunter.spearThrow) { game.lion.health -= 1; game.playerHunter.spearThrow = false; } } } if (game.playerHunter.spearJab && game.playerHunter.health > 0) { keyPressed = true; getPosition = this.position; Vector2 movement = game.playerHunter.Velocity; movement.X += 12 * (float)Math.Cos(game.playerHunter.orientation); movement.Y += (12 * (float)Math.Sin(game.playerHunter.orientation)); move += 3; if (move < jabDistance) { this.position = getPosition; this.position.X += ((int)movement.X); this.position.Y += ((int)movement.Y); } else { this.position = game.playerHunter.Position; this.position.X += 40; this.position.Y -= 20; move = 0; game.playerHunter.spearJab = false; } } if (game.playerHunter.spearThrow && game.playerHunter.health > 0) { //game.playerHunter.spearThrow = true; Vector2 movement = Vector2.Zero; getPosition = this.position; movement = game.playerHunter.throwVelocity; movement.X += 8 * (float)Math.Cos(game.playerHunter.throwOrientation); movement.Y += (8 * (float)Math.Sin(game.playerHunter.throwOrientation)); keyPressed = true; move += 4; if (move < throwDistance) { this.position = getPosition; this.position.X += ((int)movement.X); this.position.Y += ((int)movement.Y); } else { this.position = game.playerHunter.Position; this.position.X += 40; this.position.Y -= 20; move = 0; game.playerHunter.spearThrow = false; } } if (!keyPressed) { this.position = game.playerHunter.Position; this.position.X += 40; this.position.Y -= 20; velocity = new Vector2(); } if (velocity.Length() > MaxSpeed) { velocity.Normalize(); velocity *= maxSpeed; } base.Update(steering, time); //position += velocity; //orientation += rotation; collide.position.X += (float)((((image.Height - 5) / 2) * Math.Cos(this.orientation))); collide.position.Y += (float)(((image.Height - 5) / 2) * Math.Sin(this.orientation)); }
public override void Update(SteeringOutput steering, GameTime time) { if (health > 4) { health = 4; } prevState = newState; newState = Keyboard.GetState(); threatCooldown--; if (threatCooldown < 0) { decayThreat(); } bool keyPressed = false; if (health > 0 && spearJab == false && spearThrow == false) { if (Game.keyboard.IsKeyDown(Keys.A)) { velocity.X -= maxAcceleration; keyPressed = true; } if (Game.keyboard.IsKeyDown(Keys.D)) { velocity.X += maxAcceleration; keyPressed = true; } if (Game.keyboard.IsKeyDown(Keys.W)) { velocity.Y -= maxAcceleration; keyPressed = true; } if (Game.keyboard.IsKeyDown(Keys.S)) { velocity.Y += maxAcceleration; keyPressed = true; } } if (!canAttack) { coolDown--; if (coolDown <= 0) { coolDown = 50; canAttack = true; } } if (canAttack) { if (newState.IsKeyDown(Keys.J) && prevState.IsKeyUp(Keys.J)) { canAttack = false; keyPressed = true; spearJab = true; threaten(); } if (newState.IsKeyDown(Keys.K) && prevState.IsKeyUp(Keys.K)) { canAttack = false; keyPressed = true; spearThrow = true; throwOrientation = this.orientation; throwVelocity = this.velocity; threaten(); } } if (!keyPressed) { velocity = new Vector2(); } if (velocity.Length() > MaxSpeed) { velocity.Normalize(); velocity *= maxSpeed; } base.Update(steering, time); }
private void FixedUpdate() { SteeringOutput steering = new SteeringOutput(); switch (blendingType) { #region Signle Blending case SteeringBlendingTypes.Single: // Get the first and only steering we need steering = steeringBehaviours[0].behaviour.GetSteering(this, steeringBehaviours[0]); break; #endregion #region Weighted Blending case SteeringBlendingTypes.Weighted: SteeringOutput weighted; for (int i = 0; i < steeringBehaviours.Count; i++) { weighted = steeringBehaviours[i].behaviour.GetSteering(this, steeringBehaviours[i]); steering.linear += weighted.linear * steeringBehaviours[i].velocityWeight; steering.angular += weighted.angular * steeringBehaviours[i].rotationWeight; } break; #endregion } steering.LimitOutputs(maxAcceleration, maxAngularAcceleration); // Update pos and orientation transform.position += velocity * Time.fixedDeltaTime; transform.Rotate(0, 0, rotationVelocity * Time.fixedDeltaTime); velocity += steering.linear * Time.fixedDeltaTime; float speed = velocity.magnitude; // Limit to velocity if (speed > maxSpeed) { velocity.Normalize(); velocity *= maxSpeed; } if (Mathf.Approximately((float)Math.Round(speed, 1), 0f)) { velocity = new Vector3(); } if (lookWhereGoingInstantly) { transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(velocity.y, velocity.x) * Mathf.Rad2Deg - 90f); } else { // update with steering rotationVelocity += steering.angular * Time.fixedDeltaTime; // Limit angular velocity if (rotationVelocity > maxRotation) { // * .... so it keeps the direction rotationVelocity = maxRotation * (maxRotation / Mathf.Abs(maxRotation)); } } }