/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { if (!_jumping) { if (!_unit.isGrounded) { return; } var scanPoint = _unit.position + (_unit.forward * this.scanDistance); var unitElevation = _unit.position.y; _targetHeight = _heightSampler.SampleHeight(scanPoint) + _unit.baseToPositionOffset; if (_targetHeight - unitElevation < this.minimumHeightToJump || ((_targetHeight - unitElevation) - _unit.heightNavigationCapability.maxClimbHeight) > 0.0001f) { return; } var halfDistance = this.scanDistance / 2f; var speed = _unit.velocity.magnitude; var timeToTarget = halfDistance / speed; //Calculate the distance the unit will drop due to gravity and adjust the target height accordingly //Since gravity is assumed negative we do -0.5 instead of just 0.5 var drop = -0.5f * input.gravity * timeToTarget * timeToTarget; _targetHeight += drop; _force = _targetHeight / (Time.fixedDeltaTime * timeToTarget); } _jumping = _unit.position.y < _targetHeight; output.overrideHeightNavigation = true; output.verticalForce = _force; }
protected override SteeringOutput SteeringGenerator() { SteeringOutput steering = new SteeringOutput(); // First, update the targets list Update(); foreach (Kinematic t in targets) { // Check if the target is close Vector3 direction = character.position - t.position; float distance = direction.Length(); if (distance < threshold) { // Calculate strength of repulsion float strength = Math.Min(decayCoefficient / (distance * distance), maxAcceleration); // Add acceleration direction.Normalize(); steering.linear += strength * direction; } } if (DEBUG) Debug(steering); return steering; }
protected override SteeringOutput SteeringGenerator() { SteeringOutput steering = new SteeringOutput(); // Work out the distance to the target Vector3 direction = target.position - character.position; float distance = direction.Length(); // Work out current speed float speed = character.velocity.Length(); // Calculate prediction time float prediction = 0; if (speed <= distance / maxPrediction) prediction = maxPrediction; else prediction = distance / speed; // Call flee base.target = target; base.target.position += base.target.velocity * prediction; return base.SteeringGenerator(); }
public SteeringOutput GetSteering() { var hitInfoForward = new RaycastHit(); var layerMask = (1 << 8); // bit shift by the index of the layer we want (NoCollision layer) layerMask = ~layerMask; // this will force to test only for collisions other than the above bool collisionForward = Physics.Raycast(new Ray(character.transform.position, character.transform.forward), out hitInfoForward, lookahead, layerMask); bool canMoveForward = !HitFound(collisionForward, hitInfoForward); if( !canMoveForward ) { dummy.position = hitInfoForward.point + hitInfoForward.normal * avoidDistance; } else { var hitInfoVertical = new RaycastHit(); bool collisionVertical = (character.maxSpeed > 0f ? Physics.Raycast(new Ray(character.transform.position, Vector3.down), out hitInfoVertical, character.maxSpeed * 0.25f, layerMask) : false); bool canMoveVertical = !HitFound(collisionVertical, hitInfoVertical); if( !canMoveVertical ) dummy.position = character.position + character.transform.forward * 10f + Vector3.up * 10f; else return (_lastSteering = SteeringOutput.None); } return (_lastSteering = seek.GetSteering()); }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { if (this.target == null) { return; } Vector3 targetPos = this.target.position; Vector3 unitPos = input.unit.position; var squaredDistance = (targetPos - unitPos).sqrMagnitude; if (this.awarenessRadius > 0f && squaredDistance > (this.awarenessRadius * this.awarenessRadius)) { // if target is outside awareness radius return; } if (squaredDistance <= (this.stopRadius * this.stopRadius)) { // if inside stop radius, then start arriving output.desiredAcceleration = Arrive(this.stopTimeFrame, input); return; } Vector3 pursuePos = Vector3.zero; var targetUnit = target.GetUnitFacade(false); if (targetUnit == null) { // if target has no unit facade, then it is probably not a moving target anyway pursuePos = targetPos; } else { var distToOther = (targetPos - unitPos).magnitude; var targetSpeed = targetUnit.velocity.magnitude; var predictionTime = 0.1f; if (targetSpeed > 0f) { //Half the prediction time for better behavior predictionTime = (distToOther / targetSpeed) / 2f; } pursuePos = targetPos + (targetUnit.velocity * predictionTime); } if (pursuePos.sqrMagnitude == 0f) { return; } // seek the pursue position and allow speed-up output.desiredAcceleration = Seek(pursuePos, input); output.maxAllowedSpeed = input.unit.maximumSpeed; }
public SteeringOutput GetSteering() { SteeringOutput steering = new SteeringOutput(); steering.linearVel = Vector3.zero; //steering.rotation = Vector3.zero; // face in the direction that the target is facing character.transform.LookAt(character.transform.position + target.transform.forward); return steering; }
public virtual SteeringOutput GetSteering() { var steering = new SteeringOutput(); // get the direction to the target steering.linearVel = target.position - character.position; // the velocity is along this direction, at full speed steering.linearVel.Normalize(); steering.linearVel *= character.maxSpeed; return steering; }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { if (!_jumping) { // exit early if not jumping return; } // start jumping if unit is below the target height _jumping = _unit.position.y < _targetHeight; output.overrideHeightNavigation = true; output.verticalForce = _force; }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { if (this.target == null) { return; } Vector3 targetPos = this.target.position; // if target is within awareness radius - or awareness radius has been set to 0 or below, then seek if ((targetPos - input.unit.position).sqrMagnitude < (this.awarenessRadius * this.awarenessRadius) || this.awarenessRadius <= 0f) { // arrive at the target position output.desiredAcceleration = Arrive(targetPos, input); } }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { if (this.target == null) { // if no target, exit early return; } Vector3 targetPos = this.target.position; Vector3 unitPos = input.unit.position; if (this.awarenessRadius > 0f && (targetPos - unitPos).sqrMagnitude > (this.awarenessRadius * this.awarenessRadius)) { // if distance is more than awareness radius, then exit return; } Vector3 evadePos = Vector3.zero; var targetUnit = this.target.GetUnitFacade(); if (targetUnit == null) { // if target has no unit facade, then it is probably not a moving target anyway evadePos = targetPos; } else { var distToOther = (targetPos - unitPos).magnitude; var otherSpeed = targetUnit.velocity.magnitude; var predictionTime = 0.1f; if (otherSpeed > 0f) { //Half the prediction time for better behavior predictionTime = (distToOther / otherSpeed) / 2f; } evadePos = targetPos + (targetUnit.velocity * predictionTime); } if (evadePos.sqrMagnitude == 0f) { return; } // flee evade position and allow speed-up output.desiredAcceleration = Flee(evadePos, input); output.maxAllowedSpeed = input.unit.maximumSpeed; }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { if (this.target == null) { return; } Vector3 targetPos = this.target.position; // if target is within awareness radius - or awareness radius has been set to 0 or below, then flee if ((targetPos - input.unit.position).sqrMagnitude < (this.awarenessRadius * this.awarenessRadius) || this.awarenessRadius <= 0f) { // flee and allow speed-up output.desiredAcceleration = Flee(targetPos, input); output.maxAllowedSpeed = input.unit.maximumSpeed; } }
protected override SteeringOutput SteeringGenerator() { SteeringOutput steering = new SteeringOutput(); // Get the naive direction to the target float rotation = target.orientation - character.orientation; // Map the result to the (-pi, pi) interval rotation = MapRadians(rotation); float rotationSize = Math.Abs(rotation); // Check if we are there if (rotationSize < targetRadius) return steering; float targetRotation = 0; // If we are outside slowRadius, go full speed if (rotationSize > slowRadius) { targetRotation = maxRotation; } // Otherwise calculate a scaled rotation else { targetRotation = maxRotation * rotationSize / slowRadius; } // Now combine the speed with the direction targetRotation *= rotation / rotationSize; // Acceleration tries to get to the target rotation steering.angular = targetRotation - character.rotation; steering.angular /= timeToTarget; float angularAcceleration = Math.Abs(steering.angular); // Check if acceleration is too big if (angularAcceleration > maxAngularAcceleration) { steering.angular /= angularAcceleration; steering.angular *= maxAngularAcceleration; } steering.linear = Vector3.Zero; return steering; }
protected override SteeringOutput SteeringGenerator() { // If the target was reached, return nothing if ((target.position - character.position).Length() < 80) { SteeringOutput negative = new SteeringOutput(); negative.linear = character.velocity * -1; return negative; } // If your target hasn't moved in a while, go seek him if (lastPosition == target.position) { base.target = target; return base.SteeringGenerator(); } lastPosition = target.position; // Work out the distance to the target Vector3 direction = target.position - character.position; float distance = direction.Length(); // Work out current speed float speed = character.velocity.Length(); // Calculate prediction time float prediction = 0; if (speed <= distance / maxPrediction) prediction = maxPrediction; else prediction = distance / speed; // Call arrive base.target = target; base.target.position += base.target.velocity * prediction; SteeringOutput steering = base.SteeringGenerator(); if (DEBUG) Debug(steering); return steering; }
public SteeringOutput getSteering(int choice) { SteeringOutput seekDirection = new SteeringOutput(); if (choice == 1) // Seek only { seekDirection.linear = target.transform.position - character.transform.position; } else if (choice == 2) // Flee only { seekDirection.linear = character.transform.position - target.transform.position; } return(seekDirection); }
public override SteeringOutput getSteering() { target = GameObject.Find("Player"); SteeringOutput result = new SteeringOutput(); float distance = target.transform.position.z - character.transform.position.z; distance = Mathf.Abs(distance); Debug.Log(distance); if (distance < targetRadius) { return(null); } if (distance > slowRadius) { result.linear = target.transform.position - character.transform.position; result.linear.Normalize(); result.linear *= maxAcceleration; return(result); } else { result.linear.z = maxSpeed * (distance / slowRadius); Vector3 targetVelocity = new Vector3(); targetVelocity = result.linear; targetVelocity.Normalize(); targetVelocity *= result.linear.z; result.linear = targetVelocity - character.linearVelocity; result.linear /= timeToTarget; if (result.linear.magnitude > maxAcceleration) { result.linear.Normalize(); result.linear *= maxAcceleration; } result.angular = 0; return(result); } }
public SteeringOutput getSteering() { SteeringOutput steering = new SteeringOutput(); Vector3 direction = target.position - character.position; float distance = direction.magnitude; if (distance < slowRadius) { //Debug.Log("INSIDE!!!"); steering.linear = -2 * character.velocity; //steering.linear = Vector3.zero; steering.angular = 0; return(steering); } float targetSpeed; if (distance > slowRadius) { targetSpeed = maxSpeed; } else { //Debug.Log("inside slow radius!!! :" + distance / slowRadius); targetSpeed = maxSpeed * (distance / slowRadius); } Vector3 targetVelocity = direction; targetVelocity.Normalize(); targetVelocity *= targetSpeed; steering.linear = targetVelocity - character.velocity; steering.linear /= timeToTarget; if (steering.linear.magnitude > maxAcceleration) { steering.linear.Normalize(); steering.linear *= maxAcceleration; } steering.angular = 0; return(steering); }
// Start is called before the first frame update protected virtual void Start() { mySeek = new Seek(); mySeek.character = this; mySeek.target = target; myFlee = new Flee(); myFlee.character = this; myFlee.target = target; myArrv = new Arrive(); myArrv.character = this; myArrv.target = target; myAlgn = new Align(); myAlgn.character = this; myAlgn.target = target; myFace = new Face(); myFace.character = this; myFace.target = target; myLWYG = new LookWhereGoing(); myLWYG.character = this; myLWYG.target = target; myFPth = new FollowPathDemo(); myFPth.character = this; myFPth.path = waypointList; mySepr = new Separation(); mySepr.character = this; myPrsu = new Pursue(); myPrsu.character = this; myPrsu.target = target; myClAv = new CollAvoid(); myClAv.character = this; myClAv.targets = collAvoidTargets; myObAv = new ObstAvoid(); myObAv.character = this; controlledSteeringUpdate = new SteeringOutput(); }
public override SteeringOutput getSteering() { SteeringOutput result = new SteeringOutput(); // get the direction to the target Vector3 direction = target.transform.position - character.transform.position; float distance = direction.magnitude; //if (distance < targetRadius) //{ // return null; //} // if we are outside the slow radius, then move at max speed float targetSpeed = 0f; if (distance > slowRadius) { targetSpeed = maxSpeed; } else // otherwise calculate a scaled speed { //targetSpeed = -(maxSpeed * distance / slowRadius); // should slowRadius here instead be targetRadius? targetSpeed = maxSpeed * (distance - targetRadius) / targetRadius; } // the target velocity combines speed and direction Vector3 targetVelocity = direction; targetVelocity.Normalize(); targetVelocity *= targetSpeed; // acceleration tries to get to the target velocity result.linear = targetVelocity - character.linearVelocity; result.linear /= timeToTarget; // check if the acceleration is too fast if (result.linear.magnitude > maxAcceleration) { result.linear.Normalize(); result.linear *= maxAcceleration; } return(result); }
public void updateS(SteeringOutput steering, float maxSpeed) { // Update the position and orientation. transform.position += velocity * Time.deltaTime; vz.z += (float)(rotation * Time.deltaTime * 180 / System.Math.PI); transform.rotation = Quaternion.Euler(vz); // and the velocity and rotation. velocity += steering.linear * Time.deltaTime; rotation += steering.angular * Time.deltaTime; // Check for speeding and clip if (velocity.magnitude > maxSpeed) { velocity.Normalize(); velocity *= maxSpeed; } }
protected override SteeringOutput SteeringGenerator() { SteeringOutput steering = new SteeringOutput(); // Get the direction to the target steering.linear = target.position - character.position; // Give full acceleration along this direction steering.linear.Normalize(); steering.linear *= maxAcceleration; steering.angular = 0; if (DEBUG) Debug(steering); return steering; }
public SteeringOutput Wander() { if (startTime > wanderRate) { wanderOrientation += randomBinomial() * wanderRate; startTime = 0f; } startTime += Time.deltaTime; DynamicAlign a = new DynamicAlign(agent.k, new Kinematic(), maxAngularAcceleration, maxRotation, targetRadiusA, slowRadiusA); DynamicFace f = new DynamicFace(new Kinematic(), a); DynamicSeek ds = new DynamicSeek(agent.k, new Kinematic(), maxAcceleration); DynamicWander dw = new DynamicWander(wanderOffset, wanderRadius, wanderRate, maxAcceleration, wanderOrientation, ds); SteeringOutput so = dw.getSteering(); agent.DrawCircle(dw.targetPos, wanderRadius); //agent.DrawLine(agent.k.position, asVector(wanderOrientation)); return(so); }
public virtual SteeringOutput GetSteering() { SteeringOutput steering = new SteeringOutput(); if( Vector3.Distance(character.position, target.position) <= radius ) { // get the direction to the target steering.linearVel = character.position - target.position; // the velocity is along this direction, at full speed steering.linearVel.Normalize(); steering.linearVel *= character.maxSpeed; return steering; } return SteeringOutput.None; }
public SteeringOutput Align() { SteeringOutput steering = new SteeringOutput(); // 1. Calculate the target to delegate to align // Check for a zero direction, and make no change if so if (agent.velocity.magnitude < 0.001) { return(steering); } // Otherwise set the target based on the velocity target.orientation = Mathf.Atan2(-agent.velocity.x, agent.velocity.z); return(steering); }
public SteeringOutput getSteering(Kinematic selfKinematic, GameObject target = null, Kinematic targetKinematic = null) { output.linear = Vector3.zero; output.angular = 0; foreach (SteeringBehaviour behaviour in behaviours) { SteeringOutput steering = behaviour.getSteering(selfKinematic, target, targetKinematic); if (steering == null) { continue; } output.linear += steering.linear; output.angular += steering.angular; } return(output); }
public SteeringOutput getSteering(Entity character, List <Entity> targets) { SteeringOutput steering = new SteeringOutput(); //loop through each target here foreach (Entity target in targets) { Vector2 direction = target.Position - character.Position; float distanceSquared = direction.LengthSquared(); float strength = Math.Min(decayCoefficient / (distanceSquared), character.MaxAcceleration); direction.Normalize(); direction *= character.MaxSpeed; steering.linear -= strength * direction; } return(steering); }
public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { if (other.Equals(null)) { return; } var diff = (input.unit.position - other.transform.position); if (diff.sqrMagnitude > this.repulsionRange * this.repulsionRange) { return; } var targetPos = input.unit.position + (diff.normalized * (this.repulsionRange - diff.magnitude)); output.desiredAcceleration = Seek(targetPos, input); }
void Start() { static_data target; //Inicializamos las estructuras necesarias de otros componentes for (int i = 0; i < targets_names.Length; i++) { target = GameObject.Find(targets_names[i]).GetComponent <static_data>(); targetsKins.Add(target.kineticsAgent); } kineticsAgent = agent.kineticsAgent; steeringAgent = agent.steeringAgent; Kinetics[] targets = targetsKins.ToArray(); //Inicializamos movimientos separation = new Separation(kineticsAgent, targets, threshold, maxAccel); }
protected override SteeringOutput SteeringGenerator() { SteeringOutput steering = new SteeringOutput(); // Try to get to the target velocity steering.linear = target.velocity - character.velocity; steering.linear /= timeToTarget; // Check if acceleration is too fast if (steering.linear.Length() > maxAcceleration) { steering.linear.Normalize(); steering.linear *= maxAcceleration; } steering.angular = 0; return steering; }
private void Start() { ai = GetComponent <SteeringBehavior>(); rb = GetComponent <Rigidbody>(); line = GetComponent <LineRenderer>(); stopped = false; msm = FindObjectOfType <MapStateManager>(); //intialize steering output so = new SteeringOutput(); k = new Kinematic { position = rb.position, velocity = Vector3.zero, orientation = Mathf.Deg2Rad * rb.rotation.eulerAngles.y }; }
// Update is called once per frame void Update() { //update position and rotation transform.position += linearVelocity * Time.deltaTime; transform.eulerAngles += new Vector3(0, angularVelocity * Time.deltaTime, 0); Seek mySeek = new Seek(); mySeek.character = this; mySeek.target = target; steering = mySeek.getSteering(); if (steering != null) { linearVelocity += steering.linear * Time.deltaTime; } RotAI(mode); //update linear and angular velocities }
/* * public SteeringOutput Seek() * { * return new DynamicSeek(agent.k, target.k, maxAcceleration).getSteering(); * } * public SteeringOutput Flee() * { * return new DynamicFlee(agent.k, target.k, maxAcceleration).getSteering(); * } * * public SteeringOutput Pursue() * { * DynamicPursue dp = new DynamicPursue(agent.k, target.k, maxAcceleration, maxPrediction); * SteeringOutput so = dp.getSteering(); * agent.DrawCircle(dp.predictPos, targetRadiusL); * return so; * } */ public SteeringOutput Arrive() { DynamicArrive da = new DynamicArrive(agent.k, target.k, maxAcceleration, maxSpeed, targetRadiusL, slowRadiusL); agent.DrawCircle(target.k.position, slowRadiusL); SteeringOutput so = da.getSteering(); if (pathFollow && !change && current < 5) { current++; change = true; } else if (!agent.hit) { agent.CaughtTarget(); } return(so); }
public override SteeringOutput getSteering() { wanderOrientation += Random.Range(-wanderRate, wanderRate); float targetOrientation = wanderOrientation + character.transform.eulerAngles.y; Vector3 orientationVector = new Vector3(Mathf.Sin(character.transform.eulerAngles.y * Mathf.Deg2Rad), 0, Mathf.Cos(character.transform.eulerAngles.y * Mathf.Deg2Rad)); Vector3 targetOVector = new Vector3(Mathf.Sin(targetOrientation * Mathf.Deg2Rad), 0, Mathf.Cos(targetOrientation * Mathf.Deg2Rad)); target.transform.position = character.transform.position + wanderOffset * orientationVector; target.transform.position += wanderRadius * targetOVector; SteeringOutput result = new SteeringOutput(); result.angular = getTargetAngle(); result.linear = maxAcceleration * orientationVector; return(result); }
// Update is called once per frame void Update() { // update position and rotation transform.position += linearVelocity * Time.deltaTime; Vector3 angularIncrement = new Vector3(0, angularVelocity * Time.deltaTime, 0); transform.eulerAngles += angularIncrement; // update linear and angular velocity Seek mySeek = new Seek(); mySeek.character = this; mySeek.target = target; SteeringOutput steering = mySeek.getSteering(); linearVelocity += steering.linear * speedMultiplier * Time.deltaTime; angularVelocity += steering.angular * Time.deltaTime; }
SteeringOutput getSteering() { SteeringOutput result = new SteeringOutput(); // Acceleration tries to get to the target velocity result.linear = target.velocity - character.velocity; result.linear /= timeToTarget; // Check if the acceleration is too fast if (result.linear.magnitude > maxAcceleration) { result.linear.Normalize(); result.linear *= maxAcceleration; } result.angular = 0; return(result); }
public override SteeringOutput CalculateSteering(SteeringAgent agent) { SteeringOutput output = new SteeringOutput(); Vector3 linearVelocity = (_target - agent.transform.position).normalized; if ((_target - agent.transform.position).sqrMagnitude > (_nearEnoughDist * _nearEnoughDist)) { linearVelocity *= agent.GetMaxLinearVelocity(); } else { linearVelocity *= 0.01f; } output.LinearVelocity = linearVelocity; return(output); }
// Allow this to be extended by Persue by passing in any position! public SteeringOutput GetSteering(Vector3 targetPosition) { SteeringOutput output = new SteeringOutput(); // Get the direction to the target. var direction = targetPosition - transform.position; direction.y = 0; Debug.DrawLine(transform.position, transform.position + direction, Color.red); // The velocity is along this direction, at full acceleration. output.Linear = Character.MaxAcceleration * direction.normalized; // We don't change orientation here, as we did with the Kinematic version. Instead, delegate this to Align! output.Angular = 0; return(output); }
public override SteeringOutput GetSteering() { // Create the structure to hold our output SteeringOutput steering = new SteeringOutput(); // Get direction to the target IFollowable followable = character.GetComponent <IFollowable>(); Vector3 characterVelocity = followable.GetVelocity(); Vector3 direction; if (target == null) { direction = characterVelocity.normalized; } else { direction = target.transform.position - character.transform.position; } float distance = direction.magnitude; // Velocity that we want to have Vector3 targetVelocity; // The target velocity combines speed and direction targetVelocity = direction; targetVelocity.Normalize(); targetVelocity *= maxSpeed; // Acceleration tries to get to the target velocity steering.linear = targetVelocity - characterVelocity; steering.linear /= timeToTarget; // Check if the acceleration is too fast if (steering.linear.magnitude > maxAcceleration) { steering.linear.Normalize(); steering.linear = steering.linear * maxAcceleration; } // Output the steering steering.angular = 0; return(steering); }
public SteeringOutput GetSteering() { SteeringOutput output = new SteeringOutput(); // Get the direction and distance to the target. Vector3 direction = Character.Target.transform.position - transform.position; direction.y = 0; float distance = direction.magnitude; // Won't be steering rotation here, instead delegate this to Align? output.Angular = 0; // Again, unlike KinematicArrive, we do not change orientation here // Check if we're already there if (distance < TargetRadius) { output.Linear = Vector3.zero; return(output); // If so, we're done } // Check if we're outside the slow radius if (distance > SlowRadius) { output.Linear = direction.normalized * Character.MaxSpeed; } else // Calculate a scaled speed to slow down { float targetSpeed = Character.MaxSpeed * distance / SlowRadius; Vector3 targetVelocity = direction.normalized * targetSpeed; // Acceleration tries to get to target velocity output.Linear = (targetVelocity - Rigidbody.velocity) / TimeToTarget; // Clip if acceleration is too fast if (output.Linear.magnitude > Character.MaxAcceleration) { output.Linear = output.Linear.normalized * Character.MaxAcceleration; } } return(output); }
public override SteeringOutput getSteering() { SteeringOutput result = new SteeringOutput(); Vector3 direction, targetVelocity; float distance, targetSpeed; // get the direction to the target direction = getTargetPosition() - character.transform.position; distance = direction.magnitude; // if (distance < targetRadius) // return null // if outside slowRadius, move at maxSpeed if (distance > slowRadius) { targetSpeed = maxSpeed; } // otherwise calculate a scaled speed else { targetSpeed = maxSpeed * (distance - targetRadius) / targetRadius; } //the target velocity combines speed and direction targetVelocity = direction; targetVelocity.Normalize(); targetVelocity *= targetSpeed; // acceleration tries to get to the target velocity result.linear = targetVelocity - character.linearVelocity; result.linear /= timeToTarget; // check if the acceleration is too fast if (result.linear.magnitude > maxAcceleration) { result.linear.Normalize(); result.linear *= maxAcceleration; } result.angular = 0; return(result); }
public SteeringOutput GetSteering() { SteeringOutput result = new SteeringOutput(); //get direction to target if (seek) { result.linear = target.transform.position - ai.transform.position; } else { result.linear = ai.transform.position - target.transform.position; } result.linear.Normalize(); // give full acceleration result.linear *= maxAcceleration; result.angular = 0; return(result); }
public void Update(SteeringOutput steering, float _maxSpeed, float time) { position += velocity * time; //orientation + angular velocity orientation += rotation * time; // velocity += steering.linear * time; orientation += steering.angular * time; if (velocity.magnitude > _maxSpeed) { Debug.Log(_maxSpeed); velocity.Normalize(); velocity *= _maxSpeed; } Debug.DrawRay(position, asVector(orientation) * 10f, Color.yellow); Debug.DrawRay(position, velocity * 2f, Color.green); }
// This is called every physics update private void FixedUpdate() { // Is there any target for me? GameObject target = targetTag != "" ? GameObject.FindWithTag(targetTag) : null; // Obtain steering behaviours SteeringOutput steerWeighted = new SteeringOutput(); // Get a weighted steering behaviour from the existing behaviours foreach (ISteeringBehaviour behaviour in steeringBehaviours) { // Current steering behaviour SteeringOutput steer = behaviour.GetSteering(target); // Include current behaviour in the overall weighted behaviour steerWeighted = new SteeringOutput( steerWeighted.Linear + behaviour.Weight * steer.Linear, steerWeighted.Angular + behaviour.Weight * steer.Angular); } // Limit acceleration steerWeighted = new SteeringOutput( Vector2.ClampMagnitude(steerWeighted.Linear, maxAccel), Mathf.Min(steerWeighted.Angular, maxAngularAccel)); // Apply steering rb.AddForce(steerWeighted.Linear); rb.AddTorque(steerWeighted.Angular * Mathf.Deg2Rad); // Limit speed if (rb.velocity.magnitude > maxSpeed) { rb.velocity = rb.velocity.normalized * maxSpeed; } // Limit rotation (angular velocity) if (rb.angularVelocity > maxRotation) { rb.angularVelocity = maxRotation; } }
public SteeringOutput GetSteering() { SteeringOutput steering = new SteeringOutput(); // Accumulate all accelerations foreach (BehaviorAndWeight behavior in behaviors) steering += behavior.weight * behavior.behavior.GetSteering(); // Crop the result and return if (steering.linear.Length() > maxAcceleration) { steering.linear.Normalize(); steering.linear *= maxAcceleration; } steering.angular = Math.Min(steering.angular, maxRotation); return steering; }
public override SteeringOutput getSteering() { SteeringOutput steering = new SteeringOutput(); //Direction to target Vector3 direction = target - character.position; float distance = direction.magnitude; //Check if we are there if (distance < targetRadius) { VelocityMatch getToZero = new VelocityMatch(this.character, new Vector3(0.0f, 0.0f, 0.0f), 5.0f); steering = getToZero.getSteering(); return(steering); } //If we are outside the slow radius, go max speed float targetSpeed; if (distance > slowRadius) { targetSpeed = maxSpeed; //Otherwise calculate scaled speed } else { targetSpeed = maxSpeed * distance / slowRadius; } //Target velocity combines speed & direction Vector3 targetVelocity = direction.normalized * targetSpeed; //Acceleration tries to match target velocity steering.linear = targetVelocity - character.velocity; steering.linear /= timeToTarget; //Clamp acceleration if (steering.linear.magnitude > maxAcceleration) { steering.linear = steering.linear.normalized * maxAcceleration; } //Return steering data return(steering); }
void Start() { playerK = new Kinematic(); enemyK = new Kinematic(); playerK.maxSpeed = maxSpeed; enemyK.maxSpeed = maxSpeed; playerK.position = player.GetComponent <Rigidbody>().position; playerK.velocity = Vector3.zero; playerK.orientation = Mathf.Deg2Rad * player.GetComponent <Rigidbody>().rotation.eulerAngles.y; enemyK.position = target.GetComponent <Rigidbody>().position; enemyK.velocity = Vector3.zero; enemyK.orientation = Mathf.Deg2Rad * target.GetComponent <Rigidbody>().rotation.eulerAngles.y; playerSO = new SteeringOutput(); enemySO = new SteeringOutput(); }
void MainSteeringBehaviors() { ResetOrientation(); switch (choiceOfBehavior) { case steeringBehaviors.Seek: Seek seek = new Seek(); seek.selectedBoi = this; seek.myBoi = myBoi; SteeringOutput seeking = seek.getSteering(); if (seeking != null) { linearVelocity += seeking.linearVelocity * Time.deltaTime; angularVelocity += seeking.angularVelocity * Time.deltaTime; } break; case steeringBehaviors.Flee: Flee flee = new Flee(); flee.selectedBoi = this; flee.myBoi = myBoi; SteeringOutput fleeing = flee.getSteering(); if (fleeing != null) { linearVelocity += fleeing.linearVelocity * Time.deltaTime; angularVelocity += fleeing.angularVelocity * Time.deltaTime; } break; case steeringBehaviors.Arrive: Arrive arrive = new Arrive(); arrive.selectedBoi = this; arrive.myBoi = myBoi; SteeringOutput arriving = arrive.getSteering(); if (arriving != null) { linearVelocity += arriving.linearVelocity * Time.deltaTime; angularVelocity += arriving.angularVelocity * Time.deltaTime; } break; } }
public SteeringOutput getSteering() { wanderOrientation += randomBinomial() * wanderRate; //using face, which is using align which has the characyer; float targetOrientation = wanderOrientation + f.a.character.orientation; f.target.position = f.a.character.position + wanderOffset * asVector(f.a.character.orientation); f.target.position += wanderRadius * asVector(targetOrientation); SteeringOutput steering = f.getSteering(); steering.linear = maxAcceleration * asVector(f.a.character.orientation); Debug.DrawRay(f.a.character.position, asVector(f.a.character.orientation) * maxAcceleration, Color.blue); Debug.Log("wander linear = " + steering.linear); return(steering); }
public override SteeringOutput GetSteering() { var steering = new SteeringOutput(); if( !useOldValues ) neighborhoodCount = flock.GetNeighborhoodInfo(character, maxNeighborhoodSize, neighborhoodMaxDistance * neighborhoodMaxDistance, neighborhoodMinDotProduct, aknnApproxVal, out center, out avgVel); // if there are no neighbors, return early if (neighborhoodCount == 0) return SteeringOutput.None; steering.linearVel = avgVel - character.velocity; if( steering.linearVel.magnitude > character.maxSpeed ) { steering.linearVel.Normalize(); steering.linearVel *= character.maxSpeed; } return steering; }
public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { var grid = input.grid; if (grid == null) { _targetCell = null; return; } var unit = input.unit; var pos = unit.position; var cell = grid.GetCell(pos, true); if (cell.isWalkable(unit.attributes)) { if (_targetCell == null) { return; } var dir = pos.DirToXZ(cell.position); var distanceTreshold = (grid.cellSize / 2f) - unit.radius; if (dir.sqrMagnitude > distanceTreshold * distanceTreshold) { _targetCell = cell; } else { _targetCell = null; return; } } else if (_targetCell == null || _targetCell == cell) { _targetCell = grid.GetNearestWalkableCell(pos, pos, true, this.fleeMaxRadius, unit); } output.desiredAcceleration = Seek(_targetCell.position, input); output.maxAllowedSpeed = input.unit.maximumSpeed; }
public SteeringOutput GetSteering() { var steering = new SteeringOutput(); int i = 0; foreach(var behavior in behaviors) { var tempSteering = behavior.behaviour.GetSteering(); steering.linearVel += behavior.weight * tempSteering.linearVel; lastSpeed[i] = behavior.weight * tempSteering.linearVel.magnitude; ++i; } // crop the result and return steering.linearVel = Vector3.ClampMagnitude(steering.linearVel, character.maxSpeed); return steering; }
public virtual SteeringOutput GetSteering() { SteeringOutput steering = new SteeringOutput(); // get the direction to the target var direction = target.position - character.position; float distance = direction.magnitude; // if we are within the satisfaction radius, return no steering if( distance <= satisfactionRadius ) return SteeringOutput.None; float targetSpeed = float.NaN; // if we are outside the slow radius, go full speed if( distance > slowRadius ) targetSpeed = character.maxSpeed; else // otherwise calculate a scaled speed targetSpeed = character.maxSpeed * distance / slowRadius; // the target velocity combines speed and direction var targetVelocity = direction; targetVelocity.Normalize(); targetVelocity *= targetSpeed; // acceleration tries to get to the target velocity steering.linearVel = targetVelocity - character.transform.forward; steering.linearVel /= 0.1f; if( steering.linearVel.magnitude > character.maxSpeed ) { steering.linearVel.Normalize(); steering.linearVel *= character.maxSpeed; } // face in the direction we want to move character.transform.LookAt(character.transform.position + direction); return steering; }
public SteeringOutput GetSteering() { SteeringOutput steering = new SteeringOutput(); lastUsedSteeringIndex = 0; foreach(var group in groups) { steering = group.GetSteering(); // check if we are above the epsilon threshold, if so return if( steering.linearVel.magnitude > epsilon ) { return steering; } ++lastUsedSteeringIndex; } // if we reached here it means that no group had a large enough acceleration, // so return the (small) acceleration of the last group return steering; }
/// <summary> /// Calculates the arrive acceleration vector for the specified destination. /// </summary> /// <param name="destination">The destination.</param> /// <param name="remainingDistance">The remaining distance.</param> /// <param name="input">The input.</param> /// <param name="output">The output.</param> /// <returns>The acceleration vector</returns> protected bool Arrive(Vector3 destination, float remainingDistance, SteeringInput input, SteeringOutput output) { var arriveDistance = remainingDistance - this.arrivalDistance; this.hasArrived = arriveDistance <= 0.01f; if (this.hasArrived) { return true; } var currentVelocity = input.currentPlanarVelocity; this.slowingDistance = currentVelocity.sqrMagnitude / (2 * input.maxDeceleration); //We want to start stopping when the deceleration capabilities dictate it, so applying v² = u² + 2a * d //Since v is 0 (target velocity) and a is negative (deceleration) the acceptable current velocity u can be expressed as u = sqrt(2a * d). var maxSpeed = Mathf.Sqrt(2 * input.maxDeceleration * arriveDistance); var desiredSpeed = Mathf.Min(maxSpeed, input.desiredSpeed); var dir = input.unit.position.DirToXZ(destination); var desiredVelocity = dir.normalized * desiredSpeed; //While in theory we want to clamp to max deceleration when decelerating, in practice we just want to decelerate by whatever is needed since the deceleration capabilities are already considered above. //So this ensures that floating point inaccuracies do not cause imprecise stopping. if (desiredSpeed < input.desiredSpeed) { output.desiredAcceleration = (desiredVelocity - input.currentPlanarVelocity) / input.deltaTime; } else { output.desiredAcceleration = Vector3.ClampMagnitude((desiredVelocity - input.currentPlanarVelocity) / input.deltaTime, input.maxAcceleration); } return false; }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { // Set the formation position to null to make sure that it is invalid when it's supposed to be input.unit.formationPos = null; _formationPos = null; // set instance variables to be used in load balanced update method _unitData = input.unit; _grid = input.grid; if (_grid == null) { // if not on a grid, drop formation return; } // must cast the group to have access to GetFormationPosition var group = _unitData.transientGroup as DefaultSteeringTransientUnitGroup; if (group == null) { // if not in a group, drop formation return; } int count = group.count; if (count == 0) { // if there are no members in the group, drop formation return; } var modelUnit = group.modelUnit; if (modelUnit == null) { // if group's model unit is missing, then drop formation return; } if (_unitData.formationIndex < 0) { // if this unit has not been given a valid formation index, then drop formation return; } if (_unitData.hasArrivedAtDestination && this.dropFormationOnArrival) { return; } _formationPos = group.GetFormationPosition(_unitData.formationIndex); if (_formationPos == null || _stopped) { // if there is no valid formation position calculated or it is invalid currently, then drop formation return; } // make sure desiredSpeed does not spill over or under var desiredSpeed = Mathf.Min(1.5f * input.desiredSpeed, _unitData.maximumSpeed); _unitData.formationPos = _formationPos; Vector3 arrivalVector = Arrive(_formationPos.position, input, desiredSpeed); if (modelUnit.hasArrivedAtDestination && this.hasArrived) { // When the unit arrives at the designated formation position, make sure hasArrivedAtDestination becomes true // Also, must return here, to avoid outputting a result _unitData.hasArrivedAtDestination = true; return; } output.maxAllowedSpeed = desiredSpeed; output.desiredAcceleration = arrivalVector; }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { _lastAvoidVector = Vector3.zero; var grid = input.grid; if (grid == null) { // if no grid is available, return return; } _unitData = input.unit; if (!_unitData.isGrounded) { // in the air, give up return; } Vector3 selfPos = _unitData.position; var selfCell = grid.GetCell(selfPos); if (selfCell == null || !selfCell.isWalkable(_unitData.attributes)) { // already within a blocked or missing cell, give up return; } // Find and avoid 4 neighbour cells - if they are blocked _neighbours.Clear(); _neighbours.Add(selfCell.GetNeighbour(-1, 0)); _neighbours.Add(selfCell.GetNeighbour(0, -1)); _neighbours.Add(selfCell.GetNeighbour(1, 0)); _neighbours.Add(selfCell.GetNeighbour(0, 1)); // the total radius is the unit's radius + the radius margin + half of the current grid's cell size float selfRadius = _unitData.radius + radiusMargin + (grid.cellSize / 2f); float selfRadiusSqr = selfRadius * selfRadius; Vector3 avoidVector = Vector3.zero; int neighboursCount = _neighbours.count; for (int i = 0; i < neighboursCount; i++) { var neighbourCell = _neighbours[i]; if (neighbourCell == null) { // ignore missing cells, this is not containment continue; } var dir = neighbourCell.position.DirToXZ(selfPos); float distanceSqr = dir.sqrMagnitude; if (distanceSqr < selfRadiusSqr && !neighbourCell.isWalkableFrom(selfCell, _unitData)) { // sum up a vector comprising of all avoid vectors avoidVector += dir; } } if (avoidVector.sqrMagnitude == 0f) { return; } // set the repulsion vector's magnitude to repulsionStrength Vector3 steeringVector = avoidVector.normalized * repulsionStrength; _lastAvoidVector = steeringVector; output.desiredAcceleration = steeringVector; }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { _selfCollisionPos = Vector3.zero; _lastAvoidVector = Vector3.zero; _lastAvoidPos = Vector3.zero; var otherUnits = _scanner.units; int othersCount = otherUnits.count; if (othersCount == 0) { // if the scanner has found no units to avoid, exit return; } _unitData = input.unit; Vector3 avoidVector = Avoid(otherUnits, othersCount, input.currentPlanarVelocity); if (avoidVector.sqrMagnitude < (this.minimumAvoidVectorMagnitude * this.minimumAvoidVectorMagnitude)) { // if the computed avoid vector's magnitude is less than the minimumAvoidVectorMagnitude, then discard it return; } // apply the avoidance force as a full deceleration capped force (not over time) Vector3 steeringVector = Vector3.ClampMagnitude(avoidVector / Time.fixedDeltaTime, input.maxDeceleration); _lastAvoidVector = steeringVector; output.desiredAcceleration = steeringVector; }
private void ProcessState() { switch(state){ case State.Idle: steering = SteeringOutput.empty; break; case State.Turning: steering = seeking.orientationMatcher.GetSteering(); break; case State.Avoiding: case State.PostAvoiding: steering = seeking.GetSteering(); break; } }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { _lastContainVector = Vector3.zero; if (input.grid == null) { // if off-grid, exit early return; } _unitData = input.unit; if (!_unitData.isGrounded) { // while in the air, exit early return; } // prepare local variables Vector3 selfPos = _unitData.position; Vector3 containVector = Vector3.zero; float selfHeight = _unitData.basePosition.y; // generate positions to the left and right Vector3 rightPos = selfPos + (Vector3.right * bufferDistance); Vector3 leftPos = selfPos + (Vector3.left * bufferDistance); float rightHeight, leftHeight; // sample left and right bool rightContain = _heightSampler.TrySampleHeight(rightPos, out rightHeight); bool leftContain = _heightSampler.TrySampleHeight(leftPos, out leftHeight); // if cell is missing or drop is more than allowed drop height or climb is more than allowed climb height, then compute an axis-aligned containment vector if (!rightContain || (selfHeight - rightHeight > _heightCaps.maxDropHeight) || (rightHeight - selfHeight > _heightCaps.maxClimbHeight)) { containVector = Vector3.left; } else if (!leftContain || (selfHeight - leftHeight > _heightCaps.maxDropHeight) || (leftHeight - selfHeight > _heightCaps.maxClimbHeight)) { containVector = Vector3.right; } // generate positions forward and backwards Vector3 forwardPos = selfPos + (Vector3.forward * bufferDistance); Vector3 backwardPos = selfPos + (Vector3.back * bufferDistance); float forwardHeight, backHeight; // sample forward and backwards bool forwardContain = _heightSampler.TrySampleHeight(forwardPos, out forwardHeight); bool backContain = _heightSampler.TrySampleHeight(backwardPos, out backHeight); // if cell is missing or drop is more than allowed drop height or climb is more than allowed climb height, then compute an axis-aligned containment vector if (!forwardContain || (selfHeight - forwardHeight > _heightCaps.maxDropHeight) || (forwardHeight - selfHeight > _heightCaps.maxClimbHeight)) { // we need to check whether containVector has a value beforehand, in which case we need to normalize containVector = containVector.sqrMagnitude != 0f ? (containVector + Vector3.back).normalized : Vector3.back; } else if (!backContain || (selfHeight - backHeight > _heightCaps.maxDropHeight) || (backHeight - selfHeight > _heightCaps.maxClimbHeight)) { // we need to check whether containVector has a value beforehand, in which case we need to normalize containVector = containVector.sqrMagnitude != 0f ? (containVector + Vector3.forward).normalized : Vector3.forward; } if (containVector.sqrMagnitude == 0f) { // no contain vectors to worry about - no containment necessary return; } // Containment vectors are always "full strength" Vector3 steeringVector = containVector * input.maxAcceleration; _lastContainVector = steeringVector; output.desiredAcceleration = steeringVector; }
/// <summary> /// Gets the desired steering output. /// </summary> /// <param name="input">The steering input containing relevant information to use when calculating the steering output.</param> /// <param name="output">The steering output to be populated.</param> public override void GetDesiredSteering(SteeringInput input, SteeringOutput output) { if (_isPortaling) { output.pause = true; return; } if (_stopped) { return; } if (_stop) { StopInternal(); return; } if (!ResolveNextPoint()) { return; } //Handle waypoints if (_wayPoints.hasWaypoint && _pendingPathRequest == null) { //waypoint request are done if we are close to the point where we need to slow down for arrival as we want to consider the entire length of the path including waypoints when deciding when to slow down. if (_remainingTotalDistance < this.slowingDistance + _pathSettings.requestNextWaypointDistance) { //For way points we cannot use the desired end of path, but must use the actual end as the starting point. RequestPath(_endOfResolvedPath, _wayPoints.NextWaypoint(), InternalPathRequest.Type.Waypoint); } } HandlePathReplan(); if (Arrive(_currentDestination.position, _remainingTotalDistance, input, output)) { if (_pendingPathRequest != null) { return; } //TODO: this should be set whenever the unit stops, however since it may not be the only locomotion component a smarter way must be found //The SterrableUnitComponent ought to handle this, so if there is no locomotion component that have out put it is set to true; otherwise false. //Also change the description of the property _unit.hasArrivedAtDestination = true; StopAndAnnounceArrival(); } }
public override SteeringOutput GetSteering() { Profiler.StartProfile(PT.CollisionAvoiding); if(!seeking) steering = SteeringOutput.empty; else{ TryCheckCollisions(); ChangeState(); ProcessState(); } Profiler.EndProfile(PT.CollisionAvoiding); return steering; }