예제 #1
0
    //===================================
    //===================================
    //		PERIODIC UPDATE
    //===================================
    //===================================

    void Update()
    {
        float fadeTime;
        float guiFlybySpeed = 0f;

        //pumaAnimator.SetLayerWeight(1, 1f);

        if (pumaObj == null || buck == null || doe == null || fawn == null)
        {
            return;
        }

        CalculateFrameRate();

        inputControls.ProcessControls(gameState);

        //=================================
        // Get distances from puma to deer
        //=================================

        float pumaDeerDistance1 = Vector3.Distance(pumaObj.transform.position, buck.gameObj.transform.position);
        float pumaDeerDistance2 = Vector3.Distance(pumaObj.transform.position, doe.gameObj.transform.position);
        float pumaDeerDistance3 = Vector3.Distance(pumaObj.transform.position, fawn.gameObj.transform.position);

        //=================================
        // Check for Skip Ahead
        //=================================

        if (goStraightToFeeding == true && gameState == "gameStateStalking")
        {
            SetGameState("gameStateChasing");
            pumaDeerDistance1 = 0;
        }


        //===========================
        // Update Game-State Logic
        //===========================

        switch (gameState)
        {
        //------------------------------
        // GUI States
        //
        // user interface states
        // main panel showing
        //------------------------------

        case "gameStateGui":
            // high in air, overlay panel showing
            guiFlybySpeed = 1f;
            SelectCameraPosition("cameraPosGui", -120f, 0f, null, null);
            break;

        case "gameStateLeavingGui":
            // zoom down into close up
            fadeTime      = 2.5f;
            guiFlybySpeed = 1f - (Time.time - stateStartTime) / fadeTime;
            if (stateInitFlag == false)
            {
                // init the level before zooming down
                PlaceDeerPositions();
                ResetAnimations();
                // stateInitFlag set to TRUE in the next function
            }
            SelectCameraPosition("cameraPosCloseup", 1000000f, fadeTime, "mainCurveSForward", "curveRotXLogarithmicSecondHalf");             // 1000000 signifies no change for cameraRotOffsetY
            if (Time.time >= stateStartTime + fadeTime)
            {
                guiFlybySpeed = 0f;
                SetGameState("gameStateEnteringGameplay1");
            }
            break;

        //------------------------------
        // Gameplay States
        //
        // entering, leaving,
        // stalking and chasing
        //------------------------------

        case "gameStateEnteringGameplay1":
            // brief pause on close up
            fadeTime = 0.1f;
            if (Time.time >= stateStartTime + fadeTime)
            {
                SetGameState("gameStateEnteringGameplay2");
            }
            break;

        case "gameStateEnteringGameplay2":
            // swing around to behind view
            fadeTime = 1.7f;
            SelectCameraPosition("cameraPosHigh", 0f, fadeTime, "mainCurveSBackward", "curveRotXLinearBackwardsSecondHalf");
            if (Time.time >= stateStartTime + fadeTime)
            {
                inputControls.ResetControls();
                SetGameState("gameStateStalking");
            }
            break;

        case "gameStateStalking":
            float lookingDistance = chaseTriggerDistance * 2f;
            float chasingDistance = chaseTriggerDistance;

            if (pumaDeerDistance1 < lookingDistance || pumaDeerDistance2 < lookingDistance || pumaDeerDistance3 < lookingDistance)
            {
                buckAnimator.SetBool("Looking", true);
                doeAnimator.SetBool("Looking", true);
                fawnAnimator.SetBool("Looking", true);
            }
            else
            {
                buckAnimator.SetBool("Looking", false);
                doeAnimator.SetBool("Looking", false);
                fawnAnimator.SetBool("Looking", false);
            }

            if (pumaDeerDistance1 < chasingDistance || pumaDeerDistance2 < chasingDistance || pumaDeerDistance3 < chasingDistance)
            {
                SetGameState("gameStateChasing");
                pumaAnimator.SetBool("Chasing", true);
                buckAnimator.SetBool("Running", true);
                doeAnimator.SetBool("Running", true);
                fawnAnimator.SetBool("Running", true);
                newChaseFlag      = true;
                pumaHeadingOffset = 0;                  // instantly disable diagonal movement (TEMP - really should swing camera around)
            }
            buck.forwardRate = 0f;
            buck.turnRate    = 0f;
            doe.forwardRate  = 0f;
            doe.turnRate     = 0f;
            fawn.forwardRate = 0f;
            fawn.turnRate    = 0f;
            break;

        case "gameStateChasing":
            // main chasing state - with a couple of quick initial camera moves handled via sub-states
            if (stateInitFlag == false)
            {
                gameSubState = "chasingSubState1";
                cameraController.SelectTargetPosition("cameraPosMedium", 1000000f, 0.75f, "mainCurveLinear", "curveRotXLinear");                  // 1000000 signifies no change for cameraRotOffsetY
                stateInitFlag = true;
            }
            else if (gameSubState == "chasingSubState1" && (Time.time >= stateStartTime + 0.75f))
            {
                gameSubState = "chasingSubState2";
                cameraController.SelectTargetPosition("cameraPosLow", 1000000f, 0.25f, "mainCurveLinear", "curveRotXLinear");                  // 1000000 signifies no change for cameraRotOffsetY
            }

            buck.forwardRate = buckDefaultForwardRate * Random.Range(0.9f, 1.1f);                       // ??? should these really be changed every frame ???
            buck.turnRate    = buckDefaultTurnRate * Random.Range(0.9f, 1.1f);
            doe.forwardRate  = doeDefaultForwardRate * Random.Range(0.9f, 1.1f);
            doe.turnRate     = doeDefaultTurnRate * Random.Range(0.9f, 1.1f);
            fawn.forwardRate = fawnDefaultForwardRate * Random.Range(0.9f, 1.1f);
            fawn.turnRate    = fawnDefaultTurnRate * Random.Range(0.9f, 1.1f);

            //buck.forwardRate = 0f;
            //doe.forwardRate = 0f;
            //fawn.forwardRate = 0f;
            //buck.turnRate = 0f;
            //doe.turnRate = 0f;
            //fawn.turnRate = 0f;

            if (pumaDeerDistance1 < 2.5f || pumaDeerDistance2 < 2.5f || pumaDeerDistance3 < 2.5f)
            {
                // DEER IS CAUGHT !!!

                if (pumaDeerDistance1 < 2.5f)
                {
                    buck.forwardRate = 0;
                    buck.turnRate    = 0f;
                    buckAnimator.SetBool("Die", true);
                    caughtDeer = buck;
                    scoringSystem.DeerCaught(selectedPuma, "Buck");
                }
                else if (pumaDeerDistance2 < 2.5f)
                {
                    doe.forwardRate = 0f;
                    doe.turnRate    = 0f;
                    doeAnimator.SetBool("Die", true);
                    caughtDeer = doe;
                    scoringSystem.DeerCaught(selectedPuma, "Doe");
                }
                else
                {
                    fawn.forwardRate = 0f;
                    fawn.turnRate    = 0f;
                    fawnAnimator.SetBool("Die", true);
                    caughtDeer = fawn;
                    scoringSystem.DeerCaught(selectedPuma, "Fawn");
                }

                // prepare caughtDeer obj for slide
                deerCaughtHeading = caughtDeer.heading;
                if (mainHeading >= deerCaughtHeading)
                {
                    deerCaughtHeadingLeft = (mainHeading - deerCaughtHeading <= 180) ? false : true;
                }
                else
                {
                    deerCaughtHeadingLeft = (deerCaughtHeading - mainHeading <= 180) ? true : false;
                }
                if (deerCaughtHeadingLeft == true)
                {
                    deerCaughtFinalHeading = mainHeading + 90;
                }
                else
                {
                    //deerCaughtFinalHeading = mainHeading - 90;
                    deerCaughtFinalHeading = mainHeading + 90;
                }
                if (deerCaughtFinalHeading < 0)
                {
                    deerCaughtFinalHeading += 360;
                }
                if (deerCaughtFinalHeading >= 360)
                {
                    deerCaughtFinalHeading -= 360;
                }
                deerCaughtmainHeading   = mainHeading;
                deerCaughtOffsetX       = caughtDeer.gameObj.transform.position.x - pumaX;
                deerCaughtOffsetZ       = caughtDeer.gameObj.transform.position.z - pumaZ;
                deerCaughtFinalOffsetX  = (Mathf.Sin(mainHeading * Mathf.PI / 180) * deerCaughtFinalOffsetFactor0);
                deerCaughtFinalOffsetZ  = (Mathf.Cos(mainHeading * Mathf.PI / 180) * deerCaughtFinalOffsetFactor0);
                deerCaughtFinalOffsetX += (Mathf.Sin((mainHeading - 90f) * Mathf.PI / 180) * deerCaughtFinalOffsetFactor90);
                deerCaughtFinalOffsetZ += (Mathf.Cos((mainHeading - 90f) * Mathf.PI / 180) * deerCaughtFinalOffsetFactor90);
                deerCaughtNextFrameTime = 0;

                if (Time.time - stateStartTime < 5f)
                {
                    deerCaughtEfficiency = 3;
                }
                else if (Time.time - stateStartTime < 10f)
                {
                    deerCaughtEfficiency = 2;
                }
                else if (Time.time - stateStartTime < 16f)
                {
                    deerCaughtEfficiency = 1;
                }
                else
                {
                    deerCaughtEfficiency = 0;
                }

                pumaAnimator.SetBool("DeerKill", true);
                SetGameState("gameStateFeeding1");
            }
            break;

        case "gameStateLeavingGameplay":
            // zoom up to high in the air
            fadeTime      = 2f;
            guiFlybySpeed = (Time.time - stateStartTime) / fadeTime;
            SelectCameraPosition("cameraPosGui", -120f, fadeTime, "mainCurveSBackward", "curveRotXLogarithmicBackwardsSecondHalf");
            if (Time.time >= stateStartTime + fadeTime)
            {
                guiFlybySpeed = 1f;
                ResetAnimations();
                SetGameState("gameStateGui");
            }
            break;

        //------------------------------
        // Feeding States
        //
        // puma has caught a deer
        // kills it and feeds on it
        //------------------------------

        case "gameStateFeeding1":
            // deer and puma slide to a stop as camera swings around to front
            fadeTime = 1.3f;
            SelectCameraPosition("cameraPosCloseup", -160f, fadeTime, "mainCurveSBackward", "curveRotXLogarithmic");

            if (Time.time < stateStartTime + fadeTime)
            {
                // puma and deer slide to a stop
                float percentDone      = 1f - ((Time.time - stateStartTime) / fadeTime);
                float pumaMoveDistance = 1f * Time.deltaTime * pumaChasingSpeed * percentDone * 1.1f;
                pumaX += (Mathf.Sin(deerCaughtmainHeading * Mathf.PI / 180) * pumaMoveDistance);
                pumaZ += (Mathf.Cos(deerCaughtmainHeading * Mathf.PI / 180) * pumaMoveDistance);
                // during slide move deer to correct position
                percentDone = ((Time.time - stateStartTime) / fadeTime);
                if ((deerCaughtFinalHeading > deerCaughtHeading) && (deerCaughtFinalHeading - deerCaughtHeading > 180))
                {
                    deerCaughtHeading += 360;
                }
                else if ((deerCaughtHeading > deerCaughtFinalHeading) && (deerCaughtHeading - deerCaughtFinalHeading > 180))
                {
                    deerCaughtFinalHeading += 360;
                }
                if (deerCaughtFinalHeading > deerCaughtHeading)
                {
                    caughtDeer.heading = deerCaughtHeading + ((deerCaughtFinalHeading - deerCaughtHeading) * percentDone);
                }
                else
                {
                    caughtDeer.heading = deerCaughtHeading - ((deerCaughtHeading - deerCaughtFinalHeading) * percentDone);
                }
                if (caughtDeer.heading < 0)
                {
                    caughtDeer.heading += 360;
                }
                if (caughtDeer.heading >= 360)
                {
                    caughtDeer.heading -= 360;
                }
                float deerX = pumaX + (deerCaughtOffsetX * (1f - percentDone)) + (deerCaughtFinalOffsetX * percentDone);
                float deerY = caughtDeer.gameObj.transform.position.y;
                float deerZ = pumaZ + (deerCaughtOffsetZ * (1f - percentDone)) + (deerCaughtFinalOffsetZ * percentDone);
                caughtDeer.gameObj.transform.rotation = Quaternion.Euler(0, caughtDeer.heading, 0);
                //System.Console.WriteLine("update heading: " + caughtDeer.heading.ToString());
                caughtDeer.gameObj.transform.position = new Vector3(deerX, deerY, deerZ);
            }
            else
            {
                float deerX = pumaX + deerCaughtFinalOffsetX;
                float deerY = caughtDeer.gameObj.transform.position.y;
                float deerZ = pumaZ + deerCaughtFinalOffsetZ;
                caughtDeer.gameObj.transform.rotation = Quaternion.Euler(0, deerCaughtFinalHeading, 0);
                caughtDeer.gameObj.transform.position = new Vector3(deerX, deerY, deerZ);
                SetGameState("gameStateFeeding2");
            }
            break;

        case "gameStateFeeding2":
            // brief pause
            fadeTime = 1.3f;
            if (Time.time >= stateStartTime + fadeTime)
            {
                SetGameState("gameStateFeeding3");
            }
            break;

        case "gameStateFeeding3":
            // camera slowly lifts as puma feeds on deer
            fadeTime = 5f;
            SelectCameraPosition("cameraPosEating", 1000000f, fadeTime, "mainCurveSBackward", "curveRotXLinear");
            if (Time.time >= stateStartTime + fadeTime)
            {
                SetGameState("gameStateFeeding4");
            }
            break;

        case "gameStateFeeding4":
            // camera spins slowly around puma as it feeds
            if (Time.time >= stateStartTime + 0.1f)
            {
                float spinningRotOffsetY = cameraController.GetCurrentRotOffsetY() - (Time.deltaTime + 0.03f);
                if (spinningRotOffsetY < -180f)
                {
                    spinningRotOffsetY += 360f;
                }
                cameraController.SelectTargetPosition("cameraPosEating", spinningRotOffsetY, 0f, "mainCurveNull", "curveRotXNull");
            }
            break;

        case "gameStateFeeding5":
            // camera swings back into position for stalking
            fadeTime = 2.4f;
            pumaAnimator.SetBool("DeerKill", false);
            SelectCameraPosition("cameraPosHigh", 0f, fadeTime, "mainCurveSBackward", "curveRotXLogarithmic");
            if (Time.time >= stateStartTime + fadeTime)
            {
                PlaceDeerPositions();
                ResetAnimations();
                scoringSystem.ClearLastKillInfo(selectedPuma);
                inputControls.ResetControls();
                SetGameState("gameStateStalking");
            }
            break;

        //------------------------------
        // Died States
        //
        // puma has died
        // returns to overlay display
        //------------------------------

        case "gameStateDied1":
            // camera swings around to front of puma
            fadeTime = 3f;
            SelectCameraPosition("cameraPosCloseup", -160f, fadeTime, "mainCurveSBackward", "curveRotXLogarithmic");
            if (Time.time >= stateStartTime + fadeTime)
            {
                SetGameState("gameStateDied2");
            }
            break;

        case "gameStateDied2":
            // brief pause
            fadeTime = 0.2f;
            if (Time.time >= stateStartTime + fadeTime)
            {
                SetGameState("gameStateDied3");
            }
            break;

        case "gameStateDied3":
            // camera lifts slowly away from puma
            fadeTime = 5f;
            SelectCameraPosition("cameraPosEating", 1000000f, fadeTime, "mainCurveSBackward", "curveRotXLinear");
            if (Time.time >= stateStartTime + fadeTime)
            {
                SetGameState("gameStateDied4");
            }
            break;

        case "gameStateDied4":
            // camera spins slowly around puma
            if (Time.time >= stateStartTime + 0.1f)
            {
                float spinningRotOffsetY = cameraController.GetCurrentRotOffsetY() - (Time.deltaTime + 0.03f);
                if (spinningRotOffsetY < -180f)
                {
                    spinningRotOffsetY += 360f;
                }
                cameraController.SelectTargetPosition("cameraPosEating", spinningRotOffsetY, 0f, "mainCurveNull", "curveRotXNull");
            }
            break;


        //------------------
        // Error Check
        //------------------

        default:
            Debug.Log("ERROR - LevelManager.Update() got bad state: " + gameState);
            break;
        }

        //===============
        // Update Puma
        //===============

        float distance = 0f;

        pumaHeading = mainHeading;

        if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.LeftControl))
        {
            // filter out the input when manual camera moves are in progress - DEV ONLY
        }
        else if (gameState == "gameStateGui" || gameState == "gameStateLeavingGameplay" || gameState == "gameStateLeavingGui")
        {
            // process automatic puma walking during GUI state
            if ((gameState != "gameStateLeavingGui") || (Time.time - stateStartTime < 1.8f))
            {
                pumaAnimator.SetBool("GuiMode", true);
            }
            distance = guiFlybySpeed * Time.deltaTime * 12f * speedOverdrive;
            pumaX   += (Mathf.Sin(mainHeading * Mathf.PI / 180) * distance);
            pumaZ   += (Mathf.Cos(mainHeading * Mathf.PI / 180) * distance);
        }
        else if (gameState == "gameStateStalking")
        {
            // main stalking state
            float rotationSpeed = 100f;
            distance     = inputControls.GetInputVert() * Time.deltaTime * pumaStalkingSpeed * speedOverdrive;
            mainHeading += inputControls.GetInputHorz() * Time.deltaTime * rotationSpeed;
            pumaHeading  = mainHeading + pumaHeadingOffset;
            pumaX       += (Mathf.Sin(pumaHeading * Mathf.PI / 180) * distance);
            pumaZ       += (Mathf.Cos(pumaHeading * Mathf.PI / 180) * distance);
            scoringSystem.PumaHasWalked(selectedPuma, distance);
            if (scoringSystem.GetPumaHealth(selectedPuma) == 0f)
            {
                SetGameState("gameStateDied1");
            }
        }
        else if (gameState == "gameStateChasing")
        {
            // main chasing state
            float rotationSpeed = 150f;
            distance = inputControls.GetInputVert() * Time.deltaTime * pumaChasingSpeed * speedOverdrive;
            float travelledDistance = (scoringSystem.GetPumaHealth(selectedPuma) > 0.05f) ? distance : distance * (scoringSystem.GetPumaHealth(selectedPuma) / 0.05f);
            mainHeading += inputControls.GetInputHorz() * Time.deltaTime * rotationSpeed;
            pumaHeading  = mainHeading + pumaHeadingOffset;
            pumaX       += (Mathf.Sin(pumaHeading * Mathf.PI / 180) * travelledDistance);
            pumaZ       += (Mathf.Cos(pumaHeading * Mathf.PI / 180) * travelledDistance);
            scoringSystem.PumaHasRun(selectedPuma, distance);
            if (scoringSystem.GetPumaHealth(selectedPuma) == 0f)
            {
                SetGameState("gameStateDied1");
            }
        }

        pumaAnimator.SetBool("GuiMode", false);
        pumaAnimator.SetFloat("Distance", distance);

        // calculate puma rotX based on terrain in front and behind
        float pumaRotX;
        float offsetDistance = 1f;
        float pumaAheadX     = pumaX + (Mathf.Sin(pumaHeading * Mathf.PI / 180) * offsetDistance * 1f);
        float pumaAheadZ     = pumaZ + (Mathf.Cos(pumaHeading * Mathf.PI / 180) * offsetDistance * 1f);
        float pumaBehindX    = pumaX + (Mathf.Sin(pumaHeading * Mathf.PI / 180) * offsetDistance * -1f);
        float pumaBehindZ    = pumaZ + (Mathf.Cos(pumaHeading * Mathf.PI / 180) * offsetDistance * -1f);

        pumaRotX = GetAngleFromOffset(0, GetTerrainHeight(pumaAheadX, pumaAheadZ), offsetDistance * 2f, GetTerrainHeight(pumaBehindX, pumaBehindZ)) - 90f;

        // update puma obj
        pumaY = GetTerrainHeight(pumaX, pumaZ);
        pumaObj.transform.position = new Vector3(pumaX, pumaY, pumaZ);
        pumaObj.transform.rotation = Quaternion.Euler(pumaRotX, (pumaHeading - 180f), 0);

        //================
        // Update Camera
        //================

        cameraController.UpdateCameraPosition(pumaX, pumaY, pumaZ, mainHeading);

        //================
        // Update Deer
        //================

        UpdateDeerHeading(buck);
        UpdateDeerHeading(doe);
        UpdateDeerHeading(fawn);
        UpdateDeerPosition(buck);
        UpdateDeerPosition(doe);
        UpdateDeerPosition(fawn);

        //================================
        // Leap-Frog the Ground Planes
        //================================

        for (int i = 0; i < terrainArray.Length; i++)
        {
            float terrainX = terrainArray[i].transform.position.x;
            float terrainZ = terrainArray[i].transform.position.z;

            if (pumaX - terrainX > 3000)
            {
                terrainX += 4000;
            }
            else if (terrainX - pumaX > 1000)
            {
                terrainX -= 4000;
            }

            if (pumaZ - terrainZ > 3000)
            {
                terrainZ += 4000;
            }
            else if (terrainZ - pumaZ > 1000)
            {
                terrainZ -= 4000;
            }

            terrainArray[i].transform.position = new Vector3(terrainX, 0, terrainZ);
        }
    }