In order for all participants in the session to see the same color changes, we'll show a simple implementation of ECS.
Updating the shared cube color After finishing the previous tutorials, you should have a project where users can join a shared AR session, create a primitive cube, and change the color of the cube by touching it with their hand, using Ur (hand tracker module). All the participants can see the cubes that other people created but will only see the color updates on the cubes touched by them. To change that, we will create a new component that will store the color data in the session and a system that will add and update the components and keep the color data locally. When a participant touches a cube, the color will be updated locally on that participant's device and a message will be broadcast to all other participants with the new color data.
Adding a Color Component and System Let's start by creating a color component and a color system .
Create a new ^ColorSystem^
C# class that inherits from ^SystemBase^
. ConjureKit will invoke the abstract methods defined in ^SystemBase^
.
public class ColorSystem : SystemBase
{
public ColorSystem (Session session) : base (session)
{
}
}
Declare a new component name.
// The unique name of the component
private const string COLOR_COMPONENT_NAME = "color" ;
And override the abstract method of SystemBase - ^GetComponentTypeNames^
to return the color component. This method is called by ConjureKit during initialization. The system is notified when components of the type reported by this method are updated or removed.
public override string[] GetComponentTypeNames ( )
{
return new [] {COLOR_COMPONENT_NAME};
}
To get a list of all components that other participants have updated, let's create an override method for The SystemBase Update method, ConjureKit invokes this method when the Hagall server broadcasts a component update. Using this method, we will update a local map of component data and trigger an event for each update.
So let's declare the map of component data as a Dictionary :
// Local Color component data map
private readonly IDictionary<uint, Color> _entityColorDataMap = new Dictionary<uint, Color>();
And the event we want to trigger on every update.
/// Triggered when a component data is updated by another participant
public event Action<uint, Color> OnColorComponentUpdated;
And finally, let's override the Update method.
public override void Update ( IReadOnlyList<(EntityComponent component, bool localChange)> updated )
{
foreach ( var (entityComponent, localChange) in updated)
{
// Update the local data and notify about the update
_entityColorDataMap[entityComponent.EntityId] = ByteArrayToColor(entityComponent.Data);
OnColorComponentUpdated?.Invoke(entityComponent.EntityId, _entityColorDataMap[entityComponent.EntityId]);
}
}