コード例 #1
0
    // -----------------------------------------------------------------------------------------------------//

    // Update is called once per frame
    void Update()
    {
        /*
         * STATE, holdFire, HardTarget, and SoftTarget are all already set for us
         *
         * This means just decide what to do based on the state and targets given
         *
         * */

        // SET UP DEFAULT VALUES FOR STATE-BASED VARIABLES
        Vector2 moveDirection = new Vector2(0, 0); // what direction to move in (normalized later)
        bool    shouldMove    = false;             // whether or not we should move
        bool    shouldAttack  = false;             // whether or not we should attack
        bool    shouldSprint  = false;             // whether or not to sprint
        bool    shouldReload  = false;             // whether or not we should reload (if possible)
        bool    shouldLoot    = false;             // whether or not to pick up items (if possible)

        float targetDistance = 0f;

        if (hardTarget != null)
        {
            targetDistance = Vector2.Distance(hardTarget.transform.position, transform.position); // value of distance to hard target
        }


        // determine what to do based on what state we are in
        // STATES DO NOT CHANGE HERE!
        switch (BehState)
        {
        case BehaviorState.Fighting:
            if (holdFire == false)
            {
                shouldAttack = true;
            }

            // hardTarget = enemies?? TODO: will this be somewhere else?
            if (targetDistance < minSafeDist)
            {
                shouldMove    = true;
                moveDirection = GAMESTATE.findFleeDirection(gameObject);
            }

            shouldReload = true;
            break;

        case BehaviorState.Fleeing:
            shouldMove    = true;
            shouldSprint  = true;
            moveDirection = GAMESTATE.findFleeDirection(gameObject);     // TODO set move target

            break;

        case BehaviorState.Looting:
            shouldMove   = true;
            shouldReload = true;
            shouldLoot   = true;
            // hard target will hold the closest item to go get, so move towards it...
            // TODO: hard pathfinding!
            moveDirection = hardTarget.transform.position - transform.position;

            break;

        case BehaviorState.Following:
            shouldReload = true;
            // TODO: dont move perfectly towards the player, Pathfinding

            if (targetDistance > minSafeDist)
            {
                shouldMove    = true;
                moveDirection = hardTarget.transform.position - transform.position;
            }
            break;

        default:
            // just dont change anything, leave values the preset above
            break;
        }

        // PROCESS ACTIONS BASED ON ABOVE VARIABLES


        // if the character was busy doing something, can't perform the below actions
        if (character.busyState <= Time.time)
        {
            // the following get set below
            Vector2 newPos       = transform.position;
            float   movespeed    = 0.0f;
            bool    enableAttack = true;

            // reload weapons
            if (shouldReload && character.hasLowAmmo()) // TODO what if no ammo?
            {
                character.reload();
                character.State = Character_BS.AnimState.Reload;
            }
            // pick up items
            else if (shouldLoot && (targetDistance < GAMESTATE.minLootDist)) // TODO: should we pickup items?
            {
                character.State     = Character_BS.AnimState.Loot;
                character.busyState = Time.time + character.lootTime; // technically this should be done in character class

                // TODO: Now we need to go try for another item
            }
            // should we be moving?
            else if (shouldMove)
            {
                // Sprint or walk
                if (character.canSprint == true && (shouldSprint)) // are we going to sprint?
                {
                    character.State = Character_BS.AnimState.Run;
                    movespeed       = character.runSpeed;
                    character.SetFacing(moveDirection);
                    enableAttack = false;
                }
                else
                {
                    character.State = Character_BS.AnimState.Walk;
                    movespeed       = character.walkSpeed;
                    character.SetFacing(moveDirection); // look in the direction we are moving unless interrupted by shooting later
                }
                // actually set new position
                Vector3 movDir = moveDirection.normalized;
                newPos = transform.position + (movDir * movespeed * Time.deltaTime);

                // actually move to the new location
                character.rigidbod.MovePosition(newPos);
            }
            // be idle
            else
            {
                character.State = Character_BS.AnimState.Idle;
                movespeed       = 0.0f;
                if (hardTarget != null)
                {
                    character.SetFacing(hardTarget);
                }
            }

            // HANDLE SHOOTING/ATTACKING
            if (enableAttack && shouldAttack && (hardTarget != null))
            {
                bool is_moving = false;
                if (movespeed > 0.0f)
                {
                    is_moving = true;
                }

                // TODO: Handle when hard target dies, or is behind a barrier (and a new target should be found)

                // aim at your target
                character.SetFacing(hardTarget);

                // attack with LEFT weapon
                if (character.meleeWeapon != null)
                {
                    if (character.meleeWeapon.canAttack(is_moving) == true)
                    {
                        Vector2 direction = hardTarget.transform.position - character.meleeWeapon.shotspawn.position;
                        GAMESTATE.MakeAttack(gameObject, direction, character.meleeWeapon);
                    }
                }
                // attack with RIGHT weapon
                if (character.missileWeapon != null)
                {
                    if (character.missileWeapon.canAttack(is_moving) == true)
                    {
                        Vector2 direction = hardTarget.transform.position - character.missileWeapon.shotspawn.position;
                        GAMESTATE.MakeAttack(gameObject, direction, character.missileWeapon);
                    }
                }
            }

            // ---- END MOVING ---- //
        }
        // if busy, like mid reload, we just face the target
        else
        {
            if (hardTarget != null)
            {
                character.SetFacing(hardTarget);
            }
        }
    }
コード例 #2
0
ファイル: ZombieBS.cs プロジェクト: emcdunna/zombie_game
    // Update is called once per frame
    void Update()
    {
        Vector2 newPos     = transform.position; // default
        bool    is_moving  = false;
        bool    canSeeTarg = false;

        // NOW: lose % of intensity every X seconds
        float TimeMult = 1f;

        // The ratio of delta time into X seconds
        if (Time.deltaTime < forgetNoiseRate)
        {
            TimeMult = (forgetNoiseRate - Time.deltaTime) / forgetNoiseRate;
        }

        // drop intensity by a certain % each frame, drops quickly, stays nonzero for a long time
        if (targetIntensity > 0f)
        {
            targetIntensity = targetIntensity * TimeMult;
        }
        // lose intensity if we reach destination
        if (Vector2.Distance(transform.position, softTarget) < minForgetDistance)
        {
            targetIntensity = 0;
        }

        // only do logic every delayTime seconds
        if (Time.time > nextSyncTime)
        {
            nextSyncTime = Time.time + delayTime;

            // control which target mode we are in
            if (hardTarget != null)
            {
                targetmode = TargetMode.HardTarget;
                canSeeTarg = GAMESTATE.canSee(gameObject, hardTarget);

                // if the hard target gets too far away, switch to soft target
                float dist = Vector2.Distance(hardTarget.transform.position, transform.position);

                // if we cant see the hard target, set soft target and create a path
                if (canSeeTarg == false)
                {
                    targetmode            = TargetMode.FollowPath;
                    softTarget            = hardTarget.transform.position;
                    pathDestinationTarget = softTarget;
                    hardTarget            = null;
                    if (path == null)
                    {
                        //print("Find path1 at " + Time.time);
                        path = GAMESTATE.findPath(transform.position, pathDestinationTarget);
                        if (null == path)
                        {
                            targetmode = TargetMode.SoftTarget;
                        }
                        else
                        {
                            pathTarget            = path[0];
                            pathDestinationTarget = softTarget;
                        }
                    }
                }
                // if hard target moves out of range, go back to soft
                else if (dist > hardDetectRange)
                {
                    targetmode      = TargetMode.SoftTarget;
                    softTarget      = hardTarget.transform.position; // set the soft target to the old pos
                    targetIntensity = maxIntensity;
                    hardTarget      = null;
                    path            = null;
                }
            }
            // is the intensity great enough to follow? if so, set soft target
            else if (targetIntensity > minIntensity)
            {
                // there already is a soft target
                canSeeTarg = GAMESTATE.canSeeIgnoreCharacters(transform.position, softTarget);

                if (canSeeTarg == false)
                {
                    // follow path if we cant see where the sound came from
                    // if we dont yet have a path, get one, or if this is a new soft target, generate a new path
                    targetmode = TargetMode.FollowPath;

                    if (path == null || (pathDestinationTarget != softTarget))
                    {
                        path = GAMESTATE.findPath(transform.position, pathDestinationTarget);
                        // there is no path
                        if (null == path)
                        {
                            targetmode = TargetMode.SoftTarget;
                        }
                        else
                        {
                            pathTarget            = path[0];
                            pathDestinationTarget = softTarget;
                        }
                    }
                }
                else
                {
                    // otherwise just go towards it
                    targetmode = TargetMode.SoftTarget;
                    path       = null;
                }
            }
            else
            {
                targetmode      = TargetMode.NoTarget;
                softTarget      = transform.position;
                targetIntensity = 0;
                path            = null;
            }
            //print(Vector3.Magnitude(character.rigidbod.velocity) + " " + Time.time);
        }


        // handle behavior based off of the target mode
        switch (targetmode)
        {
        case (TargetMode.NoTarget):
        {
            character.State = Character_BS.AnimState.Idle;
            break;
        }

        case (TargetMode.SoftTarget):
        {
            is_moving = true;
            character.SetFacing(softTarget);         // face the soft target VECTOR
            character.State = Character_BS.AnimState.Walk;
            Vector2 dir = new Vector2(softTarget.x, softTarget.y);
            dir -= new Vector2(transform.position.x, transform.position.y);
            dir.Normalize();
            character.rigidbod.velocity = dir * character.walkSpeed;


            break;
        }

        case (TargetMode.HardTarget):
        {
            is_moving = true;
            character.SetFacing(hardTarget);         // face the target game object
            character.State = Character_BS.AnimState.Run;
            Vector2 dir  = hardTarget.transform.position - transform.position;
            float   dist = dir.magnitude;
            dir.Normalize();
            character.rigidbod.velocity = dir * character.runSpeed;

            if (dist < meleeDist)
            {
                // makes melee attack
                if (character.meleeWeapon.canAttack(is_moving) == true)
                {
                    GAMESTATE.MakeAttack(gameObject, dir, character.meleeWeapon);
                }
            }

            break;
        }

        case (TargetMode.FollowPath):
        {
            // If we can see the next pathTarget, also just choose it (instead of walking too far the wrong way)
            float dist = Vector2.Distance(transform.position, pathTarget.transform.position);
            int   i    = path.IndexOf(pathTarget);
            is_moving = true;
            if (i + 1 < path.Count)
            {
                bool skipNode = GAMESTATE.canSeeIgnoreCharacters(transform.position, path[i + 1].transform.position);
                if (dist <= minPathNodeDist || skipNode == true)
                {
                    // get the next path target
                    pathTarget = path[i + 1];
                    //print("going to next node " + Time.time);
                }
            }
            // if too close to last path
            else if (dist <= minPathNodeDist)
            {
                targetIntensity = 0;
                is_moving       = false;
            }

            if (is_moving == true)
            {
                Vector2 pathvector = pathTarget.transform.position;
                character.SetFacing(pathvector);         // face the soft target VECTOR
                character.State = Character_BS.AnimState.Walk;
                Vector2 dir = pathvector;
                dir -= new Vector2(transform.position.x, transform.position.y);
                dir.Normalize();
                character.rigidbod.velocity = Vector2.Lerp(character.rigidbod.velocity, dir * character.walkSpeed, 0.5f);
            }

            break;
        }

        default:
        {
            break;
        }
        }
    }
コード例 #3
0
    // Update is called once per frame
    void Update()
    {
        // always face target
        //

        // enable user to play/pause game with escape
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            GAMESTATE.togglePaused();
        }

        if ((character.freezeChar == false) && (character.busyState <= Time.time))
        {
            Vector2 newPos = transform.position;
            // ---- MOVING ---- //

            // DIRECTION //
            bool move_forward = Input.GetKey(KeyCode.W);
            bool move_right   = Input.GetKey(KeyCode.D);
            bool move_left    = Input.GetKey(KeyCode.A);
            bool move_back    = Input.GetKey(KeyCode.S);


            float movespeed    = 0.0f;
            bool  enableAttack = true;
            bool  is_moving    = false;
            bool  RightAttack  = false;
            bool  LeftAttack   = false;


            // reload weapons
            if (Input.GetKeyDown(KeyCode.R))
            {
                character.reload();
                character.State = Character_BS.AnimState.Reload;
            }
            // pick up items
            else if (Input.GetKey(KeyCode.E))
            {
                character.State     = Character_BS.AnimState.Loot;
                character.busyState = Time.time + character.lootTime; // TODO: technically this should be done in character class
            }
            else if (move_forward || move_left || move_right || move_back)
            {
                is_moving = true;
                if (character.canSprint == true && Input.GetKey(KeyCode.LeftShift))
                {
                    character.State = Character_BS.AnimState.Run;
                    movespeed       = character.runSpeed;
                    enableAttack    = false;
                }
                else
                {
                    movespeed       = character.walkSpeed;
                    character.State = Character_BS.AnimState.Walk;
                }
            }
            else
            {
                // be idle
                character.State = Character_BS.AnimState.Idle;
                movespeed       = 0.0f;
            }

            // attack with melee weapon
            if (character.meleeWeapon != null)
            {
                if (character.meleeWeapon.isFullAuto == true)
                {
                    if (enableAttack && Input.GetKey(KeyCode.Mouse1))
                    {
                        LeftAttack = true;
                    }
                }
                else
                {
                    if (enableAttack && Input.GetKeyDown(KeyCode.Mouse1))
                    {
                        LeftAttack = true;
                    }
                }

                if (LeftAttack == true)
                {
                    if (character.meleeWeapon.canAttack(is_moving) == true)
                    {
                        Vector2 direction = target.transform.position - character.meleeWeapon.shotspawn.position;
                        GAMESTATE.MakeAttack(gameObject, direction, character.meleeWeapon);
                    }
                }
            }


            // attack with missile weapon
            if (character.missileWeapon != null)
            {
                if (character.missileWeapon.isFullAuto == true)
                {
                    if (enableAttack && Input.GetKey(KeyCode.Mouse0))
                    {
                        RightAttack = true;
                    }
                }
                else
                {
                    if (enableAttack && Input.GetKeyDown(KeyCode.Mouse0))
                    {
                        RightAttack = true;
                    }
                }

                if (RightAttack == true)
                {
                    if (character.missileWeapon.canAttack(is_moving) == true)
                    {
                        Vector2 direction = target.transform.position - character.missileWeapon.shotspawn.position;
                        GAMESTATE.MakeAttack(gameObject, direction, character.missileWeapon);
                    }
                }
            }

            //TODO: interrupt other weapon firing!
            if (Input.GetKeyDown(KeyCode.G))
            {
                if (character.tertiaryWeapon != null)
                {
                    if (is_moving == false)
                    {
                        Vector2 direction = target.transform.position - transform.position;
                        GAMESTATE.MakeTertiaryAttack(gameObject, direction, character.tertiaryWeapon);
                    }
                }
            }


            // ACTUALLY MOVE AND SCALE VALUE
            Vector3 forwardDirection = target.transform.position - transform.position;
            forwardDirection.Normalize();
            Vector3 finalDirection = forwardDirection;

            switch (moveControls)
            {
            case MoveControls.MouseRotate:
                if (move_forward && move_right)
                {
                    finalDirection = Quaternion.Euler(0, 0, -45) * forwardDirection;
                }
                else if (move_forward && move_left)
                {
                    finalDirection = Quaternion.Euler(0, 0, 45) * forwardDirection;
                }
                else if (move_back && move_right)
                {
                    movespeed      = character.walkSpeed;
                    movespeed      = movespeed * character.strafeRate;
                    finalDirection = Quaternion.Euler(0, 0, -135) * forwardDirection;
                }
                else if (move_back && move_left)
                {
                    movespeed      = character.walkSpeed;
                    movespeed      = movespeed * character.strafeRate;
                    finalDirection = Quaternion.Euler(0, 0, 135) * forwardDirection;
                }
                else if (move_back)
                {
                    movespeed      = character.walkSpeed;
                    finalDirection = Quaternion.Euler(0, 0, 180) * forwardDirection;
                    movespeed      = movespeed * character.strafeRate;
                }
                else if (move_left)
                {
                    movespeed      = character.walkSpeed;
                    finalDirection = Quaternion.Euler(0, 0, 90) * forwardDirection;
                    movespeed      = movespeed * character.strafeRate;
                }
                else if (move_right)
                {
                    movespeed      = character.walkSpeed;
                    finalDirection = Quaternion.Euler(0, 0, -90) * forwardDirection;
                    movespeed      = movespeed * character.strafeRate;
                }
                break;

            case MoveControls.Fixed8Ways:
                character.SetFacing(target);

                if (move_forward && move_right)
                {
                    finalDirection = new Vector3(0.707f, 0.707f, 0);
                }
                else if (move_forward && move_left)
                {
                    finalDirection = new Vector3(-0.707f, 0.707f, 0);
                }
                else if (move_back && move_right)
                {
                    finalDirection = new Vector3(0.707f, -0.707f, 0);
                }
                else if (move_back && move_left)
                {
                    finalDirection = new Vector3(-0.707f, -0.707f, 0);
                }
                else if (move_back)
                {
                    finalDirection = new Vector3(0, -1, 0);
                }
                else if (move_left)
                {
                    finalDirection = new Vector3(-1, 0, 0);
                }
                else if (move_right)
                {
                    finalDirection = new Vector3(1, 0, 0);
                }
                else
                {
                    finalDirection = new Vector3(0, 1, 0);
                }

                break;

            default:
                break;
            }


            if (is_moving)
            {
                //print("Speed: " + Vector3.Magnitude(finalDirection * movespeed * Time.deltaTime));
                Vector3 scaledDir = (finalDirection * movespeed * Time.deltaTime);
                newPos = transform.position + scaledDir;
                character.rigidbod.AddForce(scaledDir * 5000);
            }
            // ---- END MOVING ---- //
        }
    }