docs.unity3d.com
    Warning

    Warning: Unity Simulation is deprecated as of December 2023, and is no longer available.

    Pause and resume a simulation

    Simulations encapsulate a wide range of real world scenarios, which often involve unexpected situations. While the real world can't be paused in case a robot crashes into an object, or behaves unexpectedly, the Pause and Resume functionalities in Distributed Rendering allow users to pause the simulation at certain points in time.

    Usage

    FrameManager exposes Pause and Resume methods and properties via the singleton FrameManager.Instance.

    • Pause(): Sets the simulation Timescale and related properties to zero, effectively disabling the simulation. While paused, Distributed Rendering will not generate any new metaframes. Any pending metaframes will be dispatched.

    • Resume(): Un-pauses the simulation.

    • ClearQueues(): Removes any pending metaframes from all camera queues. This effectively fast-forwards the Clients to the current state of the scene as managed by the Server.

    • PauseUntil(Func): Pauses the simulation until the specified condition is satisfied.

    • SynchronizedRunStart(): Forces Clients to stay in sync with the Server. The Server will wait for each render node to complete the current frame before generating any new metaframes.

    • SynchronizedRunStop() Ends the synchronous run. The Server may run at full speed without waiting on Clients.

    The following code sample demonstrates these methods by adding various buttons that execute these methods. Attach this code to any game object in the scene before building.

    using UnityEngine;
    using UnityEngine.UI;
    using Unity.Simulation.DistributedRendering.Core;
    using UnityEngine.Events;
    
    public class SimulationControls : MonoBehaviour
    {
        #region UI Buttons
    
        public Button btnClearQueues;
        public Button btnPause;
        public Button btnNext;
        public Button btnPauseUntil;
        public Button btnRunSynchronous;
    
        #endregion
    
        // Start is called before the first frame update
        void Start()
        {
            Debug.Log($"Initializing {nameof(SceneControls)}");
    
            tryAddClick(btnPause, PauseResume);
            tryAddClick(btnNext, SingleStep);
            tryAddClick(btnClearQueues, FrameManager.Instance.ClearQueues);
            tryAddClick(btnRunSynchronous, RunSynchronous);
    
        }
    
        private void tryAddClick(Button button, UnityAction handler)
        {
            if (null != button)
                button.onClick.AddListener(handler);
        }
    
        /// <summary>
        /// Remove any pending metaframes from all camera queues. 
        /// </summary>
        void ClearQueues() => FrameManager.Instance.ClearQueues();
    
        /// <summary>
        /// Pause or resume the simulation
        /// </summary>
        public void PauseResume()
        {
            if (FrameManager.Instance.IsPaused)
                FrameManager.Instance.Resume();
            else
                FrameManager.Instance.Pause();
    
            /// uncomment this line to fast-forward render nodes to the current frame on the next iteration
            //_drSystem.ClearQueues();
            Debug.Log($"{nameof(SceneControls)}.Pause {FrameManager.Instance.IsPaused}");
        }
    
        /// <summary>
        /// Dispatch the next pending metaframe to all clients. Pause immediately after. 
        /// </summary>
        public void SingleStep()
        {
            FrameManager.Instance.RunOneFrame();
            /// See also:
            /// _drSystem.PauseUntil(Func<bool>...)
            /// unpause the system for one frame. 
        }
    
        private bool _isRunningSynchronous;
        public void RunSynchronous()
        {
            _isRunningSynchronous = !_isRunningSynchronous;
    
            if (_isRunningSynchronous)
            {
                SetButtonText("btnRunSynchronous", "Synchronized: Running");
                FrameManager.Instance.SynchronizedRunStart();
            }
            else
            {
                SetButtonText("btnRunSynchronous", "Run Synchronous");
                FrameManager.Instance.SynchronizedRunStop();
            }
        }
    
        private void SetButtonText(string buttonName, string newText)
        {
            var t = GameObject.Find(buttonName).GetComponentInChildren<Text>(true);
            t.text = newText;
        }
    }
    
    In This Article
    • Usage
    Copyright © 2023 Unity Technologies
    • 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.