Перейти к основному содержимому

Обновление с прошлых версий

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

warning

После установки новой версии обязательно откройте ваш WorldGraphContainer и нажмите "Save" — это пересоберёт сериализованные данные графа под актуальный формат и предотвратит возможные ошибки в Play Mode и при сборке.

С версии 1.0 на 1.1

Если вы обновляетесь с версии 1.0, внимательно ознакомьтесь с этим разделом. Он описывает перенос данных из 1.0 в 1.1.

Новая система сохранений

Начиная с версии 1.1 используется новая система сохранений, несовместимая с форматом версии 1.0. Чтобы конвертировать ваши данные:

  1. Откройте проект и убедитесь что все сцены, используемые в графе находятся в Build Settings. Для этого откройте в графе ваш контейнер и нажмите кнопку "Save".
  2. Найдите и выберите нужный контейнер в Project-окне. В окне Inspector нажмите на три вертикальные точки (⋮) и выберите пункт To Json. При успешном экспорте рядом с контейнером появился .json-файл с таким же именем.
  3. Удалите текущую версию World Graph Editor и установите новую.
  4. После установки создайте новый контейнер или выберите существующий. Важно: его имя должно совпадать с именем .json-файла, и он должен находиться в той же папке.
  5. Выберите контейнер в окне Inspector, нажмите и выберите Load From Json. Если все сделано правильно, контейнер автоматически заполнится данными, а так же появится вложенный ассет с именем Editor Only Data.
  6. Откройте граф с этим контейнером и нажмите "Save".

Видео: Ссылка

Обновленная регистрация асинхронных методов

Начиная с версии 1.1 методы RegisterAsyncHandler и UnregisterAsyncHandler теперь принимают делегаты типа Func<CancellationToken, Task> вместо Func<Task>. Старые версии этих методов помечены как [Obsolete] и вызовут ошибку компиляции.

Чтобы обновить код, добавьте параметр CancellationToken в асинхронный метод:

Было:

TransitionManager.RegisterAsyncHandler(eventType, DoSomething, 0);

private async Task DoSomething()
{
await Awaitable.WaitForSecondsAsync(1f);
}

TransitionManager.UnregisterAsyncHandler(_eventType, DoSomething);

Стало:

TransitionManager.RegisterAsyncHandler(eventType, DoSomething, 0);

private async Task DoSomething(CancellationToken token)
{
await Awaitable.WaitForSecondsAsync(1f, token);
}

TransitionManager.UnregisterAsyncHandler(_eventType, DoSomething);

С версии 1.1 на 1.2

Если вы обновляетесь с версии 1.1, учтите следующие изменения в API и поведении редактора.

Интерфейс ITransitionComponent

Метод в редакторе изменился: вместо void Refresh(TransitionManager manager)void Refresh(RefreshContext context). Заполнение PortsDropdown и ручной доступ к данным теперь идут через RefreshContext — полное описание см. в разделе RefreshContext.

ContainerEditorData и пути сцен

  • Рекомендуемый метод: GetPortsDropdownData(string scenePath) — путь к .unity файлу сцены (как у Scene.path / SceneManager.GetActiveScene().path).
  • Перегрузка GetPortsDropdownData(int buildIndex) помечена как [Obsolete] и сохранена для обратной совместимости; в новом коде лучше перейти на вариант с путём сцены.

TransitionManager.RefreshPorts()

  • Метод TransitionManager.RefreshPorts() помечен как [Obsolete] и не выполняет обновление. В редакторе списки портов и компоненты с ITransitionComponent обновляются автоматически при смене сцены, иерархии и ряде других действий. Не вызывайте этот метод из OnValidate и пользовательского кода — полагайтесь на автоматическое обновление.

С версии 1.2 на 1.3

Если вы обновляетесь с версии 1.2, учтите следующие изменения в API. Все перечисленные ниже старые методы и свойства помечены [Obsolete], но продолжают работать — обновлять код можно постепенно.

RefreshContext: от Manager к EditorGraph

Свойство RefreshContext.Manager (тип ITransitionManager) помечено как [Obsolete]. Вместо него используйте новое свойство RefreshContext.EditorGraph (тип EditorGraph) — оно даёт прямой доступ к графу редактора и не зависит от того, какой TransitionManager используется в проекте (встроенный или собственный).

Было:

public void Refresh(RefreshContext context)
{
var container = context.Manager.Container;
var scenePath = SceneManager.GetActiveScene().path;
var scenePortsData = container.EditorData.GetPortsDropdownData(scenePath);

_dropdown.SetData(scenePortsData);
}

Стало:

public void Refresh(RefreshContext context)
{
var scenePath = SceneManager.GetActiveScene().path;
var scenePortsData = context.EditorGraph.GetPortsDropdownData(scenePath);

_dropdown.SetData(scenePortsData);
}
примечание

По той же причине WorldGraphContainer.EditorData (тип ContainerEditorData) также помечен [Obsolete]. Используйте WorldGraphContainer.EditorGraph (тип EditorGraph) — методы у него те же (GetPortsDropdownData, GetAllPortsDropdownData, TryGetSceneDataByPortGuid и т.д.), отличается только точка доступа.

Методы расширения ITransitionComponent

В связи с поддержкой собственных реализаций TransitionManager часть методов расширения для ITransitionComponent изменилась:

БылоСталоПричина
IsOutput()IsOutput(ITransitionManager manager)Старая перегрузка помечена [Obsolete] и продолжает работать через TransitionManager.Instance, но выбросит исключение, если в настройках включён кастомный менеджер.
IsInput()IsInput(ITransitionManager manager)То же самое.
IsShortcutOutput()IsShortcutDestination()Переименование для согласованности с WorldGraph/EditorGraph.
IsShortcutInput()IsShortcutOrigin()Переименование для согласованности с WorldGraph/EditorGraph.
Также добавлены аналогичные методы для One-Way связей: IsOneWayOrigin() и IsOneWayDestination().

Было:

if (component.IsOutput())
{
// ...
}

Стало:

if (component.IsOutput(TransitionManager.Instance))
{
// ...
}
подсказка

IsShortcutDestination(), IsShortcutOrigin(), IsOneWayOrigin(), IsOneWayDestination() менеджер не принимают — они читают граф напрямую, поэтому работают одинаково и со встроенным, и с кастомным TransitionManager.

События TransitionManager стали свойствами экземпляра

Статические события TransitionManager.OnInitialized, OnPortEntered, OnTransitionStarted, OnSceneLoaded, OnTransitionEnded, OnPortLeaved и OnDestroyed помечены [Obsolete]. Подписывайтесь на одноимённые свойства (без префикса On) у TransitionManager.Instance.

Было:

private void Awake()
{
TransitionManager.OnTransitionEnded += OnTransitionEnded;
}

private void OnDestroy()
{
TransitionManager.OnTransitionEnded -= OnTransitionEnded;
}

Стало:

private void Awake()
{
TransitionManager.Instance.TransitionEnded += OnTransitionEnded;
}

private void OnDestroy()
{
TransitionManager.Instance.TransitionEnded -= OnTransitionEnded;
}
warning

Если вы используете собственный TransitionManager, TransitionManager.Instance не создаётся — подписывайтесь на события прямо на экземпляре вашей реализации ITransitionManager.

TransitionManager и асинхронные переходы

Методы переходов в TransitionManager стали асинхронными и возвращают Task:

БылоСтало
void GoTo(string, string, ITransitionContext)Task GoToAsync(string, string, ITransitionContext)
void GoFrom(string, bool ignoreShortcuts, ITransitionContext)Task GoFromAsync(string, ITransitionContext)
Task LoadScene(int, TransitionContext)Task LoadSceneAsync(int, TransitionContext)

Старые синхронные методы помечены [Obsolete] и продолжают работать. Для вызова без ожидания (fire-and-forget) используйте _ = manager.GoFromAsync(...).

Параметр ignoreShortcuts убран из GoFromAsync в интерфейсе ITransitionManager — решение о допустимости перехода теперь принимает сама реализация. У встроенного TransitionManager при этом остаётся перегрузка GoFromAsync(currentPortGuid, ignoreShortcuts, context).

Замена Get-методов на TryGet

Часть Get-методов, которые возвращали данные (или default при отсутствии), заменены на парные TryGet-методы с типичным паттерном bool + out. Это убирает необходимость в магических значениях для индикации «не найдено» и делает обработку отсутствующих данных явной.

Актуальные TryGet-методы находятся на графе — IWorldGraph/WorldGraph (рантайм) и EditorGraph (редактор). Старые Get-версии с самого графа удалены; для плавной миграции они помечены [Obsolete] и оставлены на WorldGraphContainer и ContainerEditorData, откуда и вызывались в 1.2.

Было (устаревший метод на контейнере):

var opposite = container.GetOppositePassageGuid(currentPortGuid);

if (opposite == currentPortGuid)
{
// связи нет
return;
}

Стало:

if (!Graph.TryGetOppositePassageGuid(currentPortGuid, out var opposite))
{
// связи нет
return;
}

Также добавлены новые TryGet-методы (без устаревших Get-аналогов):

  • На WorldGraph / GraphEngine: TryGetPassageTransitionData(currentPortGuid, out data), TryGetSceneDataByPortGuid(guid, out data), TryGetSceneDataByAddress(address, out data) (только при включённых Addressables).
  • На EditorGraph: TryGetSceneDataBySceneAssetGuid(sceneAssetGuid, out data), TryGetSceneDataByPath(path, out data).