Search Unity

Question No ConvertGameObjectHierarchy (replacement strategy required)

Discussion in 'Graphics for ECS' started by sstrong, Mar 15, 2023.

  1. sstrong

    sstrong

    Joined:
    Oct 16, 2013
    Posts:
    2,251
    I've read runtime conversion is removed in ECS 1.0 after working so well for us for several years. Hybrid rendering has been renamed Entities.Graphics which includes component and API name changes etc.

    At runtime, we select from a number of prefabs and convert them to Entities at runtime. We've read that runtime conversion is "almost never necessary". However, we cannot find any way round runtime generation. We're probably overlooking something.

    Here is a snippet of one of our runtime conversion scenarios.

    Code (CSharp):
    1. public Transform[] obstaclePrefabs;
    2. public int obstacles = 2500;
    3. public World asteroidWorld;
    4. public List<EntityArchetype> asteriodEntityArchetypeList;
    5. public List<Entity> asteriodPrefabEntityList;
    6. public AsteroidSystem asteroidSystem;
    7. private BlobAssetStore blobAssetStore;
    8.  
    9. // Cutdown simplified version
    10. public void Initialise()
    11. {
    12.     int numObstaclePrefabs = obstaclePrefabs == null ? 0 : obstaclePrefabs.Length;
    13.  
    14.     blobAssetStore = new BlobAssetStore();
    15.     GameObjectConversionSettings conversionSettings = GameObjectConversionSettings.FromWorld(asteroidWorld, blobAssetStore);
    16.  
    17.     for (int pfIdx = 0; pfIdx < numObstaclePrefabs; pfIdx++)
    18.     {
    19.         //..
    20.      
    21.         Entity prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(obstaclePrefabs[pfIdx].gameObject, asteroidWorld);
    22.  
    23.  
    24.         asteriodPrefabEntityList.Add(prefabEntity);
    25.      
    26.         ComponentType[] archetypeComponentTypeArray = new ComponentType[4];
    27.      
    28.       archetypeComponentTypeArray[0] = typeof(Translation);
    29.       archetypeComponentTypeArray[1] = typeof(Rotation);
    30.       archetypeComponentTypeArray[2] = typeof(Asteroid);
    31.  
    32.       // NOTE: Requires hybrid renderer
    33.       archetypeComponentTypeArray[3] = typeof(RenderMesh);
    34.    
    35.       EntityArchetype entityArcheType = asteroidWorld.EntityManager.CreateArchetype(archetypeComponentTypeArray);
    36.       asteriodEntityArchetypeList.Add(entityArcheType);
    37.     }
    38.  
    39.     //...
    40.  
    41.     asteroidSystem = asteroidWorld.GetOrCreateSystem<AsteroidSystem>();
    42. }
    What options are available to replace runtime prefab conversion? So far, I've not been able to find any coding examples that demonstrate how we could do this.

    We don't use subscenes.
    At runtime we have a mixture of gameobjects with regular monobehaviours and entities in our scenes.
     
    HiddenTess likes this.
  2. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    I think there are at least two potential strategies:
    • If your prefabs are normal Unity prefabs, you should be able to use a Baker class to bake those Prefabs into Entity Prefabs (which are Entities with a Prefab tag). Entity Prefabs can be instantiated efficiently at runtime using the Instantiate method. I think this requires placing the spawner object in a subscene so that it can request baking for the prefabs, but the rendered entities can be instantiated at runtime as you want.
    • You can also create an Entity completely procedurally at runtime, and mark it as an Entity Prefab by adding the Prefab tag. In order to make the Entity renderable, there is the RenderMeshUtility.AddComponent method which you can use to add all the required components. After you have created a custom Entity Prefab in this manner, you can use the Instantiate method to efficiently make copies of it.
     
    sstrong likes this.
  3. sstrong

    sstrong

    Joined:
    Oct 16, 2013
    Posts:
    2,251
    Thanks very much for the response.

    It "seems" like I probably want to explore option 2 so long as I can attach my existing meshes from the "regular" prefabs.

    I also have prefab spaceships that can get instantiated at runtime (regular gameobjects with monobehaviours) that can have multiple weapon projectile types. These projectile types are currently converted at runtime to entities. I'm assuming that these fit the (second) procedural option too.

    With fairly simple objects (like asteroids and projectiles), without testing, I'm assuming that these can be procedurally created at runtime and suit this approach. Are there reasons why this approach wouldn't work (or shouldn't be used) for more complex objects?
     
  4. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    I don't think there should be any significant downsides besides having to maintain your own entity creation code.

    The important part is to try to minimize structural changes, so whenever possible you should create your Entity prefabs so that they will always have all their components present in the prefab. It's cheap to modify the value of a component, but more costly to add more components to the entity after instantation.