docs.unity3d.com
    Warning

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

    Controlling Time

    Overview

    One of the key advantages of simulation over physical testing is having control over the simulated passage of time. When physically testing, your testing speed is bound to the real time frequencies of the hardware, and can only advance as fast as the slowest component in the loop. In simulation, the clock can be advanced in a "just in time" fashion, allowing you to decouple the simulated time from the wall clock. Although Unity does not, by default, enable this sort of control, using the Clock Management tools in Simulation Foundation, a developer can take control of the game loop to custom tailor how simulated time passes to best fit their simulation needs.

    Quickstart

    This flowchart should serve as a useful quick reference for those who have already familiarized themselves with how Unity's game loop handles Update scheduling. Note that for any use case, we assume you have created a GameObject called SimulationClock for the purposes of managing your simulation's clock. The naming and organization of this GameObject can be changed to personal taste, as long as you have the requisite MonoBehaviours attached to support your use case. This quickstart diagram is left at the top of the page for ease of access, but it assumes you are familiar with the concepts explained in the subsequent sections below the chart.

    4384

    Please ensure that, if you intend to take control of simulation time, your simulation scene contains exactly one TimeStepApplier. When your simulation starts, the TimeStepApplier will immediately disable any automatic physics simulation and set the TimeScale to zero, guaranteeing that components in the scene will receive a Time.deltaTime value of zero when their Update functions are called. For a course overview on how and which Clock Management components are relevant to your simulation, see the sections below. For a closer look at how each of the Clock Management components work, refer to the Usage page.

    Determining the Time Authority

    If your stack was designed without any special consideration given to clock management, it likely uses its operating system as the source of truth for current time, also known as the "wall clock" (in reference to where one might normally hang a physical clock). This is effectively the default configuration for most systems as it is the default behavior for most standard time libraries. It is also not ideal for testing in simulation, as the system clock cannot be sped up or slowed down. To fully take advantage of a simulated clock, any code that directly polls the system clock to determine current time will need to be rewritten to do one of the following:

    • Use a clock abstraction layer like the ROS Clock libraries
    • Infer time from the timestamps on the messages it consumes
    • Accept time updates from a centralized, designated time authority (in real-time or embedded systems this is sometimes referred to as the "system tick," or simply a "scheduler")

    Once a system is architectured to infer time from a shared source of truth, it can then be integrated with Unity's Clock Management features to enable testing at speeds faster or slower than real time. Unity can be configured to accept clock updates from another time authority in the system - like a scheduler (external clock) - or configured to publish clock updates whenever its internal simulation steps forward (internal clock). The former - external clock - is ideal if the processes in your control stack abide by rigid timing constraints or you wish to test your scheduler itself as part of your testing loop. The latter is ideal if you simply want the simulation to run as fast as possible, especially if you expect the amount of real time it takes your real sensors to capture and publish data to be substantially different than the time the simulated sensors need.

    External Clock

    If your stack derives time from a scheduler-like component that cannot be easily decoupled from the rest of the system, you may want to configure Unity to accept time updates from your scheduler. To enable this functionality, you would add a ClockSubscriber Component to a GameObject in your Scene, and set it up to subscribe to the appropriate topic via the appropriate Connector. Whenever Unity receives a time update, it will compute the delta between the new time and its current simulation time - i.e. the Time Step - and apply that Time Step to its simulated Scene.

    This configuration is ideal when you expect Unity to use a negligible amount of computation time with respect to your whole system's update cycle, or your system is designed such that updates from sensors can be handled asynchronously so nothing needs to block to wait for Unity to finish simulating every step.

    Internal Clock

    If your system's default scheduler can be easily disabled, or you need to block control flow execution to wait for sensor data, the easiest way to streamline your simulation is to allow the simulator (Unity) to drive the clock. You can do so by adding a TimeStepScheduler and ClockPublisher to your Scene. By default, Unity will step time forward by the amount specified on the TimeStepScheduler, and ClockPublisher will automatically take care of publishing those updates to the specified Connector/topic.

    If you have other components in your stack that need the simulation to stop and wait for their work to complete, you can pass that information into Unity by writing a class which inherits from SchedulePausingBehaviour.

    Understanding the Components

    Everything in our suite of clock management features serves two purposes. First, they are the minimal viable set of needed features to enable a user to slow down or speed up simulation time. Second, they are boilerplate classes that can be extended by a user to better finetune how their simulation interacts with the stack being tested. For more in-depth information on how each class functions, please review the Usage guide.

    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.