Chronicles of cyberpunk — architecture

Home  /  Chronicles of Cyberpunk  /  Chronicles of cyberpunk — architecture

В игре 9 сцен, на которых происходит игра + титры, главное меню, preload. Мы постоянно перемещаемся между этими сценами и когда в Unity ты загружаешь новую сцену, то все объекты предыдущей удаляются из памяти и ты не можешь обратиться к ним. А так как на некоторых сценах мы появляемся больше одного раза и для каждого акта нужно активировать разные группы объектов, то нужно хранить где-то номер текущего акта

Для этого я использую скрипт GameManager с функцией DontDestroyOnLoad(), которая инициализируется на самой первой сцене Preload. Инициализация этой функции — единственное назначение сцены Preload. После нее сразу автоматически загружается следующая. Объект, который содержит скрипт, помечен тегом Acts, поэтому после загрузки движок быстро находит нужный объект и с ним можно работать. Такой скрипт существует на протяжении всей игры на всех сценах в единственном экземпляре

    public string nameOfLastLoadedScene;

    private GameObject player;
    public int currentActNumber { get; set; } // инкремент в конце каждого акта

                         // Главное меню
                         // Preload
    private Act_0 act0;
    private Act_1 act1;
    private Act_2 act2;
    //..
    private Act_2 act28;

   void Start ()
    {
        DontDestroyOnLoad(this);
        SceneManager.LoadScene("Home");
    }

    void OnLevelWasLoaded()
    {
        player = GameObject.FindGameObjectWithTag("PlayerOnMainScene");
        PlacingPlayerNearHouse();
    }

    // При загрузке главной сцены размещаем игрока рядом с домом, откуда он выходил
    void PlacingPlayerNearHouse()
    {
        switch (nameOfLastLoadedScene)
        {            
            case "": player.transform.position = new Vector3(-4.42f, 0.65f, 49.26f); break;           
            case "": player.transform.position = new Vector3(-14.8f, 0.65f,  -7.2f); break;
            case "": player.transform.position = new Vector3( 0.44f, 0.65f,  6.89f); break;
            case "": player.transform.position = new Vector3(36.63f, 0.65f,   6.9f); break;
            case "": player.transform.position = new Vector3( 9.45f, 0.65f,-36.73f); break;
            case "": player.transform.position = new Vector3(-0.32f, 0.65f, -9.34f); break;
            default: break;
        }
    }

В зависимости от номера текущего акта загружаем определенное поведение

    void Update()
    {
        ActManager();
    }

    // Запускать определенный акт в зависимости от currentActNumber
    void ActManager()
    {
        Debug.Log("currentActNumber: " + currentActNumber);
        if (SceneManager.GetActiveScene().name != "PRELOAD" &&
            SceneManager.GetActiveScene().name != "STARTSCREEN")
        {
            GameObject objWithActScripts = GameObject.FindGameObjectWithTag("Acts");

            switch (currentActNumber)
            {
                case 0: act0 = objWithActScripts.GetComponent<Act_0>();
                        act0.StartAct(); break;
                case 1: act1 = objWithActScripts.GetComponent<Act_1>();
                        act1.StartAct(); break;
                //..
            }
        }
    }

И такая схема позволяет программировать последовательность шагов для каждого акта отдельно

    public void StartAct1(MonoBehaviour mb)
    {
        switch (stepNumber)
        { 
            case 0:
                // проигрываем анимацию открытия глаз
                mb.StartCoroutine(OpenCloseEyesAnimation());
                break;
            case 1:
                // отображаем подсказку "нажмите любую клавишу, чтобы проснуться"
                ShowTip(contentToPrint.tipsTasks[0]);
                stepNumber++;
                break;
            case 2:
                // при нажатии на любую кнопку очищаем текст подсказки,
                // анимация закрытия глаз, аудио зевания
                if (Input.anyKey)
                {
                    audioYawn.Play();
                    ShowTip("");
                    mb.StartCoroutine(OpenCloseEyesAnimation());
                }
                break;
            case 3:
                // отключаем игрока в кровати и включаем основного игрока,
                // анимация открытия глаз
                PlayerInBedDisable();
                mb.StartCoroutine(OpenCloseEyesAnimation());
                break;
            case 4:
                // блокируем перемещение, отображаем диалог с дроном
                ShowUIAndPrintMessage(0, 0);                
                stepNumber++;
                break;
            //..
        }
    }
Comments are closed.