Skip to content

Latest commit

 

History

History
109 lines (70 loc) · 10.4 KB

File metadata and controls

109 lines (70 loc) · 10.4 KB

Systems

A system is a unit of code which belongs to a world and which runs on the main thread (usually once per frame). Normally, a system will only access entities of its own world, but this is not an enforced restriction.

🕹 See example systems.

A system is defined as a struct implementing the ISystem interface, which has three key methods:

ISystemState method Description
OnUpdate() Normally called once per frame, though this depends upon the SystemGroup to which the system belongs.
OnCreate() Called before the first call to OnUpdate and whenever a system resumes running.
OnDestroy() Called when a system is destroyed.

A system may additionally implement ISystemStartStop, which has these methods:

ISystemStartStop method Description
OnStartRunning() Called before the first call to OnUpdate and after any time the system's Enabled property is changed from false to true.
OnStopRunning() Called before OnDestroy and after any time the system's Enabled property is changed from true to false.

System groups and system update order

The systems of a world are organized into system groups. Each system group has an ordered list of systems and other system groups as its children, so the system groups form a hierarchy, which determines the update order. A system group is defined as a class inheriting from ComponentSystemGroup.

When a system group is updated, the group normally updates its children in their sorted order, but this default behavior can be overridden by overriding the group's update method.

A group's children are re-sorted every time a child is added or removed from the group.

The [UpdateBefore] and [UpdateAfter] attributes can be used to determine the relative sort order amongst the children in a group. For example, if a FooSystem has the attribute UpdateBefore(typeof(BarSystem))], then FooSystem will be put somewhere before BarSystem in the sorted order. If, however, FooSystem and BarSystem don't belong to the same group, the attribute is ignored. If the ordering attributes of a group's children create a contradiction (e.g. A is marked to update before B but also B is marked to update before A), an exception is thrown when the group's children are sorted.


Creating worlds and systems

By default, an automatic bootstrapping process creates a default world with three system groups:

  • InitializationSystemGroup, which updates at the end of the Initialization phase of the Unity player loop.
  • SimulationSystemGroup, which updates at the end of the Update phase of the Unity player loop.
  • PresentationSystemGroup, which updates at the end of the PreLateUpdate phase of the Unity player loop.

Automatic bootstrapping creates an instance of every system and system group (except those with the [DisableAutoCreation] attribute). These instances are added added to the SimulationSystemGroup unless overridden by the [UpdateInGroup] attribute. For example, if a system has the attribute UpdateInGroup(typeof(InitializationSystemGroup))], then the system will be added to the InitializationSystemGroup instead of the SimulationSystemGroup.

The automatic bootstrapping process can be disabled with scripting defines:

Scripting define Description
#UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_RUNTIME_WORLD Disables automatic bootstrapping of the default world.
#UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_EDITOR_WORLD Disables automatic bootstrapping of the Editor world.
#UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP Disables automatic bootstrapping of both the default world and the Editor world.

When automatic bootstrapping is disabled, your code is responsible for:

  • Creating any worlds you need.
  • Calling World.GetOrCreateSystem<T>() to add the system and system group instances to the worlds.
  • Registering top-level system groups (like SimulationSystemGroup) to update in the Unity PlayerLoop.

Alternatively, automatic bootstrapping can be customized by creating a class that implements ICustomBootstrap.


Time in worlds and systems

A world has a Time property, which returns a TimeData struct, containing the frame delta time and elapsed time. The time value is updated by the world's UpdateWorldTimeSystem. The time value can be manipulated with these World methods:

World method Description
SetTime Set the time value.
PushTime Temporarily change the time value.
PopTime Restore the time value from before the last push.

Some system groups, like FixedStepSimulationSystemGroup, push a time value before updating their children and then pop the value once done updating.


SystemState

A system's OnUpdate(), OnCreate(), and OnDestroy() methods are passed a SystemState parameter. SystemState represents the state of the system instance and has important methods and properties, including:

Method or property Description
World The system's world.
EntityManager The EntityManager of the system's world.
Dependency A JobHandle used to pass job dependencies between systems.
GetEntityQuery() Returns an EntityQuery.
GetComponentTypeHandle<T>() Returns a ComponentTypeHandle<T>.
GetComponentLookup<T>() Returns a ComponentLookup<T>.
⚠ IMPORTANT
Although entity queries, component type handles, and component lookups can be acquired directly from the EntityManager, it is generally proper for a system to only acquire these things from the SystemState instead. By going through SystemState, the component types accessed get tracked by the system, which is essential for the Dependency property to correctly pass job dependencies between systems. See more about jobs that access entities.

SystemAPI

The SystemAPI class has many static convenience methods, covering much of the same functionality as World, EntityManager, and SystemState.

The SystemAPI methods rely upon source generators, so they only work in systems and IJobEntity (but not IJobChunk). The advantage of using SystemAPI is that these methods produce the same results in both contexts, so code that uses SystemAPI will generally be easier to copy-paste between these two contexts.

📝 NOTE
If you get confused about where to look for key Entities functionality, the general rule is to check SystemAPI first. If SystemAPI doesn't have what you're looking for, look in SystemState, and if what you're looking for isn't there, look in the EntityManager and World.

SystemAPI also provides a special Query() method that, through source generation, helps conveniently create a foreach loop over the entities and components matching a query.