Обновление с прошлых версий
Если вы переходите на актуальную версию с более ранней, прочитайте все разделы между вашей текущей версией и 1.3 — изменения накапливаются.
После установки новой версии обязательно откройте ваш WorldGraphContainer и нажмите "Save" — это пересоберёт сериализованные данные графа под актуальный формат и предотвратит возможные ошибки в Play Mode и при сборке.
С версии 1.0 на 1.1
Если вы обновляетесь с версии 1.0, внимательно ознакомьтесь с этим разделом. Он описывает перенос данных из 1.0 в 1.1.
Новая система сохранений
Начиная с версии 1.1 используется новая система сохранений, несовместимая с форматом версии 1.0. Чтобы конвертировать ваши данные:
- Откройте проект и убедитесь что все сцены, используемые в графе находятся в Build Settings. Для этого откройте в графе ваш контейнер и нажмите кнопку "Save".
- Найдите и выберите нужный контейнер в Project-окне. В окне Inspector нажмите на три вертикальные точки (⋮) и выберите пункт To Json. При успешном экспорте рядом с контейнером появился
.json-файл с таким же именем. - Удалите текущую версию World Graph Editor и установите новую.
- После установки создайте новый контейнер или выберите существующий. Важно: его имя должно совпадать с именем
.json-файла, и он должен находиться в той же папке. - Выберите контейнер в окне Inspector, нажмите ⋮ и выберите Load From Json. Если все сделано правильно, контейнер автоматически заполнится данными, а так же появится вложенный ассет с именем Editor Only Data.
- Откройте граф с этим контейнером и нажмите "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;
}
Если вы используете собственный 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).