How to instantiate an Entity at runtime? DOTS 1.0

Hi there, I am currently converting some of my code from gameobject conversion to the new Baker workflow. My previous approach was to convert a gameobject to an entity and use this master to make many copies in a job. It worked fine. Now with the new workflow, I have a subscene with the converted “baked” master entity. Now I am trying to replicate it by using a query to get this instance and EntityManager.Instantiate to make the copies. Contrary to expectation, the Entitymanager only copied the root entity without children, the child buffer component was missing as well.

How can I copy the whole structure?
Do I have to copy each entity individually now?
Should I better use the EntityCommandBuffer? (what I plan to do anyway)

I have a complex object, children with RenderMesh Component.

It is unclear to me, how to make many copies right now, without huge effort, may be some of you already figured out how to do it.

thanks in advance

I have now figured it out myself. Instead of converting the prefab with baker I pass it to him. So that an entity is created that holds the prefab, this can now be replicated easily.

1 Like

Can you describe the steps you need to do to “pass the prefab to a baker”

    • I want to know, too. Thank you

All you need to do is call GetEntity() on a prefab asset inside a baker. There is a simple example of this in the samples repo: https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/ECSSamples/Assets/HelloCube/4. Prefabs/SpawnerAuthoring.cs

Basic steps to use the sample script above:

  • Create a subscene if you don’t already have one (Right click scene in hierarchy and click “New Empty Subscene …”).
  • Create a new empty game object in the subscene to act as your spawner.
  • Attach the SpawnerAuthoring script to the game object.
  • Change the Prefab field to reference a prefab somewhere in your Assets folder.

Now at runtime, the spawner entity will have Spawner component with a reference to the baked entity prefab. This will automatically have the LinkedEntityGroup populated so that calls to EntityManager/EntityCommandBuffer.Instantiate() will also instantiate any children.

2 Likes

Any possible to way to do the same with a scene game object is different scene from baker? Right now I link the entities but it’s ugly.

Not sure I follow. Are you trying to associate an entity with a scene game object (often referred to as “hybrid”)? Or are you trying to clone a scene game object from a spawner entity? Or something else?

Yeah pretty much hybrid. But I don’t want to use a prefab as above but rather a game object in “main” scene (skinned mesh player) . I can’t cross reference so I have the main scene character read through all the subscene entities and match up the correct one. Sorry still probably confusing.

What I do is I make the game object a prefab.
Then in the subscene I reference the prefab on the “entity” but instead of storing a reference to the prefab entity, I store the reference to the GameObject prefab on a class IComponentData.

public class GameObjectRepresentation : IComponentData
{
    public GameObject Prefab;
}

In the baker add the component object to the entity :

        GameObjectRepresentation gor= new GameObjectRepresentation();
        gor.Prefab = authoring.Prefab;
        AddComponentObject(gor);

Then at runtine, you can instantiate the game object in a system :

public partial struct GoSpawnerSystem : ISystem
{
    public void OnCreate(ref SystemState state)
    {
    }

    public void OnDestroy(ref SystemState state)
    {
    }

    public void OnUpdate(ref SystemState state)
    {
        foreach (var gor in SystemAPI.Query<GameObjectRepresentation>())
        {
            GameObject.Instantiate(gor.Prefab);
        }    
    }
}

We used to have Struct CopyTransformFromGameObject | Entities | 0.51.1-preview.21
or Class CopyTransformToGameObjectSystem | Entities | 0.51.1-preview.21
to synch the position of entity and game object but that seem to be gone so you’ll have to do it yourself I guess.

2 Likes

Yeah, there really isn’t a great option for a hybrid workflow in 1.0. Like @WAYNGames mentioned, you can simply move that skinned mesh character to a prefab and then GameObject.Instantiate it at runtime. Other options include instantiating an entity at runtime from a MonoBehaviour. But both of these options have the downside of not letting your game object reference other things in the scene.

To get around that, you need to manually find and link your scene game objects and entities like you are doing. I’m using a custom tagging solution to tag the game object and then find it at runtime in a system and link it to an entity. Its ugly but it works. For “singleton” types of use cases, you can also just store the game object reference in a static variable and access it from systems.

FWIW: I’ve asked unity to consider improvements to hybrid in this thread: https://discussions.unity.com/t/896467

2 Likes

@WAYNGames
@scottjdaley

Do you have any updates on this topic? I want to do something similar. I’ve just updated from an older version. For context, all the prefabs are not in the project. They are dynamically added by the user. This means I can’t create any authoring/baking system.

I’m looking at CreateEntity with the CommandBuffer, similar to the way I was instancing all the entities previously, but it looks like it’s not supported anymore. (A GameObject with dynamically generated elements to be transformed into an entity at runtime, which I would need to be instantiated on the DOTS)

Only the existence of the content management API.

You may be able to make use of it for your users to build their content using Unity and host it from their side.
Then your game could provide a way to load that from in-game.

It isn’t quite a solution since the players aren’t Unity3d users, and they do not create the actual prefab. They just upload the data in a CMS from which they can select model/texture/animation/music at runtime based on what they need. Previously we used Mesh/Matrix4x4 and the fields required/materials as archetype, and we filled a NativeArray with those instances at runtime and then convert them into entities. I will look more into it and come back with a solution, if any.

I don’t think there will be any solution that fit your need directly from unity.

It would probably be a good idea to look into entities graphics. I not very familiar with it but there are stuff like material properties or override that could interest you.

I think the safest approach is to create base entities prefabs at game startup. And when loading let’s say data from json, at runtime, or other method alike, use these prefabs, to create actual prefab entities, using entity manager. Then instantiate them.