03 — Aspects¶
Bundled component access via aspects. Instead of declaring individual component parameters, aspects group related read/write operations into a single reusable struct.
Source: Samples/03_Aspects/
What It Does¶
Boids (simple agents) move in straight lines and wrap around the edges of a bounded area. Their GameObjects are rotated to face the direction of movement.
Schema¶
Components¶
Position, Velocity, Speed, GameObjectId from Common.
Tags & Template¶
public struct Boid : ITag { }
public partial class BoidEntity : ITemplate, IHasTags<SampleTags.Boid>
{
public Position Position = Position.Default;
public Velocity Velocity;
public Speed Speed;
public GameObjectId GameObjectId;
}
Systems¶
BoidMovementSystem¶
Defines an aspect and uses it for iteration:
public partial class BoidMovementSystem : ISystem
{
public void Execute()
{
foreach (var boid in Boid.Query(World).MatchByComponents())
{
boid.Position += World.DeltaTime * boid.Speed * boid.Velocity;
}
}
partial struct Boid : IAspect, IRead<Velocity, Speed>, IWrite<Position> { }
}
The Boid aspect provides:
ref readonly float3 Velocity(read-only, unwrapped fromVelocitycomponent)ref readonly float Speed(read-only, unwrapped fromSpeedcomponent)ref float3 Position(read-write, unwrapped fromPositioncomponent)
BoidWrapSystem¶
Wraps boids that go out of bounds. Uses [ExecutesAfter] to run after movement:
[ExecutesAfter(typeof(BoidMovementSystem))]
public partial class BoidWrapSystem : ISystem
{
readonly float _halfSize;
public BoidWrapSystem(float areaSize)
{
_halfSize = areaSize / 2f;
}
[ForEachEntity(MatchByComponents = true)]
void Execute(in Boid boid)
{
ref var p = ref boid.Position;
if (p.x > _halfSize) p.x -= _halfSize * 2;
else if (p.x < -_halfSize) p.x += _halfSize * 2;
if (p.z > _halfSize) p.z -= _halfSize * 2;
else if (p.z < -_halfSize) p.z += _halfSize * 2;
}
partial struct Boid : IAspect, IWrite<Position> { }
}
BoidRendererSystem (Variable Update)¶
Reads position and velocity to update the GameObject transform and face the movement direction.
Concepts Introduced¶
- Aspects —
partial structimplementingIAspect,IRead<T>,IWrite<T> [Unwrap]components expose their inner value type through aspect properties- Multiple aspects per system — different systems can define different aspect views over the same components
- Read vs Write —
IRead<T>providesref readonly,IWrite<T>providesref