예제 #1
0
    /// <summary>
    /// Force to apply to the vehicle
    /// </summary>
    /// <returns>
    /// A <see cref="Vector3"/>
    /// </returns>
    protected override Vector3 CalculateForce()
    {
        Vector3 forceNode = Vector3.zero;

        if (_path != null)
        {
            var tStruct         = new PathRelativePosition();
            var futurePosition  = Vehicle.PredictFuturePosition(_predictionTime);
            var futurePathPoint = _path.MapPointToPath(futurePosition, ref tStruct);
#if TRACE_PATH
            Debug.DrawLine(Vehicle.Position, futurePosition, Color.red);
            Debug.DrawLine(Vehicle.Position, futurePathPoint, Color.green);
#endif

            forceNode = Vehicle.GetSeekVector(futurePathPoint, false);
        }
        return(forceNode);
    }
예제 #2
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);
        }

        // our goal will be offset from our path distance by this amount
        float pathDistanceOffset = (int)_direction * _predictionTime * Vehicle.Speed;

        // predict our future position
        Vector3 futurePosition = Vehicle.PredictFuturePosition(_predictionTime);

        // measure distance along path of our current and predicted positions
        float nowPathDistance    = _path.MapPointToPathDistance(Vehicle.Position);
        float futurePathDistance = _path.MapPointToPathDistance(futurePosition);

        // are we facing in the correction direction?
        bool rightway = ((pathDistanceOffset > 0) ? (nowPathDistance < futurePathDistance) : (nowPathDistance > futurePathDistance));

        // find the point on the path nearest the predicted future position
        var tStruct = new PathRelativePosition();

        _path.MapPointToPath(futurePosition, ref tStruct);


        // no steering is required if (a) our future position is inside
        // the path tube and (b) we are facing in the correct direction
        if ((tStruct.outside < 0) && rightway)
        {
            // TODO Evaluate. This assumes the vehicle has inertia, and would stop if inside the path tube
            return(Vector3.zero);
        }
        else
        {
            /*
             * 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
             * the return value of MapPointToPath is ignored above. 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.
             *
             * This also means that having too high a prediction time will
             * have the effect of the agent seemingly approaching the path
             * in an elliptical manner.
             */
            float targetPathDistance = nowPathDistance + pathDistanceOffset;
            var   target             = _path.MapPathDistanceToPoint(targetPathDistance);

            // return steering to seek target on path
            var seek = Vehicle.GetSeekVector(target);
            return(seek);
        }
    }