Encapsulation of Unity ECS using extension methods and singleton class, what do you think?

351 Views Asked by At

I've been thinking about some encapsulation of Unity ECS using extension methods and disposable singleton class for keeping references to common resources like BlobAssetStore or EntityManager, something like this draft:

public class EntityComponentSystemResources : IDisposable
{
    public readonly BlobAssetStore Store = new BlobAssetStore();
    public readonly EntityManager EntityManager = World.DefaultGameObjectInjectionWorld.EntityManager;

    private static EntityComponentSystemResources instance = new EntityComponentSystemResources();
    public static EntityComponentSystemResources Singleton => instance ?? new EntityComponentSystemResources();

    public void Dispose()
    {
        Store.Dispose();
        instance = null;
    }
}

public static class EntityExtensionMethods
{
    public static Entity ToEntity(this GameObject gameObject)
    {
        var settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, EntityComponentSystemResources.Singleton.Store);
        var entity = GameObjectConversionUtility.ConvertGameObjectHierarchy(gameObject, settings);
        return entity;
    }

    public static void SetComponentData<T>(this Entity entity, T data) where T : struct, IComponentData
    {
        EntityComponentSystemResources.Singleton.EntityManager.SetComponentData(entity, data);
    }

    public static void SetSharedComponentData<T>(this Entity entity, T data) where T : struct, ISharedComponentData
    {
        EntityComponentSystemResources.Singleton.EntityManager.SetSharedComponentData(entity, data);
    }

    public static void SetPosition(this Entity entity, float3 position)
    {
        SetComponentData(entity, new Translation { Value = position });
    }

    public static void SetRotation(this Entity entity, quaternion rotation)
    {
        SetComponentData(entity, new Rotation { Value = rotation });
    }

    public static Entity Instantiate(this Entity entity)
    {
        return EntityComponentSystemResources.Singleton.EntityManager.Instantiate(entity);
    }
}

What do you think of such an approach?

1

There are 1 best solutions below

0
On

Pros:

  • All in one place, in case of an upgrade (like when World.Active became World.DefaultGameObjectInjectionWorld and settings factories no longer accept null as BlobAssetStore) you need to make a change on one place

  • More concise syntax, see usage:

var sourceEntity = gameObject.ToEntity();
var instance = sourceEntity.Instantiate();
instance.SetPosition(new float3(1,2,3));

Cons:

  • Adds complexity

  • All team members must be aware of it