Beispiel #1
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);
            var offset   = _menace.Position - position;
            var distance = offset.magnitude;

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

            //var target = _menace.PredictFuturePosition(predictionTime);

            var target = _menace.PredictFuturePosition(predictionTime) + _offset;

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

            //Debug.DrawRay(Vehicle.Position, desiredVelocity, Color.blue);

            return(desiredVelocity - Vehicle.DesiredVelocity);
        }
        /// <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.
             */
            var futurePosition = Vehicle.PredictFuturePosition(_minTimeToCollision);
            var movement       = futurePosition - Vehicle.Position;

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

            if (_offMeshCheckingEnabled)
            {
                var 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);
                    } // 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);
            }

            Profiler.BeginSample("Calculate NavMesh avoidance");
            var moveDirection = Vehicle.Velocity.normalized;
            var 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);
        }