Presentation & Dismissal

Canvas controllers can present and dismiss other canvas controllers, allowing you to easily build a user interface flow, presenting and dismissing screens as required.

A canvas controller automatically manages the presentation hierarchy, as well as loading and unloading itself as it is presented or dismissed. This allows you to build large, complex, or dynamic user interface flows, loading only the necessary screens on demand.

Note: Use storyboards to present and dismiss canvas controllers without scripting by visually creating your user interface's flow. Please see the Storyboards section of the manual for information about using Storyboards.

Presenting From A Canvas Controller

Canvas controllers are presented and dismissed using the PresentCanvasController<T>() and DismissCanvasController() methods.

For example, suppose we have two canvas controllers - MenuCanvasController and SettingsCanvasController. In our menu canvas controller is a UI Button that should show the settings screen when pressed.

In the MenuCanvasController.cs script, we could add the following OnClick handler:

public void OnSettingsButtonPressed()
{
    PresentCanvasController<SettingsCanvasController>();
}

And that's it. When this button is pressed, the menu will present the settings screen, dynamically loading the settings canvas controller and animating it on screen.

We could do a similar thing in our settings canvas controller, except this time the button being pressed is a back button and we want to return to the previous screen when it is pressed.

public void OnBackButtonPressed()
{
    DismissCanvasController();
}

This will cause the settings screen to be animated off-screen and subsequently unloaded, returning to the menu.


Presenting From A Scene

In a game environment, there is usually an existing scene - say the game's level or other 3D content scene - over which a user interface is presented. Once the initial canvas controller has been presented, the PresentCanvasController<T>() and DismissCanvasController() methods described above can be used. In order to present the initial canvas controller however, the static method CanvasController.PresentInitialCanvasController<T>() is used.

So, for example, say we have an existing game scene called Level1, which contains our game's content, and a canvas controller called GameOverlayCanvasController. When the game scene Level1 is run, we wish to present the game overlay screen over the game's content.

To do this, we could create a new script in the Level1 game scene and present the initial GameOverlayCanvasController in the MonoBehaviour's Awake() method, like so:

private void Awake()
{
    CanvasController.PresentInitialCanvasController<GameOverlayCanvasController>(animated: false)
}

Note how we can specify this presentation to not be animated by using the animated parameter.

The game overlay screen could then use the PresentCanvasController<T>() and DismissCanvasController() methods described above, perhaps presenting pause or game-over screens, as required.

Note: A single Unity EventSystem is required to be present for canvases to receive input events. Therefore, depending on your game's structure, you may wish to place an Event System (Game Object/UI/Event System) in the scene presenting your initial canvas controller.


Presenting In World Space

By default, canvas controllers are presented in screen space. To present a canvas controller in world space, you specify a CanvasControllerWorldSpaceContainer component when calling the aforementioned CanvasController.PresentInitialCanvasController<T>() method.

First, create a new GameObject in the scene and add a CanvasControllerWorldSpaceContainer component to it. This will give you a world space canvas that you can position freely in your scene.

Then, when calling CanvasController.PresentInitialCanvasController<T>(), pass in the world space container like so:

CanvasController.PresentInitialCanvasController<GameOverlayCanvasController>(worldSpaceContainer: yourWorldSpaceContainer)

This will cause the canvas controller to be presented in world space and embedded within the specified container.

Note that any subsequent calls to PresentCanvasController<T>() will automatically detect whether they should be presented in world space or screen space. If the presenting canvas controller is in world space, the presented canvas controller will also be in world space. Likewise, if the presenting canvas controller is in screen space, the presented canvas controller will also be in screen space.


Configuring A (To-Be) Presented Canvas Controller

All Present…() methods include a configuration action parameter to allow configuring the loaded canvas controller before it is presented. The configuration action is invoked by Canvas Flow after the canvas controller has been loaded, but before it has begun presenting. The configuration action is specified like so:

PresentCanvasController<GameOverlayCanvasController>(configuration: (gameOverlayCanvasController) =>
{
    // Configure the newly-loaded gameOverlayCanvasController.
});

A common use-case for the configuration action is to pass data to the to-be-presented canvas controller. To illustrate, take the earlier example of presenting a game overlay screen in the game's Level1 scene. Say we now have Level2 and Level3 scenes as well, which also display the same game overlay screen as before. However, we want to display the current level number in the top corner of the screen for the player. After adding a label to display the current level, we could also add a ConfigureWithLevel() method to our gameOverlayCanvasController, which sets the level label's text.

// In GameOverlayCanvasController.cs
public void ConfigureWithLevel(int levelNumber)
{
    currentLevelLabel.text = string.Format("Level {0}", levelNumber);
}

Then when presenting the game overlay screen from the Awake() method as before, we can use the configuration action to configure it with the level number, which is set in the scene.

public int levelNumber;

private void Awake()
{
    CanvasController.PresentInitialCanvasController<GameOverlayCanvasController>(
        configuration: (gameOverlayCanvasController) =>
    {
        gameOverlayCanvasController.ConfigureWithLevel(levelNumber);
    } animated: false);
}

Now, no matter how many levels we create, the game overlay screen will simply display the level number it is configured with.

Note: Canvas controllers also have a similar completion: action parameter, which is invoked after the presentation transition has completed.


For information on customizing the transition animation between canvas controllers, please see the Custom Transition Animators section.