Class SystemBase
Implement SystemBase to create a system in ECS.
Inherited Members
Namespace: Unity.Entities
Assembly: solution.dll
Syntax
[RequireDerived]
public abstract class SystemBase : ComponentSystemBase
Remarks
Systems in ECS
A typical system operates on a set of entities that have specific components. The system identifies the components of interest, reading and writing data, and performing other entity operations as appropriate.
The following example shows a basic system that iterates over entities using a Entities.ForEach construction. In this example, the system iterates over all entities with both a Displacement and a Velocity component and updates the Displacement based on the delta time elapsed since the last frame.
public struct Position : IComponentData
{
public float3 Value;
}
public struct Velocity : IComponentData
{
public float3 Value;
}
[RequireMatchingQueriesForUpdate]
public partial class ECSSystem : SystemBase
{
protected override void OnUpdate()
{
// Local variable captured in ForEach
float dT = SystemAPI.Time.DeltaTime;
Entities
.WithName("Update_Displacement")
.ForEach(
(ref Position position, in Velocity velocity) =>
{
position = new Position()
{
Value = position.Value + velocity.Value * dT
};
}
)
.ScheduleParallel();
}
}
System lifecycle callbacks
You can define a set of system lifecycle event functions when you implement a system. The runtime invokes these functions in the following order:
- OnCreate() -- called when the system is created.
- OnStartRunning() -- before the first OnUpdate and whenever the system resumes running.
- OnUpdate() -- every frame as long as the system has work to do (see ShouldRunSystem()) and the system is Enabled.
- OnStopRunning() -- whenever the system stops updating because it finds no entities matching its queries. Also called before OnDestroy.
- OnDestroy() -- when the system is destroyed.
All of these functions are executed on the main thread. To perform work on background threads, you can schedule jobs from the OnUpdate() function.
System update order
The runtime executes systems in the order determined by their ComponentSystemGroup. Place a system in a group using UpdateInGroupAttribute. Use UpdateBeforeAttribute and UpdateAfterAttribute to specify the execution order within a group.
If you do not explicitly place a system in a specific group, the runtime places it in the default World SimulationSystemGroup. By default, all systems are discovered, instantiated, and added to the default World. You can use the DisableAutoCreationAttribute to prevent a system from being created automatically.
Entity queries
A system caches all queries created through an Entities.ForEach construction, through
ComponentSystemBase.GetEntityQuery, or through ComponentSystemBase.RequireForUpdate. By default,
a system calls OnUpdate()
every frame. You can use the RequireMatchingQueriesForUpdateAttribute
to make the system only update when one of these cached queries finds Entities. See
ShouldRunSystem() for more details on whether
a system will update.
Entities.ForEach and Job.WithCode constructions
The Entities property provides a convenient mechanism for iterating over entity data. Using an Entities.ForEach construction, you can define your entity query, specify a lambda expression to run for each entity, and either schedule the work to be done on a background thread or execute the work immediately on the main thread.
The Entities.ForEach construction uses a C# compiler extension to take a data query syntax that describes your intent and translate it into efficient (optionally) job-based code.
The Job property provides a similar mechanism for defining a C# Job. You can only use
Schedule()
to run a Job.WithCode construction, which executes the lambda expression as a single job.
System attributes
You can use a number of attributes on your SystemBase implementation to control when it updates:
- UpdateInGroupAttribute -- place the system in a ComponentSystemGroup.
- UpdateBeforeAttribute -- always update the system before another system in the same group.
- UpdateAfterAttribute -- always update the system after another system in the same group.
- RequireMatchingQueriesForUpdateAttribute -- skip
OnUpdate
if every EntityQuery used by the system is empty. - DisableAutoCreationAttribute -- do not create the system automatically.
- AlwaysSynchronizeSystemAttribute -- force a sync point before invoking
OnUpdate
.
Properties
Name | Description |
---|---|
CheckedStateRef | The SystemState for this SystemBase. |
Dependency | The ECS-related data dependencies of the system. |
Entities | Provides a mechanism for defining an entity query and invoking a lambda expression on each entity selected by that query. |
Job | Provides a mechanism for defining and executing an [IJob]. |
Methods
Name | Description |
---|---|
CompleteDependency() | Completes job handles registered with this system. See Dependency for more information. |
Exists(Entity) | Checks if the entity exists inside this system's EntityManager. |
GetBufferFromEntity<T>(bool) | Obsolete. Use GetBufferLookup<T>(bool) instead. |
GetBufferLookup<T>(bool) | Manually gets a BufferLookup<T> object that can access a DynamicBuffer<T>. |
GetBuffer<T>(Entity, bool) | Gets the dynamic buffer of an entity. |
GetComponentDataFromEntity<T>(bool) | Obsolete. Use GetComponentLookup<T>(bool) instead. |
GetComponentLookup<T>(bool) | Manually gets a dictionary-like container containing all components of type T, keyed by Entity. |
GetComponent<T>(Entity) | Look up the value of a component for an entity. |
GetEntityStorageInfoLookup() | Manually gets an EntityStorageInfoLookup object that can access a EntityStorageInfo. |
GetStorageInfoFromEntity() | Obsolete. Use GetEntityStorageInfoLookup() instead. |
HasBuffer<T>(Entity) | Checks whether an entity has a dynamic buffer of a specific IBufferElementData type. |
HasComponent<T>(Entity) | Checks whether an entity has a specific type of component. |
OnUpdate() | Implement |
SetComponent<T>(Entity, T) | Sets the value of a component of an entity. |
Update() | Update the system manually. |