Ok, I'm a little vexed by Singletons (and the various APIs that exist around them), and wonder how I can use them to share some data with Mono-Land and ECS-Land stuff alike, especially if there is state that is based on the presence of that data (other ECS systems have RequireForUpdate for that component)
Every sync point counts, right?
So assuming I have some UI that needs to grab some data from ECS to show in a UGUI or UIElements panel the name, entity, and some supplementary data on the entity... how do YOU communicate this out of ECS?
I've been using a singleton like this, but the creation / deletion code raises the hairs on the back of my neck as if there's something I'm just not seeing here that would be much better.
public partial struct InteractSystem : ISystem
{
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<BubbleCameraState>();
state.RequireForUpdate<PhysicsWorldSingleton>();
}
public void OnUpdate(ref SystemState state)
{
var physicsWorld = SystemAPI.GetSingleton<PhysicsWorldSingleton>();
var camData = SystemAPI.GetSingleton<BubbleCameraState>();
var camera = Cam.Instance.localCamera; //would like to replace screenpoint to ray from just the view matrix, found no equivalent in mathematics
var ray = camera.ScreenPointToRay(Mouse.current.position.ReadValue());
ray.origin = (float3) ray.origin + camData.virtualPosition;
var input = new RaycastInput
{
Filter = camData.filter, //candidate for refactoring, it's a complex filter, currently can't calculate that value here
Start = ray.origin,
End = ray.origin + ray.direction * (camera.farClipPlane-camera.nearClipPlane),
};
if (physicsWorld.CollisionWorld.CastRay(input, out var hit))
{
var interact = new Interact
{
entity = hit.Entity,
normal = hit.SurfaceNormal,
localPosition = hit.Position
};
if (!SystemAPI.HasSingleton<Interact>()) state.EntityManager.CreateEntity(typeof(Interact));
SystemAPI.SetSingleton(interact);
}
else if (SystemAPI.TryGetSingletonEntity<Interact>(out var entity))
{
state.EntityManager.DestroyEntity(entity);
}
}
Mono UI Code, in Update:
-> EntityManager.TryGetSingleton
(let's assume further data than the Interact component are not required)
Should I keep a managed singleton instead? How?