Warning
Warning: Unity Simulation is deprecated as of December 2023, and is no longer available.
Clock Management Components
This page details the different ways our clock management Components can be configured to support a variety of use cases. This first section will give a brief explanation of what each Component does in isolation, and the following selections will detail how they can be used together to support specific cases.
TimestepApplier
TimeStepApplier is the core Component of our clock management features. Its job is to take control of the simulation clock and apply time steps only when requested by another Component in the simulation. All simulations will need exactly one TimeStepApplier to keep Unity from using the system's time (wallclock) as its time authority. This can be added to any object, but to keep things organized it is useful to create a SimulationClock GameObject meant specifically to hold this component and the others you need for your use case.
TimeStepScheduler
The TimeStepScheduler is responsible for telling the TimeStepApplier when it is appropriate to move simulated time forward. By default, it will simply step time forward by a fixed duration every time a Frame is rendered. However, when used in conjunction with PauseConditions, you can set up logic to determine when the simulation should wait for external processes instead of freely stepping forward every Frame.
IPauseCondition
This is a simple interface which, when implemented by any Component, will be automatically monitored by the TimeStepScheduler at runtime. A PauseCondition simply contains a flag called RequestsPause
that, when set to True, will pause the simulated clock.
ClockPublisher
As the name suggests, the ClockPublisher publishes clock. This class simply publishes clock messages to a user-specified topic whenever time moves forward in the simulation.
ClockSubscriber
Similar to the ClockPublisher, a ClockSubscriber instead listens for an external clock signal. Unlike ClockPublisher, ClockSubscriber has an additional responsibility: to pass clock updates to the TimeStepApplier. The ClockPublisher effectively replaces both the ClockPublisher and TimeStepScheduler - as a means by which simulated time can be stepped forward in simulation (via a signal external to Unity).
Configuring for your Use Case
Unity as the Time authority
Add a TimeStepScheduler
If Unity should control the simulation clock, you will need to add a scheduler as well in conjunction with the TimeStepApplier mentioned in the previous section. We've included a default scheduler implementation in our collection of ClockManagement components called TimeStepScheduler. It acts as an extension of the TimeStepApplier class, and for this reason it should be added to the same GameObject. Because TimeStepApplier is a required Component, on creation, TimeStepScheduler will add one if none exists on the current GameObject.
Using the TimeStepScheduler
The TimeStepScheduler is responsible for determining when time should move forward in simulation, and by how much. Physics steps will always occur on the fixed interval defined under Project Settings -> Time, but they will only occur in between Update steps where simulated time has passed, and will generally simulate much faster than real-time assuming the physics state of the system is not incredibly complex (think fluid dynamics or thousands of articulated graspers). For especially granular simulations, you may want to check the UseFixedDeltaAsTimeStep box in the TimeStepScheduler's inspector panel, which will ensure that everything in the system updates in lock-step with the physics updates. This is not recommended if you have cameras or sensors which are meant to capture data every single Update. By default, every frame the TimeStepScheduler will step time forward by the value specified by the TimeStep parameter. However, the simulation will automatically pause to wait for any PauseConditions the Scheduler is currently tracking, and will only continue when all PauseConditions are not blocking.
Using PauseConditions
If you want your simulation to halt until specific requirements are met, you may implement the IPauseCondition interface and place your implementations into your scene. These will be picked up by the TimeStepScheduler when the simulation starts and checked at every time step to determine whether or not the simulation clock can advance. For most cases, you should be able to inherit from SchedulePausingBehaviour, our default implementation, and override either the RequestsPause property and/or the UpdateState() method with your simulation-specific logic. While RequestsPause is true, simulated time will not advance, and UpdateState() will be invoked by the TimeStepScheduler after every time step, giving you the opportunity to evaluate whether to reset RequestsPause to true immediately, or wait for future Update events from Unity.
Publishing clock
Add/Use the ClockPublisher
To publish time to processes external to Unity, add a ClockPublisher to the scene. The ClockPublisher will use Unity's standard Time APIs to determine how much time has passed, and publish a clock message whenever Time.deltaTime is greater than zero. This can be used regardless of whether or not Unity is tracking wall clock or simulating time. No changes are needed in the ClockPublisher to support either situation; it will do whichever by default.
Tell other components to follow the Clock topic
Applications outside of Unity may need to be told not to follow wall clock and instead subscribe to the clock topic. For most ROS packages, for example, you will need to set the rosparam use\_sim\_time
to True
for nodes to follow the signal published to the clock topic, /clock. What exact configuration is required will depend on your software stack.
Unity with an External Time Authority
In this scenario, Unity subscribes to an external clock signal, and only steps its simulation in accordance with the time delta reported by the clock source.
Add a ClockSubscriber
When Unity was the time authority, we added a TimeStepScheduler. However, when Unity is meant to follow an external clock signal, we add instead a ClockSubscriber. The ClockSubscriber listens for Time messages published on whatever topic is specified by the ClockTopic parameter. Similar to the TimeStepScheduler, when added to a GameObject in the scene, if a TimeStepApplier is not already present, one will be added for you, and any other TimeStepAppliers in the scene will be disabled.
Using the ClockSubscriber
Adding the ClockSubscriber to your scene is sufficient to force your simulation to follow an external clock signal. If you expect your clock signal to publish small (less than 100ms) intervals, you may want to enable the SyncPhysicsToClockDelta
variable, which will ensure each update received is not sub-divided when applied on the physics thread. If the time intervals published by your clock signal provider or greater than 100ms, we recommend not checking SyncPhysicsToClockDelta
as the large jumps in simulated time may cause extrapolation errors in the physics sim.