Beispiel #1
0
        /// <summary>
        /// A seek steering behavior. Will return the steering for the current game object to seek a given position
        /// </summary>
        public Vector3 Seek(Vector3 targetPosition, float maxSeekAccel)
        {
            Vector3 acceleration = physicsController.ConvertVector(targetPosition - transform.position);

            acceleration.Normalize();
            acceleration *= maxSeekAccel;

            return(acceleration);
        }
Beispiel #2
0
        public Vector3 GetAcceleration()
        {
            float distanceTravelled = racingLineProgress * pathManager.RacingLinePath.path.length;
            float futureDistance    = (distanceTravelled + predictionStep) % pathManager.RacingLinePath.path.length;

            TargetPosition = pathManager.RacingLinePath.path.GetPointAtDistance(futureDistance, pathManager.TrackType);
            TargetPosition = physicsController.ConvertVector(TargetPosition);

            // adds randomness on horizontal axis
            float pathRandomOffset = Mathf.Sin(Mathf.PingPong(Time.time * pathFollowingRandomnessSpeed, pathFollowingRandomnessDistance));

            TargetPosition += agent.transform.TransformDirection(new Vector3(pathRandomOffset, 0, 0));

            // get the angle between the nearest and next anchor point
            int nearestAnchorIndex = pathManager.GetNearestAnchorIndex(self.PathProgress);

            nearestAnchorPoint = pathManager.GetPointOnRacingLine(nearestAnchorIndex);
            Vector3 nearestForward = pathManager.GetAnchorDirection(nearestAnchorIndex);
            Vector3 nextForward    = pathManager.GetAnchorDirection(nearestAnchorIndex + 1);
            float   nodeAngle      = Vector3.Angle(nearestForward, nextForward);

            // Calculate desired velocity adjusted to incoming corners angle
            float desiredCornerVelocity  = steering.maxVelocity / nodeAngle;
            float targetSlowDownDistance = physicsController.Velocity.magnitude / desiredCornerVelocity / steering.handling / corneringAggressionMultiplier;

            // Get the right direction for the linear acceleration
            Vector3 targetVelocity = TargetPosition - physicsController.Position;

            // Calculate the target speed, full speed at slowRadius distance and 0 speed at 0 distance
            float targetSpeed;

            if (targetVelocity.magnitude <= targetSlowDownDistance)
            {
                targetSpeed = steering.maxVelocity * (targetVelocity.magnitude / targetSlowDownDistance);
            }
            else
            {
                targetSpeed = steering.maxVelocity;
            }

            // Give targetVelocity the correct speed
            targetVelocity.Normalize();
            targetVelocity *= targetSpeed;
            TargetVelocity  = targetVelocity;

            // Calculate the linear acceleration we want
            Vector3 acceleration = targetVelocity - physicsController.Velocity;

            // Rather than accelerate the character to the correct speed in 1 second, accelerate so we reach the desired speed in timeToTarget seconds
            acceleration *= 1 / steering.accelerationTime;

            // Limit acceleration to max:
            if (acceleration.magnitude > steering.maxAcceleration)
            {
                acceleration.Normalize();
                acceleration *= steering.maxAcceleration;
            }

            return(acceleration);
        }
Beispiel #3
0
        private bool DetectedObstacle(Vector3 facingDir, out GenericCastHit firstHit)
        {
            facingDir = controller.ConvertVector(facingDir).normalized;

            Vector3[] dirs = new Vector3[3];
            dirs[0] = facingDir;

            float orientation = SteeringHelper.VectorToOrientation(facingDir);

            dirs[1] = SteeringHelper.OrientationToVector(orientation + sideWhiskerAngle * Mathf.Deg2Rad);
            dirs[2] = SteeringHelper.OrientationToVector(orientation - sideWhiskerAngle * Mathf.Deg2Rad);

            return(CastWhiskers(dirs, out firstHit));
        }
Beispiel #4
0
        private Vector3 GetAccelerationForPlayerAvoidance(ICollection <RigidbodyMovementController> targets)
        {
            Vector3 acceleration = Vector3.zero;

            // 1. Find the target that the character will collide with first
            // The first collision time
            float shortestTime = float.PositiveInfinity;

            // The first target that will collide and other data that we will need and can avoid recalculating
            RigidbodyMovementController firstTarget = null;
            float   firstMinSeparation = 0;
            float   firstDistance      = 0;
            float   firstRadius        = 0;
            Vector3 firstRelativePos   = Vector3.zero;
            Vector3 firstRelativeVel   = Vector3.zero;

            foreach (RigidbodyMovementController target in targets)
            {
                // Calculate the time to collision
                Vector3 relativePos   = controller.ColliderPosition - target.ColliderPosition;
                Vector3 relativeVel   = controller.RealVelocity - target.RealVelocity;
                float   distance      = relativePos.magnitude;
                float   relativeSpeed = relativeVel.magnitude;

                if (relativeSpeed == 0)
                {
                    continue;
                }

                float timeToCollision = -1 * Vector3.Dot(relativePos, relativeVel) / (relativeSpeed * relativeSpeed);

                // Check if they will collide at all
                Vector3 separation    = relativePos + relativeVel * timeToCollision;
                float   minSeparation = separation.magnitude;

                if (minSeparation > controller.ColliderRadius + target.ColliderRadius + collisionDistanceOffset)
                {
                    continue;
                }

                // Check if its the shortest
                if (timeToCollision > 0 && timeToCollision < shortestTime)
                {
                    shortestTime       = timeToCollision;
                    firstTarget        = target;
                    firstMinSeparation = minSeparation;
                    firstDistance      = distance;
                    firstRelativePos   = relativePos;
                    firstRelativeVel   = relativeVel;
                    firstRadius        = target.ColliderRadius;
                }
            }

            // 2. Calculate the steering
            // If we have no target then exit
            if (firstTarget == null)
            {
                return(acceleration);
            }

            // If we are going to collide with no separation or if we are already colliding then steer based on current position
            if (firstMinSeparation <= 0 || firstDistance < controller.ColliderRadius + firstRadius + collisionDistanceOffset)
            {
                acceleration = controller.ColliderPosition - firstTarget.ColliderPosition;
            }
            // Else calculate the future relative position
            else
            {
                acceleration = firstRelativePos + firstRelativeVel * shortestTime;
            }

            // Avoid the target
            acceleration = controller.ConvertVector(acceleration);
            acceleration.Normalize();
            acceleration *= steering.maxAcceleration;

            return(acceleration);
        }