Custom Transition Animators

You may create your own transition animators to implement a custom transition animation between canvas controllers. If following the steps below, your custom transition animator will be displayed in Unity's Create menu alongside the default transition animators, and will therefore also be compatible with storyboards.

Canvas Flow's default transition animators are included as .cs files. This means you can easily inspect their source code, which is recommended when creating your first custom transition animator. They can be found in the Project inspector at Canvas Flow/Transition Animators/.

See also: Creating A Custom Transition Animator Using DOTween

1. Create A Custom Transition Animator Script

To begin creating a new transition animator, open Unity's Create menu - by either right-clicking in the Project window or selecting Assets in the menu bar - and selecting Create/Canvas Flow/Custom Transition Animator. Enter a name and a directory for your new animator. This will generate a new transition animator script file at the specified location.

The generated script contains two methods for you to implement.

2. The Animate Transition Method

As described in Using A Transition Animator, an instance of your custom transition animator will be vended to Canvas Flow at runtime when the transition is about to be performed. Once this has occurred, Canvas Flow will tell the transition animator to perform the transition by calling its AnimateTransition() method. This is where you can perform your custom animation. Please see Performing The Animation for more details.

public override void AnimateTransition(CanvasControllerTransitionContext transitionContext)
{
    /*  
      *  Do your custom animation with the source and destination content
      *  here. For example:
      *
      *  CanvasController source = transitionContext.sourceCanvasController;
      *  CanvasController destination = transitionContext.destinationCanvasController;
      *
      *  source.ContentPosition = ...
      *  destination.ContentScale = ...
      */

    /*  
     *  Call CompleteTransition() on the transition context once you have
     *  performed your custom animation.
     */
    transitionContext.CompleteTransition();
}

When your transition animator has completed its animation, you must call CompleteTransition on the provided transition context. This tells Canvas Flow that the custom animation has been performed and to complete the transition.

3. The Animate Transition For Initial Canvas Controller Method (Optional)

The AnimateTransitionForInitialCanvasController() method is called on your transition animator when the transition is presenting or dismissing an initial canvas controller. An initial canvas controller is one with no presenter - i.e. it was the first canvas controller presented, perhaps from a storyboard entry transition or using PresentInitialCanvasController. Therefore, you only need to implement this method if you intend to use your transition animator on transitions involving an initial canvas controller.

The only difference from the AnimateTransition method is that either the context's sourceCanvasController or destinationCanvasController will be null, depending on whether the transition context isUpstream - i.e. it is presenting/dismissing to 'nothing'.

The default transition animator, found in Canvas Flow/Transition Animators/DefaultTransitionAnimator.cs simply forwards this method to AnimateTransition() as it only ever operates on the presented canvas, like so:

public override void AnimateTransitionInvolvingInitialCanvasController(
    CanvasControllerTransitionContext transitionContext)
{
    /*
     *  We support transitions to and from the initial canvas controller by
     *  default in our main AnimateTransition() method as we only operate on the
     *  presented canvas controller, so we can just forward to that method.
     */

    AnimateTransition(transitionContext);
}

Please see Canvas Flow/Transition Animators/FadeToColorTransitionAnimator.cs for an example of how different behaviour can be implemented when presenting/dismissing the initial canvas controller.

4. Performing The Animation

Below is an example of a complete AnimateTransition method, which animates the presented canvas controller from/to the bottom of the screen. This will serve as a basis for presenting several useful pointers when animating canvas controllers.

Note that you are free to animate the context's canvas controllers however you wish, including using external animation tools.

public override void AnimateTransition(CanvasControllerTransitionContext transitionContext)
{
    // Determine the target canvas controller - the one being presented or dismissed.
    var targetCanvasController = (transitionContext.isUpstream) ?
        transitionContext.sourceCanvasController :
            transitionContext.destinationCanvasController;

    // Determine the content's start position.
    Vector3 contentStartPosition = (transitionContext.isUpstream) ?
        targetCanvasController.OnScreenContentPosition() :
            targetCanvasController.OffScreenBottomContentPosition();

    // Determine the content's end position.
    Vector3 contentEndPosition = (transitionContext.isUpstream) ?
        targetCanvasController.OffScreenBottomContentPosition() :
            targetCanvasController.OnScreenContentPosition();

    // Create a routine lasting `duration` seconds.
    Routine animation = new Routine(duration);

    // Execute the routine.
    animation.Run(OnUpdate: (progress01) =>
    {
        // The update action is called every frame for the routine's duration,
        // passing in a progress01 value.

        // Move the canvas controller's content from the start position
        // to the end position, each frame.
        targetCanvasController.ContentPosition = Vector3.LerpUnclamped(
                    contentStartPosition,
                    contentEndPosition,
                    progress01);

    }, OnComplete: () =>
    {
        // The completion action is called after `duration` seconds.
        transitionContext.CompleteTransition();
    });
}

The Content Transform

To move a canvas controller's content, the ContentPosition (or content.localPosition) should be animated. Animating the canvas' transform itself will cause the canvas' camera to move with it, which, although moving the canvas in world space, will have no effect on the canvas' screen position.

Similarly, to scale or rotate the canvas, you should also perform these operations on the canvas controller's content transform.

Use The Helper Positioning Methods

A canvas controller has several extension methods to help with positioning a canvas controller's content transform. These are used above to calculate the content's on/off-screen position.

Routine

The above example, as well as all default transition animators, use Canvas Flow's Routine class to perform their animation. You may also use this class to easily create a coroutine with a progress and completion callback, as above.

Complete The Transition

When your transition animator has completed its animation, you must call CompleteTransition on the provided transition context. This tells Canvas Flow that the custom animation has been performed and to complete the transition.

5. Use Your Custom Transition Animator

Once your custom transition animator is complete, it will be available to select in Unity's Create menu. Please refer to Using A Transition Animator to create an instance of your custom animator.