Using SubScenes like Prefabs

I’ve found SubScenes to be really useful. Having a pre-converted, or pure data representation, of objects is awesome, especially to the fact its integrated with Live Link (see 5argons article to learn more about how SubScene operates currently, and why it can be so useful). I’ve personally found SubScenes to be especially amazing, because you do not need a parent object to hold multiple, related objects (prefabs need a parent object to be considered “one” prefab. This can be annoying when dealing with ECS prefab instantiation).

I noticed when duplicating a sub scene that “multiple, identical sub scenes are not supported.” That certainly shows sub scenes are intended for environments, where duplication is not a necessity. (In a side note, is it possible to spawn a singular SubScene via a script?)

With all that said, having a spawn-able, pure-data, pre-converted prefab (not scene) that could sync between clients would be certainly amazing. Is there planned support for using SubScenes like prefabs (spawn-able, duplicatable)? Or instead, a pure-data, pre-converted representation of prefabs?

5 Likes

Yeah, I would love it. In the game I am currently working on I have a huge procedurally generated levels and storing them as a prefabs currently just isn’t working because the GameObject->Entity conversion on level spawn takes forever. Spawnable SubScenes would solve so many problems for me

1 Like

You could create a “gameplay” subscene where all of your ECS gameplay related data is defined. This allows you to then also include prefabs which will be converted upfront and loaded with the subscene instead of only converted on instantiation.

3 Likes

+1 on this, it’s pretty much what I’m planning on doing (and partially implemented). You build a map storing a “game type name/id” to prefab entityId and expose it for example as a singleton. Whenever you want to spawn a “prefab” you refer it by name/id and then look up in this table what the entityId for the converted prefab is.

What I’m not sure on yet is how to guarantee subscene loading order, so this loads before other subscene that might reference this data (for dynamic instantiation)?

3 Likes

I’d argue to not have the prefab instantiation process be too complex. If you’re building something like a random spawner let it just maintain a list of the prefabs it needs. The key thing to be aware of though is it could happen that your subscene has been unloaded, you make changes to some of your prefabs and those changes aren’t applied correctly to the subscene’s binary representation. I’ll have to experiment a little more myself, but I’m seeing more and more value in breaking things into subscenes instead of adding the whole convert-to-entity component into the mix.

1 Like

Currently I rewriting our RTS core part (which responsible for data preloading and management) and I’m using SO’s with AssetReference to GO prefab (and icon for UI) and some utility fields like frinedly name and description (we now support Addressables in our DOTS RTS) for better (and asych) data loading and memory management, i’m loading prefabs asynchronous now, collect list of prefabs for conversion, and creates hidden converter GO which implements IDeclareReferencedPrefabs, and in Convert iterates through prefabs list and store them in global ID<->Entity map which stored on singletone storage entity (with other SO things which not require conversion), and also on corvesion this prefabs has special authorings which converts shared mutable data to blobs and attach special component with blob asset references and unique ID to this blob in ID<->BAR map, also store unique meshes and material in another global map and this maps always deterministic. All works like a charm. And with this logic I can (and do) easily serialize\deserialize my game (for saving\loading game). I just copy all entities from default world to saving world and call couple of preprocessing systems which removes trash and all ISCD\Components with BlobAssetReference from instanced from entity prefabs and replaces them to ICD with ID to mesh\material\blob thus I can serialize Saving World directly in to binary file without any referenced objects. And on load I deserialize this binary file to empty Saving World, again call couple of postprocessing systems which replaces ICD with ID to mesh\material\blob related to this ID (mesh\material\blob\prefab maps already populated at this moment, because it happens only once at application start, and it’s fast and not stall main thread, because of asynch AsserReference loading in Addressables) and just move this entities to default world and all game progress restored from moment I saved it. And we can easy change meshes, materials, blobs data which used in our game (in dlc\patch for example) and it’s not corrupt our saves, because we not serialize\deserialize them with world (we remap them before serialization\deserialization) and our saves will use always up to date meshes\materials\blobs

8 Likes

Does it mean that all your prefabs from SO already loaded? If so do you use asset loading/unloading during game?

Well in our case it wouldn’t make sense as all prefab preconverted at application startup and thus there always will be entity (prefab) using assets :slight_smile: but anyway, thats acceptable memory waste for us, as we don’t want to run runtime conversion more than once (at startup), and it’s not so big chunk of memory in persistent use.

2 Likes