Example #1
0
    /* A seek steering behavior. Will return the steering for the current game object to seek a given position */
    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);
    }
Example #2
0
    /* Finds the param for the closest point on the segment vw given the point p */
    private 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);
    }
Example #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));
        }
    }
Example #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);
    }
Example #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);
    }