Переход между сценами в Unity

Tulenber 27 March, 2020 ⸱ Intermediate ⸱ 10 min ⸱ 2019.3.6f1 ⸱

Это блог про аниме?

Intermedius — находящийся посередине. Думаю, что все, кто смотрел хотя бы одну серию аниме, замечали небольшую вставку в середине, которая обычно служит для перехода между сценами и рекламного блока (англ. - bumper, яп. - アイキャッチ aikyatchi). Картинка из заголовка статьи является таким переходом в одной из серий тайтла “New Game!!", про небольшую игровую студию. Ах да, раз это блог про Unity, то в данном посте мы рассмотрим оформление перехода между сценами именно в нём. =)

Сцены в Unity являются основной единицей деления игры на части и сам по себе переход между ними не является чем-то сложным. Переход реализуется через класс SceneManager, при помощи методов LoadScene() или LoadSceneAsync(), но без дополнительного оформления эти переходы будут резкими и это будет выглядеть странно. Попробуем сгладить этот переход, добавив проекту немного визуальной привлекательности.

Схема довольно проста: обе сцены, между которыми осуществляется переход, должны быть визуально идентичны на момент выгрузки предыдущей и загрузки следующей. Манипуляции для такого перехода обычно организуются через анимацию элементов сцены. Для примера в этом посте мы используем чёрный экран(элементом, отвечающим за данный эффект, будет картинка чёрного цвета). Выгружаемая сцена должна постепенно уйти в чёрный цвет, а следующая за ней плавно из него появиться.

Слово анимация как бы намекает нам на использование механизма в Unity под названием "Mecanim". Если вы не очень с ним знакомы, то можно прочитать(а ещё лучше использовать его в качестве упражнения) предыдущий пост "Шаблон Состояние", в котором, в целях тренировки, этот механизм использовался для создания машины состояний без анимации.

Задача

Оформить переход между тремя сценами через затемнение. Первая сцена появляется моментально и через 2 секунды переходит во вторую. Переходы между второй и третьей зациклены и осуществляется плавно по клику.

Подготовка

  1. Создадим три сцены:
    • BootScene - самая первая сцена, на которую попадает игра, покажем её сразу без затемнения
    • FirstScene и SecondScene - две сцены, переходы между которыми буду зациклены между друг другом
  2. Добавим сцены в Build Settings
    Add scenes
  3. Создадим ещё один объект Canvas с именем SceneTransition. Выставим ему Render Mode - Screen Space - Camera и добавим Main Camera. Выставим Order in Layer равным 999, чтобы он всегда был поверх всего остального
    Create canvas
  4. Добавим к SceneTransition объект типа Image и назовём его Fade. Полностью чёрный, перекрывающий всю площадь экрана. Можно его отключить, чтобы он не загораживал экран
    Add fade element

Анимация

  1. Создадим папку Animations
  2. Откроем панель Animation. Выделив элемент Fade нажмём кнопку Create и создадим анимацию FadeIn, также создадим анимацию FadeOut
    Create animations
  3. Настроим анимацию FadeIn. Выделяем ассет FadeIn. Убираем галочку Loop Time. Выделяем элемент Fade. В закладке Animation нажатием кнопки Enable/Disable keyframe recording mode включаем запись действий. Включаем компонент Image. Переходим в закладке Animation на отметку в 1 секунду. Выставляем в настройке цвета alpha = 0. Выключаем компонент Image. В закладке Animation выключаем запись действий. Проверяем анимацию плавного появления UI из затемнения
    Set up fade in animation
  4. Настраиваем анимацию FadeOut, но в обратном порядке: включаем Image, альфа-канал от 0 до 100. Этот пункт остаётся в качестве тренировки
  5. Настраиваем переход между анимациями. Во вкладке Animator добавляем триггер FadeOut. Добавляем переход между FadeIn и FadeOut. На переходе выключаем Has Exit Time, Transition duration выставляем в 0. В Conditions добавляем созданный триггер FadeOut
    Set up transitions
  6. Создадим скрипт TransitionHandler для переключения сцены после завершения анимации FadeOut
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using UnityEngine;
using UnityEngine.SceneManagement;

public class TransitionHandler : MonoBehaviour
{
    // Имя загружаемой сцены
    [SerializeField] private string nextScene = "";
    // Флаг выключения анимации появления сцены
    [SerializeField] private bool disableFadeInAnimation = false;

    private void Start()
    {
        if (disableFadeInAnimation)
        {
            // При отсутствии анимации появления проигрываем FadeIn в конец при инициализации
            Animator animator = gameObject.GetComponent<Animator>();
            animator.Play("FadeIn", 0 , 1);
        }
    }

    // Функция, вызываемая в конце анимации FadeOut
    void FadeOutFinished()
    {
        // Загрузка следующей сцены
        SceneManager.LoadScene(nextScene);
    }
}
  1. Добавим созданный скрипт к объекту Fade. В конец анимации FadeOut добавим Event. Выберем функцию FadeOutFinished() из скрипта TransitionHandler
    Add action
    Объект эвента на вкладке Animation выглядит так
    Action object
  2. Создадим Prefab из элемента SceneTransition
    Create perefab

Настройка переходов

  1. Для BootScene создадим скрипт, который будет запускать переход на FirstScene через 2 секунды
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System.Collections;
using UnityEngine;

public class BootHandler : MonoBehaviour
{
    // Аниматор для Fade элемента
    [SerializeField] private Animator fadeAnimator = null;

    void Start()
    {
        // Запускаем корутину в качестве таймера
        StartCoroutine(Timer());
    }

    IEnumerator Timer()
    {
        // Задержка в 2 секунды
        yield return new WaitForSeconds(2);
        // Выставляем триггер для начала анимации перехода
        fadeAnimator.SetTrigger("FadeOut");
    }
}
  1. Настроим BootScene. Добавим префаб SceneTransition. Настроим камеру. Укажем следующую сцену - FirstScene. Отключим анимацию появления сцены
    Set up boot scene 1
  2. Добавим на сцену пустой объект назовём его BootHandler и добавим соответствующий скрипт. Настроим для нового объекта animator
    Set up boot scene 2
  3. После запуска BootScene должна иметь затемнение перед переключением
    Test boot scene
  4. Создадим скрипт ClickHandler для остальных сцен, который будет запускать переход по клику
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using UnityEngine;

public class ClickHandler : MonoBehaviour
{
    // Аниматор для Fade элемента
    [SerializeField] private Animator animator = null;
    
    void Update()
    {
        //Перехватываем клик левой кнопки мыши
        if (Input.GetMouseButtonDown (0))
        {
            // Выставляем триггер для начала анимации перехода
            animator.SetTrigger("FadeOut");
        }
    }
}
  1. Настроим FirstScene. Добавим префаб SceneTransition. Настроим камеру. Укажем следующую сцену - SecondScene
    Set up first scene 1
  2. Добавим на сцену пустой объект назовём его ClickHandler и добавим соответствующий скрипт. Настроим для нового объекта animator
    Set up first scene 2
  3. Настроим SecondScene. Проделываем те же самые шаги, что и для FirstScene, только указываем следующей сцену - FirstScene
  4. Наслаждаемся результатом
    Result

Заключение

После всех наших манипуляций мы получили префаб, который можно использовать для настройки переходов между сценами. Навряд ли вы будете его использовать для продакшена, так как используемая синхронная загрузка сцен не очень красивое решение, а также необходима тонкая настройка условий перехода, необходимо продумать остановку игры, в момент начала анимации. Да и сами анимации желательно сделать более интересными, например, в Homescapes(Playrix) переход между загрузкой ресурсов и запуском меню скрыт за опускающейся вдоль стены дома камерой. Однако, после повторения данных шагов собственными руками, у вас должно сложиться представление, как сделать переходы красиво. Пока! =)



Privacy policyCookie policyTerms of service
Tulenber 2020