/// <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
        protected override Vector3 CalculateForce()
        {
            if (_menace == null || (Vehicle.Position - _menace.Position).sqrMagnitude > _sqrSafetyDistance)
            {
                return(Vector3.zero);
            }
            // offset from this to menace, that distance, unit vector toward menace
            var     position = Vehicle.PredictFutureDesiredPosition(_predictionTime);
            Vector3 offset   = _menace.Position - position;
            float   distance = offset.magnitude;

            float roughTime      = distance / _menace.Speed;
            float predictionTime = ((roughTime > _predictionTime) ?
                                    _predictionTime :
                                    roughTime);

            Vector3 target = _menace.PredictFuturePosition(predictionTime);

            // This was the totality of SteerToFlee
            Vector3 desiredVelocity = position - target;

            return(desiredVelocity - Vehicle.DesiredVelocity);
        }
예제 #3
0
        /// <summary>
        /// Calculates the force necessary to stay on the navmesh
        /// </summary>
        /// <returns>
        /// Force necessary to stay on the navmesh, or Vector3.zero
        /// </returns>
        /// <remarks>
        /// If the Vehicle is too far off the navmesh, Vector3.zero is retured.
        /// This won't lead back to the navmesh, but there's no way to determine
        /// a way back onto it.
        /// </remarks>
        protected override Vector3 CalculateForce()
        {
            NavMeshHit hit;

            /*
             * While we could just calculate line as (Velocity * predictionTime)
             * and save ourselves the substraction, this allows other vehicles to
             * override PredictFuturePosition for their own ends.
             */
            Vector3 futurePosition = Vehicle.PredictFuturePosition(_minTimeToCollision);
            Vector3 movement       = futurePosition - Vehicle.Position;

                #if ANNOTATE_NAVMESH
            Debug.DrawRay(Vehicle.Position, movement, Color.cyan);
                #endif

            if (_offMeshCheckingEnabled)
            {
                Vector3 probePosition = Vehicle.Position + _probePositionOffset;

                Profiler.BeginSample("Off-mesh checking");
                NavMesh.SamplePosition(probePosition, out hit, _probeRadius, _navMeshLayerMask);
                Profiler.EndSample();

                if (!hit.hit)                   // we're not on the navmesh
                {
                    Profiler.BeginSample("Find closest edge");
                    NavMesh.FindClosestEdge(probePosition, out hit, _navMeshLayerMask);
                    Profiler.EndSample();

                    if (hit.hit)                        // closest edge found
                    {
                                        #if ANNOTATE_NAVMESH
                        Debug.DrawLine(probePosition, hit.position, Color.red);
                                        #endif

                        return((hit.position - probePosition).normalized * Vehicle.MaxForce);
                    }
                    else                                        // no closest edge - too far off the mesh
                    {
                                        #if ANNOTATE_NAVMESH
                        Debug.DrawLine(probePosition, probePosition + Vector3.up * 3, Color.red);
                                        #endif

                        return(Vector3.zero);
                    }
                }
            }


            Profiler.BeginSample("NavMesh raycast");
            NavMesh.Raycast(Vehicle.Position, futurePosition, out hit, _navMeshLayerMask);
            Profiler.EndSample();

            if (!hit.hit)
            {
                return(Vector3.zero);
            }

            Vector3 avoidance = Vector3.zero;
            Profiler.BeginSample("Calculate NavMesh avoidance");
            Vector3 moveDirection = Vehicle.Velocity.normalized;
            avoidance = OpenSteerUtility.perpendicularComponent(hit.normal, moveDirection);

            avoidance.Normalize();

                #if ANNOTATE_NAVMESH
            Debug.DrawLine(Vehicle.Position, Vehicle.Position + avoidance, Color.white);
                #endif

            avoidance += moveDirection * Vehicle.MaxForce * _avoidanceForceFactor;

                #if ANNOTATE_NAVMESH
            Debug.DrawLine(Vehicle.Position, Vehicle.Position + avoidance, Color.yellow);
                #endif

            Profiler.EndSample();

            return(avoidance);
        }