0

我一直在考虑使用扩展方法和一次性单例类对 Unity ECS 进行一些封装,以保留对 BlobAssetStore 或 EntityManager 等公共资源的引用,类似于此草案:

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);
    }
}

您如何看待这种做法?

4

1 回答 1

1

优点:

  • 都在一个地方,如果升级(比如 World.Active 变成 World.DefaultGameObjectInjectionWorld 并且设置工厂不再接受 null 作为 BlobAssetStore),您需要在一个地方进行更改

  • 更简洁的语法,见用法:

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

缺点:

  • 增加复杂性

  • 所有团队成员都必须意识到这一点

于 2020-04-19T20:42:40.473 回答