Creating a system
Implement the abstract class SystemBase to create an ECS system.
To create a system, you program the necessary system event callbacks. Use the SystemBase OnUpdate() function to perform the work your system must do every frame. The other callback functions are optional; for example, you can use OnCreate() to initialize a system, but not every system requires initialization code.
The system callback functions are invoked 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, which can be because you set Enabled to false or because it finds no entities matching its queries. Also called before OnDestroy().
- OnDestroy() -- when the system is destroyed.
A system's OnUpdate() function is triggered by its parent system group's own OnUpdate() function. Likewise, when a group changes state, for example if you set the group's Enabled property, it changes the state of its child systems. However, children can also change state independently from their parent groups. See System update order for more information.
All the system events run on the main thread. Ideally, your OnUpdate() function schedules jobs to perform most of the work. To schedule a job from a system, you can use one of the following mechanisms:
- Entities.ForEach -- the simplest way to iterate over ECS component data.
- Job.WithCode -- execute a lambda function as a single, background job.
- IJobEntityBatch -- a "lower level" mechanism for iterating over ECS component data chunk-by-chunk.
- C# Job System -- create and schedule general purpose C# jobs.
The following example illustrates using Entities.ForEach to implement a system that updates one component based on the value of another:
public struct Position : IComponentData
{
public float3 Value;
}
public struct Velocity : IComponentData
{
public float3 Value;
}
public partial class ECSSystem : SystemBase
{
protected override void OnUpdate()
{
// Local variable captured in ForEach
float dT = Time.DeltaTime;
Entities
.WithName("Update_Displacement")
.ForEach(
(ref Position position, in Velocity velocity) =>
{
position = new Position()
{
Value = position.Value + velocity.Value * dT
};
}
)
.ScheduleParallel();
}
}