예제 #1
0
        /// <summary>
        /// The WallAvoidance behavior. Will return a steering based on finding collisions and avoid them
        /// </summary>
        /// <param name="facingDir">The direction we are facing</param>
        /// <returns></returns>
        public Vector3 GetSteering(Vector3 facingDir)
        {
            var acceleration = Vector3.zero;

            /* Creates the ray direction vector */
            var rayDirs = new Vector3[3];

            rayDirs[0] = facingDir.normalized;

            var orientation = Mathf.Atan2(_rb.velocity.x, _rb.velocity.z);

            rayDirs[1] = OrientationToVector(orientation + LookToSideAngle * Mathf.Deg2Rad);
            rayDirs[2] = OrientationToVector(orientation - LookToSideAngle * Mathf.Deg2Rad);

            /* If no collision do nothing */
            if (FindObstacle(rayDirs, out var hit) == false)
            {
                return(acceleration);
            }

            /* Create a target away from the wall to seek */
            var targetPosition = hit.point + hit.normal * WallAvoidDistance;

            /* If velocity and the collision normal are parallel then move the target a bit to the left or right of the normal */
            var cross = Vector3.Cross(_rb.velocity, hit.normal);

            if (cross.magnitude < 0.005f)
            {
                targetPosition += new Vector3(-hit.normal.z, hit.normal.y, hit.normal.x);
            }

            return(_seek.GetSteering(targetPosition, MaxAcceleration));
        }
예제 #2
0
    public Steering GetSteering()
    {
        if (path == null || currentPoint >= path.Length)
        {
            if (path == null)
            {
                Debug.LogError("Path is invalid: Null");
            }
            if (currentPoint >= path.Length)
            {
                Debug.LogError("Path is invalid: Out of bounds");
            }
            return(new Steering());
        }

        UpdateExtraRadius();
        float arrivalRadius2 = arrivalRadius + extraRadius;

        float distance = Util.HorizontalDist(path[currentPoint], npc.position);

        if (distance < arrivalRadius2)
        {
            if (currentPoint != Mathf.Min(currentPoint + 1, path.Length - 1))
            {
                extraRadius = 0;
                near        = false;
            }
            currentPoint = Mathf.Min(currentPoint + 1, path.Length - 1); //When it reaches the last stays on it
            //if (currentPoint == path.Length - 2)
            // return Arrive.GetSteering(path[currentPoint], npc, 1f, maxAccel /*50*/);
        }

        return(Seek.GetSteering(path[currentPoint], npc, maxAccel /*50*/, false));
    }
예제 #3
0
        /// <summary>
        /// The Pursue behavior. Will return a steering based on prediction of the movement of the target
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public Vector3 GetSteering(Rigidbody target)
        {
            /* Calculate the distance to the target */
            var direction = target.position - transform.position;
            var distance  = direction.magnitude;

            /* Get the character's speed */
            var speed = _rb.velocity.magnitude;

            /* Calculate the prediction time */
            float prediction;

            if (speed <= distance / MaxPrediction)
            {
                prediction = MaxPrediction;
            }
            else
            {
                prediction = distance / speed;
            }

            /* Put the target together based on where we think the target will be */
            var predictedTarget = target.position + target.velocity * prediction;

            return(_seek.GetSteering(predictedTarget));
        }
예제 #4
0
파일: Cohesion.cs 프로젝트: fylux/GameAI
    public static Steering GetSteering(Agent npc, float threshold, float decayCoefficient, float maxAccel, bool visibleRays)
    {
        Steering steering = new Steering();

        int     neighbours   = 0;
        Vector3 centerOfMass = Vector3.zero;

        int layerMask = 1 << 9;

        Collider[] hits = Physics.OverlapSphere(npc.position, threshold, layerMask);
        foreach (Collider coll in hits)
        { //Comprobar con un SphereCast, en vez de Tag quiza usar Layers
            Agent agent    = coll.GetComponent <Agent>();
            float distance = Util.HorizontalDist(agent.position, npc.position);


            if (agent != npc && distance < threshold)
            {
                centerOfMass += agent.position;
                neighbours++;
            }
        }

        if (neighbours > 0)
        {
            centerOfMass /= neighbours;
            return(Seek.GetSteering(centerOfMass, npc, maxAccel, visibleRays));
        }

        return(steering);
    }
예제 #5
0
파일: GoTo.cs 프로젝트: fylux/GameAI
    public Steering Apply()
    {
        Steering st = new Steering();

        if (finished)
        {
            callback(true);
            return(st);
        }

        if (followPath.HasPath())
        {
            if (Time.fixedTime - timeStamp > reconsiderSeconds)
            {
                timeStamp = Time.fixedTime;
                SetNewTarget(target, false);
            }
        }
        else
        {
            st += Seek.GetSteering(target, agent, 500f); //If path has not been solved yet just do Seek.
        }
        st += followPath.Apply();                        //If there is no path just avoid collisions

        return(st);
    }
예제 #6
0
    void Update()
    {
        SteeringOutput steering;

        //Update position and rotation
        transform.position += linearVelocity * Time.deltaTime;
        Vector3 angularIncrement = new Vector3(0, angularVelocity * Time.deltaTime, 0);

        transform.eulerAngles += angularIncrement;

        switch (type)
        {
        case SteeringType.Pursue:
            steering = pursueAI.GetSteering();
            break;

        case SteeringType.Evade:
            steering = evadeAI.GetSteering();
            break;

        case SteeringType.FollowPath:
            steering = followAI.GetSteering();
            break;

        case SteeringType.Seek:
            steering = seekAI.GetSteering();
            break;

        case SteeringType.Flee:
            steering = fleeAI.GetSteering();
            break;

        case SteeringType.Seperation:
            steering = seperationAI.GetSteering();
            break;

        default:
            steering = seekAI.GetSteering();
            break;
        }

        linearVelocity  += steering.linear * Time.deltaTime;
        angularVelocity += steering.angular * Time.deltaTime;

        //Update kinematic reference with complex data it can't get by itself
        kinematic.GetData(steering);
    }
예제 #7
0
    public override void GetAction(AIInputController script)
    {
        script.steering += Seek.GetSteering(script.target._static.position, script.self._static.position, script.tank.maxSpeed).Weight(1.0f);

        if (script.CheckShieldDanger())
        {
            transitions[0].bTriggered = true;
        }
    }
예제 #8
0
    public static Steering GetSteering(Vector3 target, Agent npc, float maxAccel, bool visibleRays = false)
    {
        Steering steering = -Seek.GetSteering(target, npc, maxAccel, false);

        if (visibleRays)
        {
            drawRays(npc.position, steering.linear, Color.magenta);
        }


        return(steering);
    }
예제 #9
0
    public Steering GetSteering()
    {
        if (path == null || currentPoint >= path.Length)
        {
            if (path == null)
            {
                Debug.LogError("Path is invalid: Null");
            }
            if (currentPoint >= path.Length)
            {
                Debug.LogError("Path is invalid: Out of bounds");
            }
            return(new Steering());
        }

        float distance = Util.HorizontalDist(path[currentPoint], npc.position);

        if (distance < arrivalRadius)
        {
            if (type == FollowT.STAY)
            {
                currentPoint = Mathf.Min(currentPoint + 1, path.Length - 1); //When it reaches the last stays on it
                //if (currentPoint == path.Length - 1)
                // return Arrive.GetSteering(path[currentPoint], npc, 1f,maxAccel /*50*/);
            }
            else if (type == FollowT.BACK)
            {
                currentPoint += direction;
                //Needs to be run twice, since the currentPoint will remain the same the first time
                if (currentPoint >= path.Length || currentPoint < 0)
                {
                    direction     = 1 - direction;
                    currentPoint += direction;
                }
            }
            else if (type == FollowT.LOOP)
            {
                //When it reaches the last it starts from the begging
                currentPoint++;
                if (currentPoint >= path.Length)
                {
                    currentPoint = 0;
                }
            }
        }

        return(Seek.GetSteering(path[currentPoint], npc, maxAccel /*50*/, visibleRays));
    }
예제 #10
0
        /// <summary>
        /// The Wander behavior. Will return a steering based on its current postion and the its target
        /// </summary>
        /// <returns></returns>
        public Vector3 GetSteering()
        {
            _wanderTargetPosition = WanderTargetTransform.position;

            //get the jitter for this time frame
            var jitter = WanderJitter * Time.deltaTime;

            //add a small random vector to the target's position
            _wanderTargetPosition += new Vector3(Random.Range(-1f, 1f) * jitter, 0, Random.Range(-1f, 1f) * jitter);

            //make the wanderTarget fit on the wander circle again
            _wanderTargetPosition *= WanderRadius;

            //move the target in front of the character
            var targetPosition = transform.forward * WanderDistance + _wanderTargetPosition;

            // TODO this line is not optimal and should be only used for debugging
            Debug.DrawLine(transform.position, targetPosition);

            return(_seek.GetSteering(targetPosition));
        }
예제 #11
0
    public Steering Apply()
    {
        if (IsFinished())
        {
            callback(true);
        }

        if (Time.frameCount % 1 == 0)
        {
            RequestPath();
        }

        if (pathF.path != null)
        {
            return(pathF.GetSteering());
        }
        else
        {
            return(Seek.GetSteering(target, agent, 50f)); //If path has not been solved yet just do Seek.
        }
    }
예제 #12
0
파일: Wanderer.cs 프로젝트: SK0P3iN/IA-GOAP
        /// <summary>
        /// The Wander behavior. Will return a steering based on its current postion and the radius where it can wander
        /// </summary>
        /// <returns></returns>
        public Vector3 GetSteering()
        {
            var characterOrientation = transform.rotation.eulerAngles.y * Mathf.Deg2Rad;

            /* Update the wander orientation */
            _wanderOrientation += RandomBinomial() * WanderRate;

            /* Calculate the combined target orientation */
            var targetOrientation = _wanderOrientation + characterOrientation;

            /* Calculate the center of the wander circle */
            var targetPosition = transform.position + OrientationToVector(characterOrientation) * WanderOffset;

            //debugRing.transform.position = targetPosition;

            /* Calculate the target position */
            targetPosition = targetPosition + OrientationToVector(targetOrientation) * WanderRadius;

            //Debug.DrawLine (transform.position, targetPosition);

            return(_seek.GetSteering(targetPosition));
        }
예제 #13
0
    public static Steering GetSteering(Agent npc, float maxAccel, LayerMask layerMask, float obstacleMaxDist, float avoidDist, float whiskerSeparation, bool visibleRays = false)
    {
        Steering steering = new Steering();

        Vector3 target = Vector3.zero;

        Vector3 leftRay   = npc.position + npc.getRight() * whiskerSeparation / 2f;
        Vector3 rightRay  = npc.position - npc.getRight() * whiskerSeparation / 2f;
        Vector3 centerRay = npc.position;

        AvoidanceRay[] rays = { new AvoidanceRay(leftRay,   Util.RotateVector(npc.velocity.normalized,  30) * obstacleMaxDist / 2.2f),
                                new AvoidanceRay(rightRay,  Util.RotateVector(npc.velocity.normalized, -30) * obstacleMaxDist / 2.2f),
                                new AvoidanceRay(centerRay, npc.velocity.normalized * obstacleMaxDist) };

        RaycastHit hitInfo;

        bool rayHit = false;

        foreach (AvoidanceRay ray in rays)
        {
            if (Physics.Raycast(ray.startPoint, ray.direction, out hitInfo, ray.length, layerMask) && !rayHit)
            {
                target = hitInfo.normal * avoidDist + npc.position; //Errata, book proposes hitInfo.point instead of npc.position
                if (visibleRays)
                {
                    Debug.DrawLine(ray.startPoint, hitInfo.point, Color.red);
                }

                rayHit   = true;
                steering = Seek.GetSteering(target, npc, maxAccel, visibleRays);
            }
            else if (visibleRays)
            {
                Debug.DrawRay(ray.startPoint, ray.direction.normalized * ray.length, Color.yellow);
            }
        }
        return(steering);
    }
    // Update is called once per frame
    void Update()
    {
        //Debug.Log(target);
        // Check distance to see if steering behavior should be applied to AI
        // float targetDist = (transform.position - target.transform.position).magnitude;
        // if (!DistanceActivation || targetDist >= activationRange) { }
        transform.position += linearVelocity * Time.deltaTime;
        // adding angular velocity to current transform rotation y component
        if (float.IsNaN(angularVelocity))
        {
            angularVelocity = 0;
        }
        transform.eulerAngles += new Vector3(0, angularVelocity * Time.deltaTime, 0);
        // control to switch to proper steering behavior
        if (avoidObstacles)
        {
            ObstacleAvoidance avoid = new ObstacleAvoidance();
            avoid.ai = this;
            SteeringOutput avoidForce = avoid.GetSteering();
            if (avoidForce != null)
            {
                linearVelocity += avoidForce.linear;
            }
        }
        if (seperationObstacles.Length > 0)
        {
            Seperation seperation = new Seperation();
            seperation.targets = seperationObstacles;
            seperation.ai      = this;
            SteeringOutput seperateForce = seperation.GetSteering();
            // check to see if steering is greater than zero and lock out control from other steering
            if (seperateForce.linear.magnitude > 0)
            {
                seperating = true;
            }
            else
            {
                seperating = false;
            }
            linearVelocity += seperateForce.linear * Time.deltaTime;
        }
        if (collisionAvoidance.Length > 0)
        {
            CollisionAvoidance avoidKinematic = new CollisionAvoidance();
            avoidKinematic.ai      = this;
            avoidKinematic.targets = collisionAvoidance;
            SteeringOutput avoidKinematicForce = avoidKinematic.GetSteering();
            if (avoidKinematicForce != null)
            {
                linearVelocity += avoidKinematicForce.linear;
            }
        }

        switch (movementType)
        {
        case "seek":
            Seek mySeek = new Seek();
            mySeek.ai = this;
            // if seek is false set seek property on class to false to activate flee
            mySeek.seek   = true;
            mySeek.target = target;
            SteeringOutput steeringSeek = mySeek.GetSteering();
            if (!seperating)
            {
                linearVelocity += steeringSeek.linear * Time.deltaTime;
            }
            if (linearVelocity.magnitude > maxSpeed)
            {
                linearVelocity.Normalize();
                linearVelocity *= maxSpeed;
            }
            break;

        case "flee":
            Seek myFlee = new Seek();
            myFlee.ai = this;
            // if seek is false set seek property on class to false to activate flee
            myFlee.seek   = false;
            myFlee.target = target;
            SteeringOutput steeringFlee = myFlee.GetSteering();
            if (!seperating)
            {
                linearVelocity += steeringFlee.linear * Time.deltaTime;
            }
            if (linearVelocity.magnitude > maxSpeed)
            {
                linearVelocity.Normalize();
                linearVelocity *= maxSpeed;
            }
            break;

        case "arrive":
            Arrive myArrive = new Arrive();
            myArrive.ai     = this;
            myArrive.target = target;
            SteeringOutput steeringArrive = myArrive.GetSteering();
            if (!seperating)
            {
                linearVelocity += steeringArrive.linear * Time.deltaTime;
            }
            break;

        case "pursue":
            Pursue myPursue = new Pursue();
            myPursue.ai     = this;
            myPursue.target = target;
            SteeringOutput steeringPursue = myPursue.GetSteering();
            if (!seperating)
            {
                linearVelocity += steeringPursue.linear * Time.deltaTime;
            }
            if (linearVelocity.magnitude > maxSpeed)
            {
                linearVelocity.Normalize();
                linearVelocity *= maxSpeed;
            }
            break;

        case "evade":
            Pursue myEvade = new Pursue();
            myEvade.ai     = this;
            myEvade.target = target;
            // This changes the seek flag in the parent Seek class of Pursue, sending it the flee vector instead
            myEvade.seek = false;
            SteeringOutput steeringEvade = myEvade.GetSteering();
            if (!seperating)
            {
                linearVelocity += steeringEvade.linear * Time.deltaTime;
            }
            if (linearVelocity.magnitude > maxSpeed)
            {
                linearVelocity.Normalize();
                linearVelocity *= maxSpeed;
            }
            break;

        default:
            // provide no input
            break;
            // If obstacles have been provided, return steering to seperate from them
        }

        switch (rotationType)
        {
        case "face":
            Face myFace = new Face();
            myFace.ai     = this;
            myFace.target = target;
            SteeringOutput steeringFace = myFace.GetSteering();
            if (steeringFace != null)
            {
                //    linearVelocity += steering.linear * Time.deltaTime;
                angularVelocity += steeringFace.angular * Time.deltaTime;
            }

            break;

        case "align":
            Align myAlign = new Align();
            myAlign.ai     = this;
            myAlign.target = target;
            SteeringOutput steeringAlign = myAlign.GetSteering();
            if (steeringAlign != null)
            {
                //linearVelocity += steering.linear * Time.deltaTime;
                angularVelocity += steeringAlign.angular * Time.deltaTime;
            }
            break;

        case "look":
            LookWhereGoing myLook = new LookWhereGoing();
            myLook.ai     = this;
            myLook.target = target;
            SteeringOutput steeringLook = myLook.GetSteering();
            if (steeringLook != null)
            {
                //linearVelocity += steering.linear * Time.deltaTime;
                angularVelocity += steeringLook.angular * Time.deltaTime;
            }
            break;

        default:
            //provide no input
            break;
        }
    }
    // Update is called once per frame
    void Update()
    {
        transform.position += linearVelocity * Time.deltaTime;
        // adding angular velocity to current transform rotation y component
        if (float.IsNaN(angularVelocity))
        {
            angularVelocity = 0;
        }
        transform.eulerAngles += new Vector3(0, angularVelocity * Time.deltaTime, 0);
        //dynamicSteering steering = new Seek();
        // control to switch to proper steering behavior
        if (!arrive)
        {
            Seek mySeek = new Seek();
            mySeek.ai = this;
            // if seek is false set seek property on class to false to activate flee
            if (!seek)
            {
                mySeek.seek = false;
            }
            else
            {
                mySeek.seek = true;
            }
            mySeek.target = target;
            SteeringOutput steering = mySeek.GetSteering();
            linearVelocity  += steering.linear * Time.deltaTime;
            angularVelocity += steering.angular * Time.deltaTime;
            if (linearVelocity.magnitude > maxSpeed)
            {
                linearVelocity.Normalize();
                linearVelocity *= maxSpeed;
            }
        }
        else
        {
            Arrive myArrive = new Arrive();
            myArrive.ai     = this;
            myArrive.target = target;
            SteeringOutput steering = myArrive.GetSteering();

            linearVelocity  += steering.linear * Time.deltaTime;
            angularVelocity += steering.angular * Time.deltaTime;
        }
        if (align)
        {
            Align myAlign = new Align();
            myAlign.ai     = this;
            myAlign.target = target;
            SteeringOutput steering = myAlign.GetSteering();
            if (steering != null)
            {
                linearVelocity  += steering.linear * Time.deltaTime;
                angularVelocity += steering.angular * Time.deltaTime;
            }
        }
        if (lookWhereGoing && !align && !face)
        {
            LookWhereGoing myLook = new LookWhereGoing();
            myLook.ai     = this;
            myLook.target = target;
            SteeringOutput steering = myLook.GetSteering();
            if (steering != null)
            {
                linearVelocity  += steering.linear * Time.deltaTime;
                angularVelocity += steering.angular * Time.deltaTime;
            }
            else
            {
                Debug.Log("Returning Null");
            }
        }
        if (!lookWhereGoing && !align && face)
        {
            Face myFace = new Face();
            myFace.ai     = this;
            myFace.target = target;
            SteeringOutput steering = myFace.GetSteering();
            if (steering != null)
            {
                linearVelocity  += steering.linear * Time.deltaTime;
                angularVelocity += steering.angular * Time.deltaTime;
            }
        }
    }
    void Update()
    {
        SteeringOutput movementSteering;

        //SteeringOutput lookSteering;
        //Update position and rotation
        transform.position += linearVelocity * Time.deltaTime;
        Vector3 angularIncrement = new Vector3(0, angularVelocity * Time.deltaTime, 0);

        transform.eulerAngles += angularIncrement;

        switch (moveType)
        {
        case SteeringType.Pursue:
            movementSteering = pursueAI.GetSteering();
            break;

        case SteeringType.Evade:
            movementSteering = evadeAI.GetSteering();
            break;

        case SteeringType.FollowPath:
            movementSteering = followAI.GetSteering();
            break;

        case SteeringType.Seek:
            movementSteering = seekAI.GetSteering();
            break;

        case SteeringType.Flee:
            movementSteering = fleeAI.GetSteering();
            break;

        case SteeringType.Seperation:
            movementSteering = seperationAI.GetSteering();
            break;

        case SteeringType.Arrive:
            movementSteering = arriveAI.GetSteering();
            break;

        case SteeringType.CollisionAvoidance:
            movementSteering = avoidAI.GetSteering();
            break;

        case SteeringType.ObstacleAvoidance:
            movementSteering = obstacleAI.GetSteering();
            break;

        default:
            movementSteering = new SteeringOutput();
            break;
        }

        if (movementSteering != null)
        {
            linearVelocity += movementSteering.linear * Time.deltaTime;
            //angularVelocity += movementSteering.angular * Time.deltaTime;
        }

        switch (lookType)
        {
        case LookType.None:
            break;

        case LookType.Align:
            lookSteering = alignAI.GetSteering();
            break;

        case LookType.Face:
            lookSteering = faceAI.GetSteering();
            break;

        case LookType.LookWhereGoing:
            lookSteering = lookAI.GetSteering();
            break;

        default:
            lookSteering = alignAI.GetSteering();
            break;
        }

        if (lookSteering != null)
        {
            angularVelocity += lookSteering.angular * Time.deltaTime;
        }
        //Update kinematic reference with complex data it can't get by itself
        kinematic.GetData(movementSteering);
        kinematic.GetData(lookSteering);
    }