예제 #1
0
        /// <summary>
        /// Calculates the force to apply to the vehicle to reach a point
        /// </summary>
        /// <returns>
        /// A <see cref="Vector3"/>
        /// </returns>
        protected override Vector3 CalculateForce()
        {
            var difference = Target.forward;

            difference.Scale(_distance);
            return(Vehicle.GetSeekVector(Target.position - difference, _considerVelocity));
        }
예제 #2
0
        protected override Vector3 CalculateForce()
        {
            if (_quarry == null)
            {
                enabled = false;
                return(Vector3.zero);
            }

            var force    = Vector3.zero;
            var offset   = _quarry.Position - Vehicle.Position;
            var distance = offset.magnitude;
            var radius   = Vehicle.ScaledRadius + _quarry.ScaledRadius + _acceptableDistance;

            if (!(distance > radius))
            {
                return(force);
            }

            var unitOffset = offset / distance;

            // how parallel are the paths of "this" and the quarry
            // (1 means parallel, 0 is pependicular, -1 is anti-parallel)
            var parallelness = Vector3.Dot(transform.forward, _quarry.transform.forward);

            // how "forward" is the direction to the quarry
            // (1 means dead ahead, 0 is directly to the side, -1 is straight back)
            var forwardness = Vector3.Dot(transform.forward, unitOffset);

            var directTravelTime = distance / Vehicle.Speed;
            // While we could parametrize this value, if we care about forward/backwards
            // these values are appropriate enough.
            var f = OpenSteerUtility.IntervalComparison(forwardness, -0.707f, 0.707f);
            var p = OpenSteerUtility.IntervalComparison(parallelness, -0.707f, 0.707f);

            float timeFactor = 0; // to be filled in below

            // Break the pursuit into nine cases, the cross product of the
            // quarry being [ahead, aside, or behind] us and heading
            // [parallel, perpendicular, or anti-parallel] to us.
            switch (f)
            {
            case +1:
                switch (p)
                {
                case +1:     // ahead, parallel
                    timeFactor = 4;
                    break;

                case 0:     // ahead, perpendicular
                    timeFactor = 1.8f;
                    break;

                case -1:     // ahead, anti-parallel
                    timeFactor = 0.85f;
                    break;
                }
                break;

            case 0:
                switch (p)
                {
                case +1:     // aside, parallel
                    timeFactor = 1;
                    break;

                case 0:     // aside, perpendicular
                    timeFactor = 0.8f;
                    break;

                case -1:     // aside, anti-parallel
                    timeFactor = 4;
                    break;
                }
                break;

            case -1:
                switch (p)
                {
                case +1:     // behind, parallel
                    timeFactor = 0.5f;
                    break;

                case 0:     // behind, perpendicular
                    timeFactor = 2;
                    break;

                case -1:     // behind, anti-parallel
                    timeFactor = 2;
                    break;
                }
                break;
            }

            // estimated time until intercept of quarry
            var et  = directTravelTime * timeFactor;
            var etl = (et > _maxPredictionTime) ? _maxPredictionTime : et;

            // estimated position of quarry at intercept
            var target = _quarry.PredictFuturePosition(etl);

            force = Vehicle.GetSeekVector(target, _slowDownOnApproach);

#if ANNOTATE_PURSUIT
            Debug.DrawRay(Vehicle.Position, force, Color.blue);
            Debug.DrawLine(Quarry.Position, target, Color.cyan);
            Debug.DrawRay(target, Vector3.up * 4, Color.cyan);
#endif

            return(force);
        }
예제 #3
0
        //protected override void Start()
        //{
        //    base.Start();

        //    if (_defaultToCurrentPosition && TargetPoint == Vector3.zero)
        //    {
        //        enabled = false;
        //    }
        //}

        /// <summary>
        /// Calculates the force to apply to the vehicle to reach a point
        /// </summary>
        /// <returns>
        /// A <see cref="Vector3"/>
        /// </returns>

        protected override Vector3 CalculateForce()
        {
            return(Vehicle.GetSeekVector(_quarry.transform.position + _offset.z * _quarry.transform.forward
                                         + _offset.x * _quarry.transform.right, _considerVelocity));
            //return Vehicle.GetSeekVector(_quarry.transform.position + _offset, _considerVelocity);
        }
예제 #4
0
 /// <summary>
 /// Calculates the force to apply to the vehicle to reach a point
 /// </summary>
 /// <returns>
 /// A <see cref="Vector3"/>
 /// </returns>
 protected override Vector3 CalculateForce()
 {
     return((Target == null)
         ? Vector3.zero
         : Vehicle.GetSeekVector(Target.TransformPoint(_distance), _considerVelocity));
 }
 /// <summary>
 /// Calculates the force to apply to the vehicle to reach a point
 /// </summary>
 /// <returns>
 /// A <see cref="Vector3"/>
 /// </returns>
 protected override Vector3 CalculateForce()
 {
     return(Vehicle.GetSeekVector(TargetPoint, _considerVelocity));
 }
예제 #6
0
 /// <summary>
 /// Calculates the force to apply to a vehicle to reach a target transform
 /// </summary>
 /// <returns>
 /// Force to apply <see cref="Vector3"/>
 /// </returns>
 protected override Vector3 CalculateForce()
 {
     return(Vehicle.GetSeekVector(Target.position));
 }
예제 #7
0
        /// <summary>
        /// Should the force be calculated?
        /// </summary>
        /// <returns>
        /// A <see cref="Vector3"/>
        /// </returns>
        protected override Vector3 CalculateForce()
        {
            if (Path == null || Path.SegmentCount < 2)
            {
                return(Vector3.zero);
            }

            // If the vehicle's speed is 0, use a low speed for future position
            // calculation. Otherwise the vehicle will remain where it is if he
            // starts within the path, because its current position matches its
            // future path position
            var speed = Mathf.Max(Vehicle.Speed, _minSpeedToConsider);

            // our goal will be offset from our path distance by this amount
            var pathDistanceOffset = _predictionTime * speed;

            // measure distance along path of our current and predicted positions
            DistanceAlongPath = Path.MapPointToPathDistance(Vehicle.Position);

            /*
             * Otherwise we need to steer towards a target point obtained
             * by adding pathDistanceOffset to our current path position.
             *
             * Notice that this method does not steer for the point in the
             * path that is closest to our future position, which is why
             * we don't calculate the closest point in the path to our future
             * position.
             *
             * Instead, it estimates how far the vehicle will move in units,
             * and then aim for the point in the path that is that many units
             * away from our current path position _in path length_.   This
             * means that it adds up the segment lengths and aims for the point
             * that is N units along the length of the path, which can imply
             * bends and turns and is not a straight vector projected away
             * from our position.
             */
            var targetPathDistance = DistanceAlongPath + pathDistanceOffset;
            var target             = Path.MapPathDistanceToPoint(targetPathDistance);

            /*
             * Return steering to seek target on path.
             *
             * If you set the considerVelocity parameter to true, it'll slow
             * down at each target to try to ease its arrival, which will
             * likely cause it to come to a stand still at low prediction
             * times.
             */
            var seek = Vehicle.GetSeekVector(target);

            if (seek == Vector3.zero && targetPathDistance <= Path.TotalPathLength)
            {
                /*
                 * If we should not displace but still have some distance to go,
                 * that means that we've encountered an edge case: a relatively low
                 * vehicle speed and short prediction range, combined with a path
                 * that twists. In that case, it's possible that the predicted future
                 * point just around the bend is still within the vehicle's arrival
                 * radius.  In that case, aim a bit further beyond the vehicle's
                 * arrival radius so that it can continue moving.
                 */
                target = Path.MapPathDistanceToPoint(targetPathDistance + 2f * Vehicle.ArrivalRadius);
                seek   = Vehicle.GetSeekVector(target);
            }

            return(seek);
        }