How do you access Hybrid components/objects after converting them using .AddHybridComponent()?

I am working on a Camera system in ECS. Of course there isn’t any pure, official DOTS camera yet, so I just associate the camera component with the DOTS world using conversionSystem.AddHybridComponent(theCamera) during conversion (see code below).

public class EpicCameraAuthoring : MonoBehaviour, IConvertGameObjectToEntity
{
  public Camera theCamera;

  public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
  {
    // Associate non-DOTS camera with DOTS components
    conversionSystem.AddHybridComponent(theCamera);

    // Add the component data here...
  }
}

According to 5argon’s post about Game Object Conversion, .AddHybridComponent will associate the object with the DOTS world, but that object is still in the “basic” Unity world, but with HideFlags.HideInHierarchy enabled. So technically the Camera still exists in the scene, but it is hidden in the editor.

With this, the camera converts fine, and all is happy. But, once this conversion is all set and done, I have no idea how to get the camera component so I can modify FOV and whatnot.

I’ve tried using FindObjectsOfType() in another MonoBehaviour well after conversion is done, but it returns with nothing! I’d expect that because the object is in the Hierarchy, one can get its GameObject using any GameObject querying tool.

Also because the Camera component is not technically and truly inside the ECS World, you can’t use GetComponentData(cameraEntity) because the Camera is not a component. There is only a Companion component that associates the Entity with the Camera GameObject. The Entity Debugger also shows no data associated with any of the Component tags/components! Accessing my once beloved Camera component remains more and more of a mystery to me!

So how are you supposed to access Hybrid objects (hidden objects) in a ECS context, and outside ECS contexts? When I mean “ECS context”, I mean inside systems. When I mean “outside ECS context”, I mean in something like a normal MonoBehaviour.

Use EntityManager.GetComponentObject

2 Likes

You can also use Hybrid components in Entities.ForEach

Hey,
first of all, you don’t need to do AddHybridComponent for your camera - it is already part of Hybrid Renderer - see HybridEntitiesConversion.cs. Notice though, this doesn’t work in subscenes, only with ConvertToEntity (see this thread: ECS Camera ). Now as all your cameras are added automatically as hybrid components you can do GetPrimaryEntity(yourCamera) and store the resulting entity id wherever you see fit. Later you take that entity id and do EntityManager.GetComponentObject(yourCameraEntity) to reach to that camera. You will have to do that on the main thread I believe, i.e. in a non-bursted loop.

1 Like

This is perfect, thank you! I can confirm that Camera does indeed not require a AddHybridComponent! Thats cool that Unity does it automagically.

For my project, I store the Camera’s entity using GetPrimaryEntity(myCamera) during conversion, and then access the data using EntityManager.GetComponentObject(myCameraEntity).

In the documentation for EntityManager.GetComponentObject(), there is no note about this function creating a Sync point. Is it true you cannot use it in a parallelized fashion? I am not able to test this at the moment with my current code.