/// <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;
        }
예제 #2
0
        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;
        }
예제 #3
0
파일: Evade.cs 프로젝트: jennydvr/ColorWars
        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();
        }
예제 #4
0
        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;
        }
예제 #6
0
파일: Align.cs 프로젝트: minas1/flocking
        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;
        }
예제 #7
0
파일: Seek.cs 프로젝트: minas1/flocking
        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;
        }
예제 #8
0
        /// <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;
        }
예제 #9
0
        /// <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;
        }
예제 #11
0
        /// <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;
            }            
        }
예제 #12
0
파일: Align.cs 프로젝트: jennydvr/ColorWars
        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;
        }
예제 #13
0
        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;
        }
예제 #14
0
    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);
    }
예제 #15
0
    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);
        }
    }
예제 #16
0
    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);
    }
예제 #17
0
    // 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();
    }
예제 #18
0
    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);
    }
예제 #19
0
    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;
        }
    }
예제 #20
0
파일: Seek.cs 프로젝트: jennydvr/ColorWars
        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;
        }
예제 #21
0
    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);
    }
예제 #22
0
파일: Flee.cs 프로젝트: minas1/flocking
    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);
    }
예제 #25
0
        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);
        }
예제 #26
0
        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);
        }
예제 #27
0
    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);
    }
예제 #28
0
        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;
        }
예제 #29
0
    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
        };
    }
예제 #30
0
    // 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
    }
예제 #31
0
    /*
     * 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);
    }
예제 #32
0
    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);
    }
예제 #33
0
    // 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);
    }
예제 #35
0
    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);
    }
예제 #36
0
    // 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);
    }
예제 #37
0
    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);
    }
예제 #38
0
    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);
    }
예제 #39
0
    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);
    }
예제 #40
0
    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);
    }
예제 #41
0
    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);
    }
예제 #42
0
        // 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;
            }
        }
예제 #43
0
        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;
        }
예제 #44
0
    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);
    }
예제 #45
0
    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();
    }
예제 #46
0
    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;
        }
    }
예제 #47
0
    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);
    }
예제 #48
0
        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;
        }
예제 #49
0
        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;
        }
예제 #50
0
        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;
        }
예제 #51
0
파일: Arrive.cs 프로젝트: minas1/flocking
        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;
        }
예제 #52
0
        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;
        }
예제 #53
0
        /// <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;
        }
예제 #59
0
        /// <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;
    }