Search Unity

New SubScene & ConvertToEntity workflows

Discussion in 'Data Oriented Technology Stack' started by Joachim_Ante, Mar 4, 2019.

  1. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,279
    ah, it landed already, need to put this on your manifest:
     
  2. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    202
    I just upgraded, and the old conversion workflow doesn't work anymore of course, but figuring out the current one is somewhat complex it seems;

    Code (csharp):
    1. manager = World.Active.EntityManager;
    2. asteroidEntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(asteroidPrefab, World.Active);
    I'd use to use that to convert an asteroid prefab to an entity prefab and spawn a whole bunch of those. But since World.Active is deprecated/removed that doesn't work anymore. Trying to figure out how to assign and then convert prefabs.
     
  3. Monguskan

    Monguskan

    Joined:
    Jan 2, 2013
    Posts:
    4
    I just update Entities to preview.18 0.2.0 and I notice the following things compared with preview.0.1.1
    • On version 0.1.1 was a MonoBehaviour that control GameObject conversion.
    • On version 0.2.0 is a MonoBehaviour that injects information into a ComponentSystem that executes the conversion.
    • On version 0.1.1 "Convert and inject" creates an entity with all of its components, without destroying the GameObject original reference.
    Code (CSharp):
    1. public static bool InjectOriginalComponents(World srcGameObjectWorld, EntityManager simulationWorld, Transform transform)
    2.         {
    3.             var convert = transform.GetComponent<ConvertToEntity>();
    4.             if (convert != null && convert.ConversionMode == Mode.ConvertAndInjectGameObject)
    5.             {
    6.                 var entity = GameObjectConversionUtility.GameObjectToConvertedEntity(srcGameObjectWorld, transform.gameObject);
    7.                 InjectOriginalComponents(simulationWorld, entity, transform);
    8.                 transform.parent = null;
    9.                 return true;
    10.             }
    11.      
    12.             for (int i = 0; i < transform.childCount;)
    13.             {
    14.                 if (!InjectOriginalComponents(srcGameObjectWorld, simulationWorld, transform.GetChild(i)))
    15.                     i++;
    16.             }
    17.             return false;
    18.         }

    • On version 0.2.0 "Convert and inject" does the same, but at the end destroys the GameObject reference and as a consequence, the entire hierarchy is destroyed too.
    Code (CSharp):
    1. void Convert()
    2.         {
    3.             var toBeDetached = new HashSet<Transform>();
    4.             var toBeDestroyed = new HashSet<GameObject>();
    5.  
    6.             try
    7.             {
    8.                 var toBeInjected = new List<Transform>();
    9.  
    10.                 foreach (var convertToWorld in m_ToBeConverted)
    11.                 {
    12.                     var toBeConverted = convertToWorld.Value;
    13.  
    14.                     var settings = new GameObjectConversionSettings(
    15.                         convertToWorld.Key,
    16.                         GameObjectConversionUtility.ConversionFlags.AssignName);
    17.                    
    18.                     settings.BlobAssetStore = BlobAssetStore;
    19.  
    20.                     using (var gameObjectWorld = settings.CreateConversionWorld())
    21.                     {
    22.                         toBeConverted.RemoveAll(convert =>
    23.                         {
    24.                             var parent = convert.transform.parent;
    25.                             var remove = parent != null && parent.GetComponentInParent<ConvertToEntity>() != null;
    26.                             if (remove && parent.GetComponentInParent<StopConvertToEntity>() != null)
    27.                             {
    28.                                 LogWarning(
    29.                                     $"{nameof(ConvertToEntity)} will be ignored because of a {nameof(StopConvertToEntity)} higher in the hierarchy",
    30.                                     convert.gameObject);
    31.                             }
    32.  
    33.                             return remove;
    34.                         });
    35.  
    36.                         foreach (var convert in toBeConverted)
    37.                             toBeDestroyed.Add(convert.gameObject);
    38.  
    39.                         foreach (var convert in toBeConverted)
    40.                             AddRecurse(gameObjectWorld.EntityManager, convert.transform, toBeDetached, toBeInjected);
    41.  
    42.                         GameObjectConversionUtility.Convert(gameObjectWorld);
    43.  
    44.                         var mappingSystem = gameObjectWorld.GetExistingSystem<GameObjectConversionMappingSystem>();
    45.                         foreach (var convert in toBeInjected)
    46.                             InjectOriginalComponents(mappingSystem, convert);
    47.                     }
    48.  
    49.                     toBeInjected.Clear();
    50.                 }
    51.             }
    52.             finally
    53.             {
    54.                 m_ToBeConverted.Clear();
    55.  
    56.                 foreach (var transform in toBeDetached)
    57.                     transform.parent = null;
    58.  
    59.                 foreach (var go in toBeDestroyed)
    60.                     UnityObject.DestroyImmediate(go);
    61.             }
    62.         }
    Does the new "Convert and inject" behavior mean that injecting GameObjects would only serve as a placeholder for components on the unity ECS hybrid approach? If you mark a GameObject as a "Convert and Inject", it shouldn't have any children?
     
    Enzi likes this.
  4. Brendon_Smuts

    Brendon_Smuts

    Joined:
    Jun 12, 2017
    Posts:
    45
    Some of these more fundamental ECS systems seem to make such restrictive assumptions that I'm starting to worry I'm going to be spending a lot of my own time having to develop my own.

    What are the mechanisms for customizing this conversion workflow, in particular the built in conversions? I want to be able to author both the server and client worlds in a single subscene and perform a conversion that is specific to the needs of each particular world. As an example, the server world does not need the mesh renderer or its child information to perform its job, nor does the client world need the majority of components responsible for simulation logic.

    Is it possible to convert a single subscene into multiple representations?

    Multi-world setups were something being touted from the early days and I've been trying to follow this principle for a multiplayer project but so little of the currently developing workflow seems to support any of this.
     
    Last edited: Dec 2, 2019
    florianhanke likes this.
  5. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    249
    I don't get it. I don't get many parts of this whole workflow. It's stuck between 2 worlds and one isn't even supported anymore. How should one work with hybrid objects?

    I still have physics and movement code in MB world and it won't change for the time being.
    Right now I just want to make a trigger that references a door. Both of those are normal scene gameobjects. Graphical representation and colliders are living in MB world, the rest is already in ECS world.
    Now I'm unable to get this really easy use case to work. In 0.0.12p33 the door reference was Entity.Null, now my gameobjects dissappear.

    Has anyone a solution for this within the workflow? I get this working, no problems, without the workflow so I'm kind of perplexed what I'm missing here. Should I just go back to GameObjectEntity and mostly ignore the workflow for everything that's not pure ECS?

    edit: Good lord, there's a very unintuitive workaround: https://forum.unity.com/threads/0-2-0-preview-13.781937/#post-5208599
    At least the GOs aren't removed anymore.
     
    Last edited: Nov 30, 2019
    Monguskan likes this.
  6. Monguskan

    Monguskan

    Joined:
    Jan 2, 2013
    Posts:
    4
    Thanks!

    Definitely not the best solution, but works for the moment.

    I'm also using the same approach. Physics, movement, and animation are based on MB world (at least until we get more info on conversion on those packages); and game logic on ECS world
     
  7. Dipak_Sorathia

    Dipak_Sorathia

    Joined:
    Jul 6, 2014
    Posts:
    2
    Hello guys!
    I have created a large world and convert it into 100 tiles that streaming using Subscene system (each have large number of objects like grass). And works smoothly in mobile devices.
    Main problem is the entity cache files generated from subscenes takes huge memory and that is very bad when you targeting mobile platform.
    Also I use Megacity demo script StreamingLogicSystem that controll RequestSceneLoaded of SubSceneStreamingSystem what happens is it load/unloads subscene but not release the memory of subscene objects [Texture,meshes].
    So is there any solution or trick for this or I did something wrong?
     
    alialharbi likes this.
  8. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    223
    Unity (I think Joachim) recently commented somewhere that the referenced assets are currently duplicated in each subscene, and this is something they are working on improving.
     
  9. Dipak_Sorathia

    Dipak_Sorathia

    Joined:
    Jul 6, 2014
    Posts:
    2
    Ohh! Also can I somehow decrease the size of entity cache files that generated from subscenes? That entity cache file also get insane in memory when you have thousands of objects in each subscenes.
     
  10. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    223
    The generated asset isn't really a cache file, it is the result of the conversion ready to be loaded straight into memory. This allows you to skip the conversion and instantiating entities at runtime.. It's basically a "ready to use" block with all the entities from the subscene ready to be used.
     
  11. aveakrause

    aveakrause

    Joined:
    Oct 3, 2018
    Posts:
    5
    So first off: all of the github links in the first post are 404, please update this.

    Trying to understand subscens a bit.
    When I change the Convert method on any of the objects in the subscene, such as modifying them to have an additional component, how do I force the subscene to RELOAD the cached data of the entities it contains, calling the convert method and adding the new component or removing the old one? The only way I've found is to wiggle a value on the mono, save, wiggle it back, save, then close. But if the subscene has like 4k objects in it, wiggling each of them 2 times is NOT a viable way to reload the cache.

    unload->load doesn't do it.

    There used to be a reload button on the subscene, it seems, but that is now gone, leaving us with no way to reload all of the entities. UNITY WAI.

    My authoring script:
    Code (CSharp):
    1.  
    2. public class PlayerAuthoring : MonoBehaviour, IConvertGameObjectToEntity
    3. {
    4.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    5.     {
    6.         dstManager.SetName(entity, name);
    7.         dstManager.AddComponent(entity, typeof(RotationEulerXYZ));
    8.         dstManager.AddComponent(entity, typeof(Tag_KeepUpright));
    9.     }
    10. }
    11.  
    See video for example: https://clips.twitch.tv/SmellyAltruisticPastaTBTacoRight

    Why do I have to "wiggle" a value to make unity rerun this conversion? Why isn't there a button to just reconvert every entity in the subscene anymore? Or if it just did it every time I closed the subscene? Very frustrating.
     
    Last edited: Dec 13, 2019
    OndrejP likes this.
  12. OndrejP

    OndrejP

    Joined:
    Jul 19, 2017
    Posts:
    68
    Add ConverterVersion attribute to your authoring component and each time you make change which needs reimport, increment the version.

    This works on prefabs linked into subscene as well.
     
    Last edited: Dec 17, 2019
    aveakrause likes this.
  13. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    703
    Will there be some attributes for customizing the behavior of the generated converters? For something like [EntityFromGameObject]
    Code (CSharp):
    1. [GenerateAuthoringComponent]
    2. public struct MyComponent : IComponentData
    3. {
    4.     [EntityReferenceFromGamObject]
    5.     public float Entity targetEntity;
    6. }
    Because currently entity references like that are often needed and it requires a custom Authoring component every time.

    EDIT: Never mind that example. I just found out that it generates a prefab field for an entity field by default. (Of course..)
     
    Last edited: Dec 18, 2019
  14. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    223
    @illinar there was a bug where it threw an error when you tried to link a gameobject reference, but I believe that was fixed in 0.4? I haven't confirmed it yet though.

    But Unity is aware of this and its supposed to work for both GameObjets and prefabs (dragged in from an asset folder).

    Edit: Yep, Entities 0.4 has this fix. From changelog:
    • Remove unnecessary & incorrect warning in DeclareReferencedPrefab when the referenced game object is a scene object
     
    illinar likes this.
  15. hazarartuner

    hazarartuner

    Joined:
    Oct 22, 2016
    Posts:
    6
    Hi to all. I need some advice about using ScriptableObject assets with the DOTS.

    After I watched this awesome video about ScriptableObjects
    I decide to use this approach within my new game project with the DOTS.

    I've created a ScriptableObject asset to share my level configurations with DOTS entities and normal game objects in the scene. In DOTS side, I've converted the config asset to Blob asset by using the GameObjectConversionSystem. As far as I know, in SubScene, conversion workflow only happens when you firstly created the scene or saved the sub scene after some changes.

    The problem is, when I update this config asset, it is not applied to the previously created blob asset. As far as I know, there is no way to manually triggering conversion workflow. Therefore, something like this may be so useful for this type of situations.

    What would you think about this? How would you share your configs with both DOTS entities and normal game objects? Would you use ScriptableObject asset like me or what else? If you agree with me, how would you update blob assets automatically or manually after each config changes?
     
    Last edited: Dec 22, 2019
    OndrejP likes this.
  16. OndrejP

    OndrejP

    Joined:
    Jul 19, 2017
    Posts:
    68
  17. hazarartuner

    hazarartuner

    Joined:
    Oct 22, 2016
    Posts:
    6
    @OndrejP thank you for your help. Unfortunately that attribute seems not working for me or I'm using it wrong, not sure :)

    I found another workaround which is not really nice but it worked. I've created a new property for my MonoBehaviour class which is named `version`. If I need to update SubScene cache, I click the `Edit` button on the SubScene, select the GameObject that I interested in, increment the version number by using Inspector window, then I click the the `Save` button on SubScene object. It generates new cache I guess and it works. But I think we still need some button like `Clear Cache` or `Force Update`. If this is not possible, at least, I need a better approach for handling configurations for both DOTS and normal game objects.
     
  18. OndrejP

    OndrejP

    Joined:
    Jul 19, 2017
    Posts:
    68
    @hazarartuner I've tried modifying Subscene in similar manner as you, but it did not pickup changes on my prefab.
    When I changed prefab, then changed Subscene which referenced that prefab and saved value in Entity Inspector still shown old value.

    This is how I use the attribute.
    Code (CSharp):
    1.  
    2. [DisallowMultipleComponent, ConverterVersion("ReimportHelper", 3)]
    3. public class ReimportHelper : MonoBehaviour, IConvertGameObjectToEntity
    4. {
    5.     public void Convert(Entity entity, EntityManager destinationManager, GameObjectConversionSystem conversionSystem)
    6.     {
    7.     }
    8. }
    9.  
     
  19. hazarartuner

    hazarartuner

    Joined:
    Oct 22, 2016
    Posts:
    6
    @OndrejP I have no idea why our solutions not work for both of us :(

    For now, I decided to use ConvertToEntity script rather than SubScene. As far as I know, It converts entities on start and this works for me. It may be not efficient for production usage if you have lots of game objects and/or heavy conversion workflow. But I'm at the beginning of my project and I hope there will be a better solutions for our cases later. In worst case, when I am ready to production, I can change these game objects to SubScenes because my configs will no need to be changed very often.

    By the way, here is my code sample (updated):

    Screen Shot 2019-12-22 at 14.34.29.png
     
    Last edited: Dec 22, 2019
    OndrejP likes this.
  20. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    115
    Hello,

    I'm starting to use the subscene feature in hte editor and I have a behaviors that I think is a bug.
    I put all my level asset in a sub scene (ground, trees, buildings,...) while all my gameplay (character,...) is in hte main scene.

    Now when entering play mode in the editor, if the subscene is open, it works fine (my character rests on the ground through the new physics engine). But if the subscene is close, when entering play mode, the character goes rigth through the ground, as if the subscene had a distinct physics world from the main scene.

    Is it the correct behaviour ? Should I do something special to "merge" the physics worls ?
     
  21. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    492
    When the scene is open that means your assets still Go which means they are not entities and have the old physics stuff. Try to install the unity.physics package from package manager which will convert their old physics components to ones compatible with ecs. If you have already installed this package:
    1) try to configure their physics shape and physics body components (I think the conversion it’s not working for the old meshcollider component)
    2) make sure the belongsTo and collidesWith are configured correctly in the physics shape component.
    3) make sure you character collider is converted too.
     
  22. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    115
    Hi, that's not it, I'm fully working with the new components comming with the physics package.
     
  23. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    492
    do you have error when you character is converted ?
    try to see if it's related to this thread.
     
  24. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    115
    Thanks for you sugesstions. Unfortunatly, no, no error during conversion.
     
    Opeth001 likes this.
  25. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    115
    Migrating to 2019.3.0f3 seems to solve the issue.
     
  26. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    115
    Ok, new issue with 2019.3.0f3 :

    When using sub scene if the sub scene is open when entering play mode, position, rotation, materials are mixed up :
    upload_2020-1-4_17-36-18.png
    This also happen when not using subscene at all.

    When entiring play mode with closed sub scene, or not converting the object to entities at all, everithing is fine:

    upload_2020-1-4_17-37-59.png
     
  27. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    131
  28. Srokaaa

    Srokaaa

    Joined:
    Sep 18, 2018
    Posts:
    80
    Is there a standard way of instantiating an Entity that has a child with ConvertToEntity-(Convert And Inject Game Object) somewhere in it's hierarchy?

    Example:
    I have a PlayerShip prefab and one of it's children is an Engine GameObject with with Visual Effect component so that I may use VFX Graph to draw engine exhaust.
    Currently I set ConvertToEntity-(Convert And Destroy) component on a PlayerShip and ConvertToEntity-(ConvertInject Game Object) and CopyTransformToGameObject components on Engine.

    Situation 1 - Instantiating by putting a prefab in a scene
    This works just fine. Whole hierarchy is converted to entities destroyed but Engine which is just converted and has it's transform copied every turn form accompanying entity.


    Situation 2 - Instantiating by calling EntityCommandBuffer.Instantiate()
    Sometimes I don't need my PlayerShip prefab spawned right away but rather as a result of some event. So I made PlayerSpawner IComponentData and accompanying PlayerSpawnerAuthoring MB with IDeclareReferencedPrefabs. Unfortunately when I spawn my PlayerShip prefab with EntityCommandBuffer.Instantiate() entities are spawned correctly but Engine GameObject that my VFX Graph is attached to doesn't.

    Is there a way to instantiate GameObjects in Situation 2?
    Is there an easy way to use VFX graph with Unity ECS atm or do we have to wait longer for it?
     
    WAYN_Group likes this.
  29. nantoaqui

    nantoaqui

    Joined:
    Oct 1, 2014
    Posts:
    28
    I'm facing an issue where the Parent and children have attached Convert To Entity script using "Convert and Inject Game Object".

    Parent component gets converted and the entity is generated but the latter doesn't get converted.
     
  30. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    98
    If i remember correctly, you need add only the ConvertToEntity componend to the root object and the Hirachy will be converted.
     
    nantoaqui likes this.
  31. tgienger

    tgienger

    Joined:
    Jul 18, 2013
    Posts:
    39
    Taking a standard gameobject scene I picked a group of static objects and created a subscene. When I close the subscene or run the game (or just in game view) these objects disappear. From the few videos I've seen and stuff I've read this is all that is required to turn scene objects into entities and this isn't the behavior I expected. I thought they were suppose to remain visible in the editor, but not unable to interact with them. Also obviously they should not disappear from the game view.

    I must be missing a step, but I sure can't find any info on it.
     
  32. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    115
    Maybe you face the same issue I do (see a few posts up.

    Or you are missing the hybrid rendering package.
     
  33. tgienger

    tgienger

    Joined:
    Jul 18, 2013
    Posts:
    39
    I ended up removing all the packages and starting over. I'm not sure where it went wrong, but it's working for the most part now. Thanks for the reply :)
     
  34. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    115
    FYI for those interested I seem to have solve all my display issue by making everything non static and enabaling GPU instancing on all materials.
     
unityunity