Как переименовать сцену в unity
Перейти к содержимому

Как переименовать сцену в unity

Scenes

Сцены содержат объекты вашей игры. Они могут использоваться для создания главного меню, отдельных уровней и для других целей. Можно считать каждый файл сцены отдельным игровым уровнем. В каждой сцене можно разместить объекты окружения, заграждения, декорации, по кусочкам создавая дизайн и саму игру.

A new empty scene, with the default 3D objects - a camera and a directional light.

When you create a new Unity project, your scene view will show a new Scene. This is an untitled and unsaved scene. The scene will be empty except for defult objects — either an orthographic camera, or a perspective camera and a directional light, depending on whether you started the project in 2D or 3D mode.

To save the scene you’re currently working on, choose File > Save Scene from the menu, or pres Ctrl/Cmd + S.

Scenes are saved as assets, into your project’s Assets folder. Therefore they appear in the Project Window, just like any other asset.

Some scene assets, saved and visible in the project view

To open a scene, in order to begin or continue working within that scene, double-click the scene asset in the Project Window.

If your current scene contains unsaved changes, you will be prompted to save or discard the changes.

Multi-Scene Editing.

It is possible to have multiple scenes open for editing at one time. For more information about this, see Multi-Scene Editing.

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

Приветствую! В данной статье мы разберём несколько способов перехода между сценами, а именно:

  1. Смена сцен по названию.
  2. Смена сцен по индексам.
  3. Смена сцен, используя параметры.

Смена сцен по названию

Данный способ самый простой, и встречается он очень часто. Он используется тогда, когда нам необходимо перейти точно на определённую сцену. Для этого создадим C# скрипт, с названием, например, Scenes. И пропишем в нём следующий код:

using UnityEngine; using UnityEngine.SceneManagement; public class Scenes : MonoBehaviour < public void OpenMenu() < SceneManager.LoadScene("Menu"); >public void OpenGame() < SceneManager.LoadScene("Game"); >>

Разбор кода

Обратите внимание, что при работе со сценами, нам необходимо обязательно подключить библиотеку:

using UnityEngine.SceneManagement; 

Дальше мы создаём функцию OpenMenu(), которая будет загружать сцену с названием Menu. Вторая функция с названием OpenGame() загружаем сцену с названием Game. Убедитесь, что сцены с такими названиями существуют в Вашем проекте.

Как видите, всё очень просто. Условия, при которых Вы будете запускать данные функции, могут быть совсем разные. Например: клик на клавишу «Esc», здоровье персонажа меньше нуля, и тд. Пример:

if(HealthUser

Смена сцен по индексам

Данный способ аналогичен предыдущему, за исключением того, что мы вместо названий сцен, используем их индексы. Данный способ полезен в тех случаях, когда нам необходимо перейти на следующую или предыдущую сцену. Создадим C# скрипт, с названием, например, Scenes. И пропишем в нём следующий код:

using UnityEngine; using UnityEngine.SceneManagement; public class Scenes : MonoBehaviour < public void OpenMenu() < SceneManager.LoadScene(0); >public void OpenGame() < SceneManager.LoadScene(1); >>

Как видите, код аналогичен предыдущему, поэтому разбирать мы его не будем. Единственное что хотелось бы отметить, что благодаря функциям, у нас открываются чуть больше возможностей перехода на сцены. Например, мы можем перейти на следующую или предыдущую функцию:

using UnityEngine; using UnityEngine.SceneManagement; public class Scenes : MonoBehaviour < public void NextLevel() < var index = SceneManager.GetActiveScene().buildIndex; SceneManager.LoadScene(index + 1); >public void PreviousLevel() < var index = SceneManager.GetActiveScene().buildIndex; SceneManager.LoadScene(index - 1); >>

Разбор кода

Строчки в функции NextLevel():

var index = SceneManager.GetActiveScene().buildIndex; SceneManager.LoadScene(index + 1); 

В первой строчке мы в переменную index мы заносим тот индекс сцены, в котором мы находимся в данный момент. А уже во второй строчке, мы увеличиваем индекс нашей сцены на единицу, и запускаем таким образом следующую сцену.

В функции PreviousLevel() всё аналогично, только индекс мы не увеличиваем на единицу, а уменьшаем. Тем самым запускаем предыдущую сцену.

Обратите внимание! Перед тем как работать со сценами по их индексам, нам необходимо добавить все сцены в Build Settings. Для этого жмём на вкладку File — Build Settings. Далее перетаскиваем все свои сцены в область Scenes in Build, и расставляем их по порядку. После чего просто закрываем данное окно. Теперь можно спокойно работать с индексами.

Смена сцен, используя параметры

Данный способ аналогичен предыдущему, только здесь мы переходим на определённую сцену исходя из переданного аргумента в нашу функцию.

using UnityEngine; using UnityEngine.SceneManagement; public class Scenes : MonoBehaviour < public void GoToLevel(int number) < SceneManager.LoadScene(number); >>

Разбор кода

Функция GoToLevel() принимает в качестве аргумента номер индекса, который нам необходимо открыть, и заносит его в переменную number. Этот метод защитит нас от дублирования однотипных функций, которые по идее выполняют одно и тоже.

Давайте теперь попробуем выполнить функцию GoToLevel(), передав ей аргумент «1» следующим образом:

GoToLevel(1)

Конечно же, в качестве аргумента мы можем передать не только индекс, но и название. Поэтому используя открытие сцены через аргумент функции, Вы можете работать как с индексами, так и с названиями сцен.

Если Вам понравилась сцена, буду рад Вашим лайкам.

Как переименовать сцену

Есть две сцены — одна называется Untitled а друга SampleScene . Как назвать их Menu и Level1 ? Версия 2018.4.7f1.

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Как перезапустить сцену?
Не могу перезапустить сцену, точнее сцена перезагружается, но враги перестают спавнится и.

Как затемнить сцену?
Приветствую! Такая беда: В моей 2D игре игроки, подключённые по сети, бегают по ЗАТЕМНЁННОЙ сцене.

Как узнать текущую сцену (уровень)?
Как узнать текущую сцену и вывести её в переменную? Должно получиться что то типа этого: scen =.

Как сохранить сцену после нажатия?
У меня есть игрок который может перемещаться по сценам. Например когда он первый раз зашел на сцену.

Как мы переосмыслили работу со сценами в Unity

Unity, как движок, имеет ряд недостатков, но которые благодаря возможностям для кастомизации и инструментам для кодогенерации, можно решить.

Сейчас я вам расскажу о том, как мы написали плагин для Unity на основе пост-процессинга проектов и кодогенератора CodeDom.

Проблема

В Unity загрузка сцен происходит через строковой идентификатор. Он не стабильный, а это означает, что он легко изменяем без явных последствий. Например, при переименовании сцены всё полетит, а выяснится это только в самом конце на этапе выполнения.

Проблема обнаруживается быстро на часто используемых сценах, но может быть трудно обнаруживаемая, если речь идёт о небольших additive сценах или сценах, которые используются редко.

Решение

При добавлении сцены в проект, генерируется одноимённый класс с методом Load.

Если мы добавим сцену Menu, то в проекте сгенерируется класс Menu и в дальнейшем мы можем запустить сцену следующим образом:

Menu.Load();

Да, статический метод — это не лучшая компоновка. Но мне показалось это лаконичным и удобным дизайном. Генерация происходит автоматически, исходный код такого класса:

//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace IJunior.TypedScenes < public class Menu : TypedScene < private const string GUID = "a3ac3ba38209c7744b9e05301cbfa453"; public static void Load() < LoadScene(GUID); >> > 

По-хорошему, класс должен быть статическим, так как не предполагается создание экземпляра из него. Это ошибка, которую мы исправим. Как видно уже из этого фрагмента, кода мы цепляемся не к имени, а к GUID сцены, что является более надежным. Сам базовый класс выглядит вот так:

namespace IJunior.TypedScenes < public abstract class TypedScene < protected static void LoadScene(string guid) < var path = AssetDatabase.GUIDToAssetPath(guid); SceneManager.LoadScene(path); >protected static void LoadScene(string guid, T argument) < var path = AssetDatabase.GUIDToAssetPath(guid); UnityActionhandler = null; handler = (from, to) => < if (to.name == Path.GetFileNameWithoutExtension(path)) < SceneManager.activeSceneChanged -= handler; HandleSceneLoaders(argument); >>; SceneManager.activeSceneChanged += handler; SceneManager.LoadScene(path); > private static void HandleSceneLoaders(T loadingModel) < foreach (var rootObjects in SceneManager.GetActiveScene().GetRootGameObjects()) < foreach (var handler in rootObjects.GetComponentsInChildren()) < handler.OnSceneLoaded(loadingModel); >> > > >

В этой реализации видна ещё одна фишка — передача параметров сценам.

Параллельно с решением первой проблемы — избавить код от строковых идентификаторов сцены (в том числе и от констант, которые нужно обновлять вручную), мы добавили еще и параметризацию сцен.

Теперь сцена может задекларировать список параметров, а вызывающий код должен передать для них аргументы.

Например, сцена Game хочет получить перечисление, содержащее всех игроков и при инициализации добавить для них аватаров.

В таком случае мы можем сами создать такой компонент.

using IJunior.TypedScenes; using System.Collections.Generic; using UnityEngine; public class GameLoadHandler : MonoBehaviour, ISceneLoadHandler> < public void OnSceneLoaded(IEnumerableplayers) < foreach (var player in players) < //make avatars >> >

После размещения его на сцене и последующим её сохранением, генератор добавит в класс сцены метода запуска сцены с обязательной передачей перечисления игроков.

//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace IJunior.TypedScenes < public class Game : TypedScene < private const string GUID = "976661b7057d74e41abb6eb799024ada"; public static void Load(System.Collections.Generic.IEnumerableargument) < LoadScene(GUID, argument); >> >

В данный момент реализована возможность перегрузки обработчиков. Т.е. если на сцене будет N обработчиков с разными параметрами, под них создастся N методов запуска. Также не запрещается наличие нескольких компонентов-обработчиков с одинаковыми параметрами.

Это не фишка, а скорее недоработка, так как такой функционал быстрее создаст путаницу, нежели будет полезен.

А почему не сделать через N?

Первую версию плагина я осветил на своём YouTube канале в этом видео.

Там задали ряд вопросов и предложили альтернативные решения. Есть интересные подходы, которые имеют право на жизнь, а есть откровенно идиотские, которые я хочу разобрать.

Чем плох статический класс с полями, через которые передаются данные для сцены?

Нередко встречаю и такое. Речь идёт о классе по типу этого:

public class GameArguments < public IEnumerablePlayers < get; set; >>

А уже внутри сцены, вероятно, будет группа компонентов, которая достаёт данные из свойств.

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

Ну и опять же сцену придётся запускать по ID или имени.

Чем плох PlayerPerfs

Предлагали и такой экзотический вариант. Можно было бы начать с того, что PlayerPrefs вообще не предназначен для передачи значений внутри одного инстанса. Этим можно было бы и закончить, но продолжим критику тем, что вам также придётся работать с неформальными строковыми идентификаторами параметров.

Параллель с ASPNet

Мне хотелось получить что-то схожее с строго типизированными View из ASPNet Core. Мы считаем плохим тоном использовать ViewData и стараемся определять ViewModel. В Unity хочется что-то такого же толка с теми же преимуществами.

Отличие Unity в первую очередь в том, что сцена — это обычно более громоздкое предприятие, нежели View в ASPNet. Это решается разбивкой одной сцены на несколько подсцен с режимом загрузки Additive (наш плагин, к слову, его поддерживает), что позволяет скомпоновать сцену из сцен поменьше со своими более атомарными моделями.

Но такой подход не очень распространён, к сожалению, и на это, я думаю, есть свои причины.

Где скачать

Плагин мы сделали в паре с Владиславом Койдо в рамках Proof-of-concept. Он ещё не стабилен и не обкатан как следует, но с ним уже можно поиграться.

Если вам интересно, я попрошу Владислава в следующей статье рассказать, как он работал с Code Dom в Unity и как работать с пост-процессингом на примере того, что мы сегодня обсуждали.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *