Exemplo n.º 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)
        {
            /* Get the direction */
            Vector3 acceleration = rb.ConvertVector(targetPosition - transform.position);

            acceleration.Normalize();

            /* Accelerate to the target */
            acceleration *= maxSeekAccel;

            return(acceleration);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Finds the param for the closest point on the segment vw given the point p
        /// </summary>
        /// <returns>The parameter for segment.</returns>
        float GetParamForSegment(Vector3 p, Vector3 v, Vector3 w, MovementAIRigidbody rb)
        {
            Vector3 vw = w - v;

            vw = rb.ConvertVector(vw);

            float l2 = Vector3.Dot(vw, vw);

            if (l2 == 0)
            {
                return(0);
            }

            float t = Vector3.Dot(p - v, vw) / l2;

            if (t < 0)
            {
                t = 0;
            }
            else if (t > 1)
            {
                t = 1;
            }

            /* Multiple by (v - w).magnitude instead of Sqrt(l2) because we want the magnitude of the full 3D line segment */
            return(t * (v - w).magnitude);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Will return true if the character is at the end of the given path
        /// </summary>
        public bool IsAtEndOfPath(LinePath path)
        {
            /* If the path has only one node then just check the distance to that node. */
            if (path.Length == 1)
            {
                Vector3 endPos = rb.ConvertVector(path[0]);
                return(Vector3.Distance(rb.Position, endPos) < stopRadius);
            }
            /* Else see if the character is at the end of the path. */
            else
            {
                Vector3 finalDestination;

                /* Get the param for the closest position point on the path given the character's position */
                float param = path.GetParam(transform.position, rb);

                return(IsAtEndOfPath(path, param, out finalDestination));
            }
        }
Exemplo n.º 4
0
        public Vector3 GetSteering(ICollection <MovementAIRigidbody> targets)
        {
            Vector3 acceleration = Vector3.zero;

            foreach (MovementAIRigidbody r in targets)
            {
                /* Get the direction and distance from the target */
                Vector3 direction = rb.ColliderPosition - r.ColliderPosition;
                float   dist      = direction.magnitude;

                if (dist < maxSepDist)
                {
                    /* Calculate the separation strength (can be changed to use inverse square law rather than linear) */
                    var strength = sepMaxAcceleration * (maxSepDist - dist) / (maxSepDist - rb.Radius - r.Radius);

                    /* Added separation acceleration to the existing steering */
                    direction = rb.ConvertVector(direction);
                    direction.Normalize();
                    acceleration += direction * strength;
                }
            }

            return(acceleration);
        }
Exemplo n.º 5
0
        public Vector3 GetSteering(ICollection <MovementAIRigidbody> 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 */
            MovementAIRigidbody firstTarget = null;
            float   firstMinSeparation = 0, firstDistance = 0, firstRadius = 0;
            Vector3 firstRelativePos = Vector3.zero, firstRelativeVel = Vector3.zero;

            foreach (MovementAIRigidbody r in targets)
            {
                /* Calculate the time to collision */
                Vector3 relativePos   = rb.ColliderPosition - r.ColliderPosition;
                Vector3 relativeVel   = rb.RealVelocity - r.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 > rb.Radius + r.Radius + distanceBetween)
                {
                    continue;
                }

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

            /* 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 < rb.Radius + firstRadius + distanceBetween)
            {
                acceleration = rb.ColliderPosition - firstTarget.ColliderPosition;
            }
            /* Else calculate the future relative position */
            else
            {
                acceleration = firstRelativePos + firstRelativeVel * shortestTime;
            }

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

            return(acceleration);
        }