Skip to main content

Upgrading from previous versions

If you jump to the current version from an older one, read every section between your current version and 1.3 — changes are cumulative.

warning

After installing a new version, make sure to open your WorldGraphContainer and press "Save" — this rebuilds the serialized graph data in the current format and prevents possible errors in Play Mode and during builds.

From 1.0 to 1.1

If you are upgrading from 1.0, read this section carefully. It describes the data migration from 1.0 to 1.1.

New save system

Starting with 1.1 a new save format is used that is incompatible with 1.0. To convert your data:

  1. Open the project and make sure every scene used in the graph is in Build Settings. In the graph, open your container and press "Save".
  2. Find and select the target container in the Project window. In the Inspector click the three vertical dots (⋮) and pick To Json. On success a .json file with the same name appears next to the container.
  3. Remove the current version of World Graph Editor and install the new one.
  4. After installation, create a new container or use an existing one. Important: its name must match the .json filename, and it must live in the same folder.
  5. Select the container in the Inspector, click and pick Load From Json. If everything is correct, the container fills with data and a nested asset named Editor Only Data appears.
  6. Open the graph for that container and press "Save".

Video: Link

Updated async handler registration

Starting with 1.1, RegisterAsyncHandler and UnregisterAsyncHandler accept Func<CancellationToken, Task> delegates instead of Func<Task>. The old signatures are marked [Obsolete] and will produce a compile error.

To update your code, add a CancellationToken parameter to the async method:

Before:

TransitionManager.RegisterAsyncHandler(eventType, DoSomething, 0);

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

TransitionManager.UnregisterAsyncHandler(_eventType, DoSomething);

After:

TransitionManager.RegisterAsyncHandler(eventType, DoSomething, 0);

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

TransitionManager.UnregisterAsyncHandler(_eventType, DoSomething);

From 1.1 to 1.2

If you are upgrading from 1.1, note the following API and editor behavior changes.

ITransitionComponent interface

The editor-side method changed: instead of void Refresh(TransitionManager manager) it is now void Refresh(RefreshContext context). Filling PortsDropdown and manual data access now go through RefreshContext — full description in the RefreshContext section.

ContainerEditorData and scene paths

  • Recommended method: GetPortsDropdownData(string scenePath) — the path to the scene .unity asset (same as Scene.path / SceneManager.GetActiveScene().path).
  • The GetPortsDropdownData(int buildIndex) overload is marked [Obsolete] and kept for backward compatibility; new code should use the scene-path variant.

TransitionManager.RefreshPorts()

  • TransitionManager.RefreshPorts() is marked [Obsolete] and no longer performs any refresh. In the editor, port lists and components implementing ITransitionComponent are refreshed automatically on scene, hierarchy, and other changes. Do not call this method from OnValidate or user code — rely on the automatic refresh.

From 1.2 to 1.3

If you are upgrading from 1.2, note the following API changes. All old methods and properties listed below are marked [Obsolete] but keep working — you can migrate gradually.

RefreshContext: from Manager to EditorGraph

The RefreshContext.Manager property (of type ITransitionManager) is marked [Obsolete]. Use the new RefreshContext.EditorGraph property (of type EditorGraph) instead — it gives direct access to the editor graph and does not depend on which TransitionManager is used in the project (built-in or custom).

Before:

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

_dropdown.SetData(scenePortsData);
}

After:

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

_dropdown.SetData(scenePortsData);
}
note

For the same reason, WorldGraphContainer.EditorData (of type ContainerEditorData) is also marked [Obsolete]. Use WorldGraphContainer.EditorGraph (of type EditorGraph) — the methods are the same (GetPortsDropdownData, GetAllPortsDropdownData, TryGetSceneDataByPortGuid, etc.), only the entry point differs.

ITransitionComponent extension methods

To support custom TransitionManager implementations, some ITransitionComponent extension methods changed:

BeforeAfterReason
IsOutput()IsOutput(ITransitionManager manager)The old overload is marked [Obsolete] and keeps working through TransitionManager.Instance, but throws if a custom manager is enabled in the settings.
IsInput()IsInput(ITransitionManager manager)Same.
IsShortcutOutput()IsShortcutDestination()Renamed for consistency with WorldGraph/EditorGraph.
IsShortcutInput()IsShortcutOrigin()Renamed for consistency with WorldGraph/EditorGraph.
Analogous methods for One-Way connections were also added: IsOneWayOrigin() and IsOneWayDestination().

Before:

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

After:

if (component.IsOutput(TransitionManager.Instance))
{
// ...
}
tip

IsShortcutDestination(), IsShortcutOrigin(), IsOneWayOrigin(), IsOneWayDestination() do not take a manager — they read the graph directly and therefore work identically with the built-in and custom TransitionManager.

TransitionManager events became instance properties

The static events TransitionManager.OnInitialized, OnPortEntered, OnTransitionStarted, OnSceneLoaded, OnTransitionEnded, OnPortLeaved, and OnDestroyed are marked [Obsolete]. Subscribe to identically-named properties (without the On prefix) on TransitionManager.Instance.

Before:

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

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

After:

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

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

If you use a custom TransitionManager, TransitionManager.Instance is never created — subscribe to events directly on the instance of your ITransitionManager implementation.

TransitionManager and async transitions

The transition methods on TransitionManager are now asynchronous and return a Task:

BeforeAfter
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)

The old synchronous methods are marked [Obsolete] and keep working. For fire-and-forget calls use _ = manager.GoFromAsync(...).

The ignoreShortcuts parameter was removed from GoFromAsync on the ITransitionManager interface — the implementation itself now decides whether a transition is allowed. The built-in TransitionManager still keeps a GoFromAsync(currentPortGuid, ignoreShortcuts, context) overload.

Replacing Get methods with TryGet

Some graph Get methods that returned data (or default when missing) were replaced by paired TryGet methods following the usual bool + out pattern. This removes the need for magic values to signal "not found" and makes missing data handling explicit.

The current TryGet methods live on the graph — IWorldGraph/WorldGraph (runtime) and EditorGraph (editor). The old Get versions were removed from the graph itself; for a smooth migration they are marked [Obsolete] and kept on WorldGraphContainer and ContainerEditorData, where they were called from in 1.2.

Before (deprecated method on the container):

var opposite = container.GetOppositePassageGuid(currentPortGuid);

if (opposite == currentPortGuid)
{
// no connection
return;
}

After:

if (!Graph.TryGetOppositePassageGuid(currentPortGuid, out var opposite))
{
// no connection
return;
}

New TryGet methods were also added (with no obsolete Get counterpart):

  • On WorldGraph / GraphEngine: TryGetPassageTransitionData(currentPortGuid, out data), TryGetSceneDataByPortGuid(guid, out data), TryGetSceneDataByAddress(address, out data) (only when Addressables is enabled).
  • On EditorGraph: TryGetSceneDataBySceneAssetGuid(sceneAssetGuid, out data), TryGetSceneDataByPath(path, out data).