Ejemplo n.º 1
0
    override public void Execute()
    {
        directionChangeTimer -= Time.deltaTime;
        if (directionChangeTimer <= 0.0f)
        {
            fleeVelocity         = StaticMovementAlgorithms.KinematicWander(selfBody, SPEED, movementVariance, Owner.transform.forward);
            directionChangeTimer = Random.Range(MIN_TIME, MAX_TIME);
        }

        Vector3 avoidanceVelocity =
            CollisionPrediction.AvoidCollisions(Owner.gameObject, AVOID_DETECTION_RADIUS, AVOID_MARGIN, SPEED, LayerMask.GetMask("Obstacle"), selfColliders);

        //if we're in range of the thing we want to flee stop wandering
        if (Vector3.Distance(Owner.transform.position, target.transform.position) < FLEE_RADIUS)
        {
            Debug.Log(Vector3.Distance(Owner.transform.position, target.transform.position));
            fleeVelocity = StaticMovementAlgorithms.KinematicFlee(selfBody, target.transform.position, SPEED);
        }

        if (avoidanceVelocity != Vector3.zero)
        {
            targetVelocity = 0.6f * fleeVelocity + 0.4f * avoidanceVelocity;
        }
        else
        {
            targetVelocity = fleeVelocity;
        }
        targetVelocity.y = 0.0f;
        targetVelocity   = targetVelocity.normalized * SPEED;
    }
    override public void Execute()
    {
        directionChangeTimer -= Time.deltaTime;
        if (directionChangeTimer <= 0.0f)
        {
            fleeVelocity         = StaticMovementAlgorithms.KinematicWander(selfBody, SPEED, movementVariance, Owner.transform.forward);
            directionChangeTimer = Random.Range(MIN_TIME, MAX_TIME);
        }

        Vector3 avoidanceVelocity =
            CollisionPrediction.AvoidCollisions(Owner.gameObject, AVOID_DETECTION_RADIUS, AVOID_MARGIN, SPEED, LayerMask.GetMask("Obstacle"), selfColliders);

        //if we're in range of the thing we want to flee stop wandering
        float closestPosition = fleeGroup.Select(x => Mathf.Min(Vector3.Distance(Owner.transform.position, x.transform.position))).Aggregate((x, y) => Mathf.Min(x, y));

        if (closestPosition < FLEE_RADIUS)
        {
            //Debug.Log(Vector3.Distance(Owner.transform.position, target.transform.position));
            fleeVelocity = StaticMovementAlgorithms.KinematicFleeMultiple(this.Owner.GetComponent <Rigidbody>(),
                                                                          fleeGroup.Select(x => x.transform.position).ToList <Vector3>(),
                                                                          SPEED,
                                                                          1.0f).normalized;
        }

        if (avoidanceVelocity != Vector3.zero)
        {
            targetVelocity = 0.6f * fleeVelocity + 0.4f * avoidanceVelocity;
        }
        else
        {
            targetVelocity = fleeVelocity;
        }
        targetVelocity.y = 0.0f;
        targetVelocity   = targetVelocity.normalized * SPEED;
    }
    void Update()
    {
        Vector3 newVelocity = StaticMovementAlgorithms.KinematicAvoidObstacles(rigidbody, obstacles, 10, radius, speed);

        newVelocity        = StaticMovementAlgorithms.GetInterpolatedVelocity(rigidbody, newVelocity, 1);
        rigidbody.velocity = newVelocity;
        rigidbody.rotation = StaticMovementAlgorithms.GetOrientation(newVelocity, Vector3.forward);
    }
Ejemplo n.º 4
0
    override public void Execute()
    {
        Rigidbody body = Owner.GetComponent <Rigidbody>();

        directionChangeTimer -= Time.deltaTime;
        if (directionChangeTimer <= 0.0f)
        {
            wanderVelocity       = StaticMovementAlgorithms.KinematicWander(body, SPEED, movementVariance, Owner.transform.forward);
            directionChangeTimer = Random.Range(MIN_TIME, MAX_TIME);
        }
        targetVelocity   = wanderVelocity;
        targetVelocity.y = 0.0f;
    }
Ejemplo n.º 5
0
    override public void Execute()
    {
        flockTimer -= Time.deltaTime;
        if (flockTimer > 0.0f)
        {
            return;
        }

        Rigidbody selfBody         = this.Owner.GetComponent <Rigidbody>();
        Vector3   velocityMatching = target.GetComponent <Rigidbody>().velocity;

        Vector3 separation = StaticMovementAlgorithms.KinematicFleeMultiple(this.Owner.GetComponent <Rigidbody>(),
                                                                            group.Select(x => x.transform.position).ToList <Vector3>(),
                                                                            SPEED,
                                                                            0.2f);

        Vector3 centerOfMass = new Vector3();

        foreach (Enemy member in group)
        {
            centerOfMass += member.transform.position;
        }
        centerOfMass = centerOfMass / group.Count;
        Vector3 displace = centerOfMass - selfBody.position;
        Vector3 cohesion = displace.magnitude * StaticMovementAlgorithms.KinematicSeek(this.Owner.GetComponent <Rigidbody>(), centerOfMass, SPEED).normalized;

        flockingVelocity = velocityMatching
                           + separation
                           + cohesion;
        if (flockingVelocity.sqrMagnitude > SPEED * SPEED)
        {
            flockingVelocity = flockingVelocity.normalized * SPEED;
        }

        //Vector3 avoidanceVelocity = StaticMovementAlgorithms.KinematicAvoidObstacles(Owner.GetComponent<Rigidbody>(), LayerMask.GetMask("Obstacle"), 5.0f, 1.0f, SPEED);
        Vector3 avoidanceVelocity =
            CollisionPrediction.AvoidCollisions(Owner.gameObject, AVOID_DETECTION_RADIUS, AVOID_MARGIN, SPEED, LayerMask.GetMask("Obstacle"), selfColliders);

        avoidanceVelocity.y = 0;
        if (avoidanceVelocity != Vector3.zero)
        {
            targetVelocity = 0.4f * avoidanceVelocity + 0.6f * flockingVelocity;
        }
        else
        {
            targetVelocity = flockingVelocity;
        }
        targetVelocity = targetVelocity.normalized * SPEED;

        flockTimer = FLOCK_PERIOD;
    }
Ejemplo n.º 6
0
    override public void Execute()
    {
        targetVelocity = StaticMovementAlgorithms.KinematicArrive(selfBody, nextNode.transform.position, ELECTRIC_SPEED, ARRIVE_RADIUS);

        /*
         * if (Controls.getDirection() != Vector3.zero)
         * {
         *  Debug.Log("Controller decided");
         *  Debug.DrawLine(nextNode.transform.position, nextNode.getNextNavPoint(Controls.getDirection()).transform.position);
         * }
         * else
         * {
         *  Debug.Log("Velocity Decided");
         *  Debug.DrawLine(nextNode.transform.position, nextNode.getNextNavPoint(selfBody.velocity).transform.position);
         * }
         */
        if (targetVelocity == Vector3.zero)
        {
            if (nextNode.isEndpoint)
            {
                Owner.ActionFsm.ChangeState(new IdleState(Owner, Owner.ActionFsm));
            }
            else
            {
                ElectricNavpoint nextNodeCandidate;

                Vector3 input_direction = Controls.getDirection();
                if (input_direction != Vector3.zero && Owner.stamina > 0.0f)
                {
                    nextNodeCandidate = nextNode.getNextNavPoint(input_direction, previousNode);
                    if (nextNodeCandidate == previousNode)
                    {
                        nextNodeCandidate = nextNode.getNextNavPoint(selfBody.velocity, previousNode);
                    }
                }
                else
                {
                    nextNodeCandidate = nextNode.getNextNavPoint(selfBody.velocity, previousNode);
                }

                previousNode = nextNode;
                nextNode     = nextNodeCandidate;

                //Now we trigger any associated devices
                previousNode.Trigger();
            }
        }
        Owner.UseStamina(STAMINA_COST_PER_SECOND * Time.deltaTime);
    }
Ejemplo n.º 7
0
    override public void Execute()
    {
        Vector3 arriveVelocity    = StaticMovementAlgorithms.KinematicArrive(selfBody, target.transform.position, SPEED, ARRIVE_RADIUS);
        Vector3 avoidanceVelocity =
            CollisionPrediction.AvoidCollisions(Owner.gameObject, AVOID_DETECTION_RADIUS, AVOID_MARGIN, SPEED, LayerMask.GetMask("Obstacle"), selfColliders);

        if (avoidanceVelocity != Vector3.zero)
        {
            targetVelocity = 0.6f * arriveVelocity + 0.4f * avoidanceVelocity;
        }
        else
        {
            targetVelocity = arriveVelocity;
        }
        targetVelocity.y = 0.0f;
        targetVelocity   = targetVelocity.normalized * SPEED;
    }
Ejemplo n.º 8
0
    override public void Execute()
    {
        targetVelocity = StaticMovementAlgorithms.KinematicArrive(selfBody, nextNode.transform.position, ELECTRIC_SPEED, ARRIVE_RADIUS);

        /*
         * if (Controls.getDirection() != Vector3.zero)
         * {
         *  Debug.Log("Controller decided");
         *  Debug.DrawLine(nextNode.transform.position, nextNode.getNextNavPoint(Controls.getDirection()).transform.position);
         * }
         * else
         * {
         *  Debug.Log("Velocity Decided");
         *  Debug.DrawLine(nextNode.transform.position, nextNode.getNextNavPoint(selfBody.velocity).transform.position);
         * }
         */

        if (targetVelocity == Vector3.zero)
        {
            if (nextNode.isEndpoint)
            {
                Owner.ActionFsm.ChangeState(new IdleState(Owner, Owner.ActionFsm));
            }
            else
            {
                ElectricNavpoint nextNodeCandidate;

                Vector3 input_direction = Controls.getDirection();
                if (input_direction != Vector3.zero)
                {
                    nextNodeCandidate = nextNode.getNextNavPoint(input_direction);
                    if (nextNodeCandidate == previousNode)
                    {
                        nextNodeCandidate = nextNode.getNextNavPoint(selfBody.velocity);
                    }
                }
                else
                {
                    nextNodeCandidate = nextNode.getNextNavPoint(selfBody.velocity);
                }

                previousNode = nextNode;
                nextNode     = nextNodeCandidate;
            }
        }
    }
Ejemplo n.º 9
0
    override public void Execute()
    {
        //Initialization of basic parameters
        Rigidbody body = Owner.GetComponent <Rigidbody>();

        directionChangeTimer -= Time.deltaTime;
        if (directionChangeTimer <= 0.0f)
        {
            wanderVelocity       = StaticMovementAlgorithms.KinematicWander(body, SPEED, movementVariance, Owner.transform.forward);
            directionChangeTimer = Random.Range(MIN_TIME, MAX_TIME);
        }

        //Calculates the velocity for not colliding into things
        Vector3 avoidanceVelocity = CollisionPrediction.AvoidCollisions(Owner.gameObject, AVOID_DETECTION_RADIUS, AVOID_MARGIN, SPEED, LayerMask.GetMask("Obstacle"));

        //StaticMovementAlgorithms.KinematicAvoidObstacles(body, LayerMask.GetMask("Obstacle"), 5.0f, 1.0f, SPEED);
        avoidanceVelocity.y = 0;
        //Vector3 targetVelocity = new Vector3();
        if (avoidanceVelocity != Vector3.zero)
        {
            targetVelocity = 0.6f * wanderVelocity
                             + 0.4f * avoidanceVelocity;
            targetVelocity = targetVelocity.normalized * SPEED;
            wanderVelocity = targetVelocity;//avoidanceVelocity;
        }
        else
        {
            targetVelocity = wanderVelocity;
        }

        targetVelocity.y = 0.0f;

        targetVelocity = targetVelocity.normalized * SPEED;

        //Debug.Log("wander " + wanderVelocity);
        //Debug.Log("avoid " + avoidanceVelocity);
    }
    public static Vector3 AvoidCollisions(GameObject self,
                                          float detectRadius,
                                          float avoidMargin,
                                          float speed,
                                          int mask = Physics.DefaultRaycastLayers,
                                          Collider[] selfColliders = null)
    {
        Vector3   results  = new Vector3();
        Rigidbody selfBody = self.GetComponent <Rigidbody>();

        // Cannot operate if we have no sense of self movement
        if (selfBody == null)
        {
            return(results);
        }

        if (selfColliders == null)
        {
            selfColliders = self.GetComponentsInChildren <Collider>();
        }

        Collider[] nearbyColliders = Physics.OverlapSphere(selfBody.position, detectRadius, mask);
        foreach (Collider col in nearbyColliders)
        {
            // Ignore colliders that belong to self
            bool skipSelf = false;
            foreach (Collider c in selfColliders)
            {
                if (col == c)
                {
                    skipSelf = true;
                    break;
                }
            }
            if (skipSelf)
            {
                continue;
            }

            // Ignore terrain (probably unneeded)
            if (col.gameObject.tag.Equals("Terrain"))
            {
                continue;
            }

            // Moving obstacles
            if (col.gameObject.GetComponent <Rigidbody>() != null)
            {
                // self = A
                // other = B
                Rigidbody other       = col.gameObject.GetComponent <Rigidbody>();
                Vector3   dv          = other.velocity - selfBody.velocity;
                Vector3   dp          = other.position - selfBody.position;
                float     closestTime = -(Vector3.Dot(dv, dp) / dv.sqrMagnitude);

                Vector3 closestA = selfBody.position + selfBody.velocity * closestTime;
                Vector3 closestB = other.position + other.velocity * closestTime;

                Vector3 distance = closestB - closestA;
                if (distance.sqrMagnitude < avoidMargin * avoidMargin)
                {
                    Debug.Log("Avoiding " + other.gameObject.name);
                    results += 0.5f * (avoidMargin / distance.magnitude) * StaticMovementAlgorithms.KinematicFlee(selfBody, closestB, speed);
                }
                continue;
            }
        }

        // Not really worried about static obstacles if we're not moving
        if (selfBody.velocity.sqrMagnitude > 0.0001)
        {
            RaycastHit[] hitInfos = selfBody.SweepTestAll(selfBody.velocity.normalized, detectRadius);
            if (hitInfos.Length > 0)
            {
                foreach (RaycastHit hitInfo in hitInfos)
                {
                    if ((mask & (1 << hitInfo.collider.gameObject.layer)) > 0)
                    {
                        Vector3 distance = hitInfo.point - selfBody.position;
                        if (distance.sqrMagnitude < avoidMargin * avoidMargin)
                        {
                            Debug.Log("Avoiding " + hitInfo.collider.gameObject.name);
                            Vector3 dest = hitInfo.point + hitInfo.normal * 2.0f * avoidMargin;
                            results += (avoidMargin / distance.magnitude) * StaticMovementAlgorithms.KinematicSeek(selfBody, dest, 1.0f);
                        }
                        break;
                    }
                }
            }
        }

        return(results.normalized * speed);
    }
Ejemplo n.º 11
0
    override public void Execute()
    {
        Vector3 targetDest;

        //if(Path.Count - PathIndex >= 3)
        //{
        //    targetDest = 0.7f * Path[PathIndex].transform.position
        //        + 0.2f * Path[PathIndex + 1].transform.position
        //        + 0.1f * Path[PathIndex + 2].transform.position;
        //}
        //else if (Path.Count - PathIndex >= 2)
        //{
        //    targetDest = 0.8f * Path[PathIndex].transform.position
        //        + 0.2f * Path[PathIndex + 1].transform.position;
        //}
        //else if (Path.Count - PathIndex >= 1)
        //{
        //    targetDest = Path[PathIndex].transform.position;
        //}
        //else
        //{
        //    targetDest = currentTarget.transform.position;
        //}
        targetDest = currentTarget.transform.position;
        Debug.DrawLine(targetDest, targetDest + Vector3.up * 1.0f, Color.red);

        Vector3 arriveVelocity = StaticMovementAlgorithms.KinematicArrive(selfBody, targetDest, 1.0f, ARRIVE_RADIUS);
        //Vector3 avoidanceVelocity =
        //    CollisionPrediction.AvoidCollisionsHelper(Owner.gameObject,
        //    AVOID_DETECTION_RADIUS,
        //    1.5f * Owner.BodyBounds.extents.magnitude,
        //    LayerMask.GetMask("Obstacle"),
        //    selfColliders);
        Vector3 avoidanceVelocity = CollisionPrediction.AvoidCollisions(Owner.gameObject, AVOID_DETECTION_RADIUS, AVOID_MARGIN, SPEED, LayerMask.GetMask("Obstacle"), selfColliders);

        avoidanceVelocity.y = 0.0f;

        if (avoidanceVelocity != Vector3.zero)
        {
            targetVelocity = 0.6f * arriveVelocity + 0.4f * avoidanceVelocity;
        }
        else
        {
            targetVelocity = arriveVelocity;
        }
        //targetVelocity.y = 0.0f;
        targetVelocity = targetVelocity.normalized * Owner.speed;
        //targetVelocity.y = 0.0f;
        //float avoidanceSpeed = avoidanceVelocity.magnitude;
        //avoidanceVelocity.y = 0.0f;
        //avoidanceVelocity = avoidanceVelocity.normalized * avoidanceSpeed;
        //targetVelocity = arriveVelocity + avoidanceVelocity;
        //if (targetVelocity.sqrMagnitude > 1.0f)
        //{
        //    targetVelocity = targetVelocity.normalized;
        //}
        //targetVelocity *= SPEED;
        //Debug.Log("chosen target velocity: " + targetVelocity);

        if (Vector3.Distance(Owner.transform.position, currentTarget.transform.position) < ARRIVE_RADIUS)
        {
            //invariant that the path has a unique set of targets
            PathIndex++;
            if (PathIndex < Path.Count)
            {
                currentTarget = Path[PathIndex];
            }
        }
    }
    override public void Execute()
    {
        Vector3 selfPos   = Owner.transform.position;
        Vector3 targetPos = target.transform.position;

        if (Vector3.Distance(targetPos, selfPos) < ARRIVE_RADIUS)
        {
            targetVelocity = Vector3.zero;
            return;
        }

        Vector3 arrivePoint;

        if (path == null)
        {
            if (Mathf.Abs(selfPos.y - targetPos.y) < 0.1f &&
                !Physics.Linecast(selfPos, targetPos, LayerMask.GetMask("Obstacle")))
            {
                // If we're on the same y-plane, and the target is visible
                // Just target the enemy
                arrivePoint        = targetPos;
                targetLastPosition = targetPos;
            }
            else
            {
                // Otherwise, find a path.
                GeneratePathToTarget();

                arrivePoint = pathPointTarget;
            }
        }
        else
        {
            // If the target has moved significantly, create a new path.
            if (Vector3.Distance(targetLastPosition, targetPos) > REPATH_THRESHOLD)
            {
                if (repathWait <= 0)
                {
                    GeneratePathToTarget();
                    repathWait = Random.Range(0, REPATH_WAIT_MAX);
                }
                else
                {
                    repathWait -= 1;
                }
            }

            // Otherwise, keep following our current path.
            else
            {
                // If we've reached our path way point, get the next if it exists
                if (Vector3.Distance(selfPos, pathPointTarget) < ARRIVE_RADIUS)
                {
                    pathIndex++;
                    if (pathIndex < path.Count)
                    {
                        pathPointTarget = path[pathIndex];
                    }
                    else
                    {
                        path            = null;
                        pathPointTarget = targetPos;
                    }
                }
            }
            arrivePoint = pathPointTarget;
        }
        Debug.DrawLine(arrivePoint, arrivePoint + Vector3.up * 1.0f, Color.red);

        Vector3 arriveVelocity    = StaticMovementAlgorithms.KinematicArrive(selfBody, arrivePoint, 1.0f, ARRIVE_RADIUS);
        Vector3 avoidanceVelocity = CollisionPrediction.AvoidCollisionsHelper(Owner.gameObject, AVOID_DETECTION_RADIUS, AVOID_MARGIN, LayerMask.GetMask("Obstacle"), selfColliders);

        avoidanceVelocity.y = 0.0f;

        if (avoidanceVelocity != Vector3.zero)
        {
            targetVelocity = targetVelocity + avoidanceVelocity * Owner.speed;
            if (targetVelocity.sqrMagnitude > Owner.speed * Owner.speed)
            {
                targetVelocity = targetVelocity.normalized * Owner.speed;
            }
        }
        else
        {
            targetVelocity = Vector3.Lerp(targetVelocity, arriveVelocity * Owner.speed, 0.2f);
        }
        if (Owner.gameObject == UnityEditor.Selection.activeGameObject)
        {
            Debug.Log(Owner.name + " has target vel " + targetVelocity + " arrive vel: " + arriveVelocity + " avoid vel : " + avoidanceVelocity);
        }
    }
Ejemplo n.º 13
0
    public static Vector3 AvoidCollisionsHelper(GameObject self,
                                                float detectRadius,
                                                float avoidMargin,
                                                int mask = Physics.DefaultRaycastLayers,
                                                Collider[] selfColliders = null)
    {
        Vector3   results  = new Vector3();
        Rigidbody selfBody = self.GetComponent <Rigidbody>();

        // Cannot operate if we have no sense of self movement
        if (selfBody == null)
        {
            return(results);
        }
        Vector3 currentDirection = selfBody.velocity.normalized;

        if (selfColliders == null)
        {
            selfColliders = self.GetComponentsInChildren <Collider>();
        }

        Collider[] nearbyColliders = Physics.OverlapSphere(selfBody.position, detectRadius, mask);
        foreach (Collider col in nearbyColliders)
        {
            // Ignore colliders that belong to self
            bool skipSelf = false;
            foreach (Collider c in selfColliders)
            {
                if (col == c)
                {
                    skipSelf = true;
                    break;
                }
            }
            if (skipSelf)
            {
                continue;
            }

            // Moving obstacles
            if (col.gameObject.GetComponent <Rigidbody>() != null)
            {
                // self = A
                // other = B
                Rigidbody other = col.gameObject.GetComponent <Rigidbody>();
                if (other.velocity.sqrMagnitude < 0.01f)
                {
                    continue;
                }

                Vector3 dv          = other.velocity - selfBody.velocity;
                Vector3 dp          = other.position - selfBody.position;
                float   closestTime = -(Vector3.Dot(dv, dp) / dv.sqrMagnitude);

                Vector3 closestA = selfBody.position + selfBody.velocity * closestTime;
                Vector3 closestB = other.position + other.velocity * closestTime;

                Vector3 distance = closestB - closestA;
                if (distance.sqrMagnitude < avoidMargin * avoidMargin)
                {
                    //Debug.Log("Avoiding " + other.gameObject.name);
                    Vector3 deltaV = StaticMovementAlgorithms.KinematicFlee(selfBody, closestB, 1.0f) - currentDirection;
                    deltaV.Normalize();
                    float proportionalToDist = (1.0f - distance.magnitude / avoidMargin);
                    deltaV *= proportionalToDist;

                    // Scale by distance
                    results += deltaV;
                }
                continue;
            }
        }

        // Not really worried about static obstacles if we're not moving
        if (selfBody.velocity.sqrMagnitude > 0.0001)
        {
            RaycastHit[] hitInfos = selfBody.SweepTestAll(selfBody.velocity.normalized, detectRadius);
            if (hitInfos.Length > 0)
            {
                foreach (RaycastHit hitInfo in hitInfos)
                {
                    if ((mask & (1 << hitInfo.collider.gameObject.layer)) > 0)
                    {
                        Vector3 displacement = hitInfo.point - selfBody.position;
                        if (displacement.sqrMagnitude < detectRadius * detectRadius) // Within Avoid Margin
                        {
                            //Debug.Log("Avoiding " + hitInfo.collider.gameObject.name);
                            //Vector3 avoidPoint = hitInfo.point + hitInfo.normal * avoidMargin;
                            //Vector3 targetV = StaticMovementAlgorithms.KinematicSeek(selfBody, avoidPoint, 1.0f);
                            //Vector3 deltaV = (targetV - currentDirection);
                            //if(deltaV.magnitude > 1.0f)
                            //{
                            //    deltaV.Normalize();
                            //}
                            Vector3 up             = Vector3.Cross(currentDirection, hitInfo.normal);
                            Vector3 avoidDirection = Vector3.Cross(up, currentDirection).normalized;
                            avoidDirection.y = 0.0f;
                            Vector3 deltaV = avoidDirection.normalized;

                            float proportionalToDist = (1.0f - displacement.magnitude / (detectRadius));
                            deltaV *= proportionalToDist;

                            results += deltaV;
                        }
                        break;
                    }
                }
            }
        }

        return(results);
    }