docs.unity3d.com
    Show / Hide Table of Contents

    How to have a smoother transition between products when cameras are different

    Switching between products that use different cameras can produce visually unpleasant results. This happens when the current camera doesn't exist in the product the user switches to and the image abruptly cuts. Even though Forma currently doesn't support specifying a list of commands that get executed when changing products, you can still achieve a smooth transition between products.

    How to implement the smooth transition

    Use this section to implement a smooth transition. Use the following procedure so that, when switching products, a screenshot is taken and there is a fade with the chosen duration between products. The cameras are different between the products, but the smooth transition enhances the experience.

    1) Create a new script named SwitchProduct in your Unity project and copy the following code:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using Unity.Industrial.Forma.Core;
    using Unity.Industrial.Forma.Core.Commands;
    using Unity.Industrial.Forma.Core.Configuring;
    using Unity.Industrial.Forma.Core.Products;
    using UnityEngine;
    
    public class SwitchProduct : MonoBehaviour
    {
        Texture2D m_Screenshot;
        Sprite m_Sprite;
    
        void OnEnable()
        {
            GetComponent<Configurator>().configurationManager.products.productChanged += ProductsOnAnyProductChanged;
            ProductRepository.anyProductChanged += ProductsOnAnyProductChanged;
        }
    
        void OnDisable()
        {
            GetComponent<Configurator>().configurationManager.products.productChanged -= ProductsOnAnyProductChanged;
            ProductRepository.anyProductChanged -= ProductsOnAnyProductChanged;
        }
    
        void ProductsOnAnyProductChanged(object sender, ConfigurationManagerProductChangedArgs args)
        {
            switch (args.eventType)
            {
                case ConfigurationManagerProductChangedEventType.ProductPreUnload:
                    StartCoroutine(HandleProductUnload());
                    break;
                case ConfigurationManagerProductChangedEventType.ProductLoaded:
                    HandleProductLoad();
                    break;
            }
        }
    
        IEnumerator HandleProductUnload()
        {
            //yield return new WaitForEndOfFrame();
            ScreenShot();
            yield return null;
        }
    
        void ScreenShot()
        {
            if (!Application.isPlaying)
                return;
    
            if (Application.isBatchMode)
                return;
    
            if(m_Screenshot != null)
                Destroy(m_Screenshot);
    
            if(m_Sprite != null)
                Destroy(m_Sprite);
    
            var screenWidth = Screen.width;
            var screenHeight = Screen.height;
    
            m_Screenshot = new Texture2D(screenWidth, screenHeight, TextureFormat.RGB24, false);
            m_Screenshot.ReadPixels(new Rect(0, 0, screenWidth, screenHeight), 0, 0, false);
            m_Screenshot.Apply();
    
            m_Sprite = Sprite.Create(
                texture: m_Screenshot,
                rect: new Rect(0, 0, screenWidth, screenHeight),
                pivot: new Vector2(0.5f, 0.5f),
                pixelsPerUnit: 100.0f);
            var splashscreen = Configurator.s_ConfiguratorInstance.splashscreen;
            if (splashscreen == null)
                return;
    
            splashscreen.transitionImage = m_Sprite;
            splashscreen.canvasGroup.alpha = 1.0f;
        }
    
        void HandleProductLoad()
        {
            var elementId = "Fade";
            var stagingElement = GetComponent<Configurator>().globalStagingSettings.events.FirstOrDefault(e => string.Equals(e.ID, elementId, StringComparison.OrdinalIgnoreCase));
            if (stagingElement == null)
                return;
    
            var fadeCommand = stagingElement.enterCommands.FirstOrDefault();
            if (!fadeCommand)
                return;
    
            StartCoroutine(fadeCommand.Execute(new CommandContext(Configurator.s_ConfiguratorInstance, new List<Command>() { fadeCommand })));
        }
    }
    
    1. Add the SwitchProduct script as a component on the Configurator GameObject that has the Configurator component.
    2. Go to Configurator > Staging Settings on the Configurator GameObject that has the Configurator component.
    3. In Events, create a global event.
    4. Name the global event Fade (this name can be different if it's also adjusted in the script) and add a FadeScreenshotCommand in the Enter Commands section. In the Hierarchy window, the FadeScreenshotCommand is under Configurator > enterCommands.

      Screenshot of the FadeScreenshotCommand in the Hierarchy window

    5. Select FadeScreenshotCommand.

    6. Expand FadeScreenshotCommand and update the Duration In Seconds property.

      Screenshot of the FadeScreenshotCommand in the Inspector window

    Back to top
    Terms of use
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023