I was wondering what the best way is to combine monobehavior components and ECS components on the same object? For example, I’d like to attach authoring components to a gameobject and have them be converted to ECS components on an entity automatically at runtime, instead of converting an entire gameobject to an entity through the use of sub-scenes.
The way I’m currently handling this is to have the objects start off as entities, associate them with a gameobject prefab, and instantiate that prefab and link the two together.
A simple way to do this is to have a prefab managed component on the entity, which holds a reference to a GameObject prefab and a GameObject instance, and on the spawned GameObject I have an EntityLink monobehavior which holds a reference to the entity.
This looks roughly as follows:
public class CPrefab : IComponentData {
public GameObject prefab;
public GameObject instance;
}
public class PrefabAuthoring : MonoBehavior {
public GameObject prefab;
public class Baker : Baker<PrefabAuthoring> {
public override void Bake(PrefabAuthoring authoring) {
Entity entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponentObject(entity, new CPrefab() { prefab = authoring.prefab });
}
}
}
public partial struct HybridSystem : ISystem {
public void OnUpdate(ref SystemState state) {
foreach ((CPrefab p, Entity e) in SystemAPI.Query<CPrefab>().WithEntityAccess()) {
p.instance = GameObject.Instantiate(p.prefab);
p.instance.GetComponent<EntityLink>().entity = e;
}
}
}
public class EntityLink : MonoBehavior {
public Entity entity;
}
There’s a number of extra steps you can take here, such as feeding LocalToWorld.Position and LocalToWorld.Rotation into the game object’s transform, having another system which keeps the transforms in sync, or storing the instance in a separate component if you want your systems to be able to specifically query for that.
But basically the above opens the door to hybrid entities.
P.S. You also have to be mindful about when the systems run - for instantiation I’ve found the end of InitializationSystemGroup to be the most sensible.