Search Unity

  1. We would like to hear your feedback about Unity and our products. Click here for more information.
    Dismiss Notice

New SubScene & ConvertToEntity workflows

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

  1. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    With the Unity.Entities release today, we are adding support for SubScenes and the new ConvertToEntity script. The main concept is that instead of using ComponentDataProxy / ComponentDataWrapper. We simply convert existing game objects or MonoBehaviours to pure entity data. This is the same workflow we used to build the MegaCity demo.

    This makes it possible to create content for Unity.Entities in an effective way.

    We have updated the HelloCube samples to show it:

    This scene uses ConvertToEntity and shows how to create a MonoBehaviour as editing representation and then convert it to an efficient entity representation:
    https://github.com/Unity-Technologi...JobForEach/RotationSpeedSystem_IJobForEach.cs

    https://github.com/Unity-Technologi...ForEach/RotationSpeedAuthoring_IJobForEach.cs

    ConvertToEntity is great for getting started in a simple scene and see the conversion workflow doing it's thing, but it doesn't help with improving load times. SubScenes do. Essentially when saving the scene, we also write out a cached entity binary representation. SubScenes is what allowed the megacity to scale, since we only ever load the game object representation for editing a specific part of the world:

    https://github.com/Unity-Technologi...e/master/Samples/Assets/HelloCube/4. SubScene

    Instantiating a prefab using the same conversion flow for existing MonoBehaviour scripts is also very easy now:
    https://github.com/Unity-Technologi...es/Assets/HelloCube/5. SpawnFromMonoBehaviour

    https://github.com/Unity-Technologi...romMonoBehaviour/Spawner_FromMonoBehaviour.cs


    Best of all that same workflow can be used to convert game object references to prefab references:
    https://github.com/Unity-Technologi...r/Samples/Assets/HelloCube/6. SpawnFromEntity

    https://github.com/Unity-Technologi...pawnFromEntity/SpawnerAuthoring_FromEntity.cs

    https://github.com/Unity-Technologi.... SpawnFromEntity/SpawnerSystem_FromEntity.cs

    NOTE: This new Unity.Entities release requires 2019.1
     
    Last edited: Jun 3, 2019
  2. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,016
    Just adding a note that new Entities release doesn't work on 2019.2.0a6 due to missing API there (Edit: Unity just released 2019.2.0a7. New Entities do run with it :)) New samples also run fine on 2019.1.0b4.

    For Subscene samples, one has to hit the "Rebuild Entity Cache" on the sample scenes, otherwise new samples were really straight forward (I really dig the clarity on current samples).
     
    Last edited: Mar 4, 2019
    SubPixelPerfect and PhilSA like this.
  3. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,057
    I'm curious to try out this approach, especially in more complex scenarios to see how it holds up.

    I've been thinking for a while about what a PureECS "prefab editor" could look like, and I haven't yet been able to imagine something good and user-friendly (that's not to say it's impossible; just that I personally couldn't come up with anything yet). So I think this conversion workflow has potential

    More specifically, I'm thinking about what it would be like to create a very complex prefab with complex logic in it, such as an animated character with:
    • a bone hierarchy (one entity per bone, and possibly one more entity for the entire "rig")
    • hit boxes (one entity per collider)
    • ragdoll setup (one entity per rigidbody and one more entity per collider, potentially. Maybe even one more entity per joint)
    • a skinned mesh renderer
    • a character controller capsule
    • a "CharacterManager" component that has references to character Bones, Meshes, Materials and other Prefabs for all sorts of purposes (in the case of Meshes, Materials and Prefabs, they cannot live on a IComponentData so that would be something to think about. And in the case of Bone references, they would be references to the specific Bone entities of that character instance). How could those "references" be edited in GameObject mode and then converted to ECS?
    • etc....
     
  4. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    412
    @Joachim_Ante, awesome work. Btw is that still long way to go to have pure entity editing at Scene? Will I able to edit current Game Object and entity together at the same Scene when this feature arrives?
     
  5. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    220
    This is good news!
     
  6. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,193
    Awesome to see how ECS-in-editor crucial pieces are coming together now.
     
  7. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    We convert whole transform hierarchies. You can have as many references to other objects as you like using Entity refs on the component data side. So all of this can be done now.

    Also do note, that referenced prefabs as shown in the spawner sample support instantiated linkedentitygroup. Meaning you have full prefab workflows, where you can instantiate a whole collection of entities in one group just like Instantiate(GameObject) clones the whole sub-hierarchy and remaps any references. It makes the whole thing all of a sudden feel much more like Unity.
     
    Opeth001, Sluggy, Alverik and 7 others like this.
  8. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    The conversion workflow is useful because it lets us convert existing content, scenes, prefabs and the output from existing tools.
    It lets us have useful tooling today.

    In parallel we are developing dedicated entity editing tools.

    But in fact the principle there is the same. Editor and Runtime representation is different. For editing you want larger components, at runtime you want to split it out into small atomic pieces. The new entity editing tool is just much more in depth built specifically for entities. Does a better job visualizing these transformations.
     
    Last edited: Mar 5, 2019
  9. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    253
    Hi, Can I use this new subscene system for partly streamed world? in example, load subscenes which is located nearby camera only. Current subscene systems seems that load all subscenes automatically. Can I customize loading strategy?

    Also, how about scene-related asset, especially lightmap. I baked lightmap with subscenes, but it disappeared when I play it. (maybe automatically converted RenderMesh does not support lightmap yet?)
     
  10. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    >Can I customize loading strategy?
    Yes. Simply add the RequestSceneLoaded tag component on the scene entity, when you want to load it and conversely remove it when you want to unload. The auto-load checkbox does exactly that.

    Lightmap baking is not supported yet by the DOTS renderer.
     
    TZ-, Alverik, joshcamas and 8 others like this.
  11. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    703
    I hit the "like" button so hard my mouse exploded.
     
  12. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    Very curious to hear from anyone who has already tried it out how the new conversion flow is actually working for you?
     
  13. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    1,280
    Have no time to test it, because new release completly broke every thing :) And I spend all time to repair (from 0.0.24 to 0.0.26 package)
     
  14. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    546
    I got my stuff back in working order again last night. Will take a crack at modifying it to use the new conversion tools tonight or tomorrow night.
     
    eizenhorn likes this.
  15. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    1,280
    Yep, me too. Finally migrate and fix all from 2018.3 to 2019.1 and 0.0.24 to 0.0.26
     
  16. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,258
    So I've been using scene conversion since p22 or whenever it was added. With p26 I've converted this over to new sub scenes (which only took minutes) so it hasn't been a huge change in my workflow.

    Anyway here's a few notes, using Unity: 2019.1b5, in no particular order.

    1. Keep getting a UI elements / serialization exception if I have the SubScene script selected when playing a scene.

    Code (CSharp):
    1. ArgumentException: Object at index 0 is null
    2. UnityEditor.SerializedObject..ctor (UnityEngine.Object[] objs, UnityEngine.Object context) (at C:/buildslave/unity/build/Editor/Mono/SerializedObject.bindings.cs:39)
    3. UnityEditor.Editor.GetSerializedObjectInternal () (at C:/buildslave/unity/build/Editor/Mono/Inspector/Editor.cs:545)
    4. UnityEditor.Editor.get_serializedObject () (at C:/buildslave/unity/build/Editor/Mono/Inspector/Editor.cs:452)
    5. UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.Editor editor, UnityEditor.UIElements.InspectorElement+Mode mode) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorElement.cs:133)
    6. UnityEditor.UIElements.EditorElement.Init () (at C:/buildslave/unity/build/Editor/Mono/Inspector/EditorElement.cs:47)
    7. UnityEditor.UIElements.EditorElement..ctor (System.Int32 editorIndex, UnityEditor.InspectorWindow iw) (at C:/buildslave/unity/build/Editor/Mono/Inspector/EditorElement.cs:31)
    8. UnityEditor.InspectorWindow.DrawEditors (UnityEditor.Editor[] editors) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1358)
    9. UnityEditor.InspectorWindow.RebuildContentsContainers () (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:613)
    10. UnityEditor.InspectorWindow.RedrawFromNative () (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:293)
    11.  
    Seems harmless just annoying as it trips 'error pause' entering play mode.

    2. Is there an automated way to handle lights (or other non convertible game object components) that I've missed?

    I currently use a custom game object conversion system
    public class LightConversion : GameObjectConversionSystem

    and a custom System that initializes them.
    https://gist.github.com/tertle/5eb0084404a8dc69616ed37699b0fd23

    3. TransformConversion has caused me a few issues.

    It adds a Translation/Rotation proxy to entities which is an issue if your entity already has the proxy!

    Previously I had a few GameObjectEntity prefabs that I had both in scene and I also used at runtime. This means I either had to remove the proxies when I put the object in a scene, or add the proxies when I initialized them at runtime.
    Instead I just overrode the TransformConversion with a custom version that did a check before adding the component.

    https://gist.github.com/tertle/b70563c21e12452038aa14805d7f3d87

    This is based off the previous version of TransformConversion (p24) and I know it's been updated in p26 but I've stopped using it so it's just legacy pulled from repo.

    Instead of doing this now though, I've decided to ditch ComponentDataProxies completely and just rely on IConvertGameObjectToEntity, so this isn't an issue for me anymore but others might run into it.

    4. Overall, pretty happy with the system, it plugs in nicely to my preferred workflow. I'm pretty sure I had some other feedback when I was converting yesterday but I've just woken up and forgotten. I'll post more as I remember.
     
    Last edited: Mar 5, 2019
  17. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    >It adds a Translation/Rotation proxy to entities which is an issue if your entity already has the proxy!
    The idea is that we want everyone to stop using ComponentDataProxy completely. We haven't deprecated it yet. But i think it fundamentally doesn't fit the conversion flow concept...
     
    tbriley and FROS7 like this.
  18. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,258
    Well that's good because I decided to stop using them after this update and converted them to IConvertGameObjectToEntity MonoBehaviours instead. Is that the recommended workflow?
     
    eizenhorn likes this.
  19. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    Yes.
     
    Zoey_O, dzamani and eizenhorn like this.
  20. Creepgin

    Creepgin

    Joined:
    Dec 14, 2010
    Posts:
    232
    That's a really good call. The current HybridECS workflow involving GameObjectEntity and ComponentDataProxy has too much coupling between GameObjects and Entities, and frankly too much performance bog in the OnEnable & OnDisable.

    Thinking those will be replaced sooner or later, I also converted everything to be using IConvertGameObjectToEntity yesterday and today (effectively getting rid of all GameObjectEntity and managing GO-to-entity relations on my own). Now there's much better separation between GOs and entities. Using the entity spawner pattern also feels really good and natural. In general, very happy with this release.
     
    Last edited: Mar 6, 2019
    TeagansDad, hippocoder and FROS7 like this.
  21. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    360
    how about the subscene work with asset bundle. I see the cache data is store in resource folder.
     
  22. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    Next step for us is to make the entity cache not be in assets folder but just be a cache like any other asset imports. We will build that on top of addressables. Ultimately we want the entity cache to be creatable by the new asset pipeline in another process with a async non-interrupting workflow.

    Let's call whats there right now a "ghetto pipeline", it will get a lot of love in the coming months. It was the simplest way to move it forward step by step unlocking value with a simple solution right now.
     
  23. Creepgin

    Creepgin

    Joined:
    Dec 14, 2010
    Posts:
    232
    Right now all the conversion methods will include Translation and Rotation in the resulting entity prefab. However, one of the advantages of using entity prefabs should be the ability to exclude transform data. Will this be supported in future APIs? Either through new conversion options or the aforementioned "dedicated entity editing tools"?
     
    learc83 likes this.
  24. Roycon

    Roycon

    Joined:
    Jul 10, 2012
    Posts:
    19
    How can I have existing monobehaviours or components (eg BoxCollider) on a prefab that I pass into
    GameObjectConversionUtility.ConvertGameObjectHierarchy

    I'm guessing I should create my own component to represent the BoxCollider and add that to the entity with
    IConvertGameObjectToEntity, then use a system to create a gameobject and put a box collider on it then attach it to the entity with EntityManager.AddComponentObject()

    I tried using EntityManager.AddComponentObject in IConvertGameObjectToEntity but it didn't work, Note I'm trying this with a prefab into GameObjectConversionUtility.ConvertGameObjectHierarchy then EntityManager.
    Instantiate to make copies of it. Is that the wrong flow?
     
    Last edited: Mar 6, 2019
  25. angusmf

    angusmf

    Joined:
    Jan 19, 2015
    Posts:
    246
    Here's an example I just happened to see. You have to implement the Convert method in the IConvertGameObjectToEntity and then looks like you do AddComponentData instead of AddComponentObject.

    https://github.com/Unity-Technologi...JobProcessComponentData/RotationSpeedProxy.cs
     
  26. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    546
    @Joachim_Ante - adding to @Creepgin's question, will there be (or is there already a timetable for) something like a ConvertScriptableObjectToEntity pipeline?
     
    rizu likes this.
  27. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    253
    Please add abstraction layer for handling asset pipeline, not directly using addressables. Current addressables are lack of many important features like error handling, runtime re-initialization, encryption and so on. I think that making users can use their own asset management system will be more good way.
     
    Tharis likes this.
  28. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,016
    That really sounds more like feature request for addressables themselves.
     
  29. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    360
    Me too, most game project has it own asset management system and it may not suitable for switching to addressable system.
     
    Tharis likes this.
  30. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,193
    What's the end product of this? You want any arbitrary ScriptableObject asset file in Project folder/connected in the scene to become 1 Entity with 1 component object leading to that file?
     
  31. Creepgin

    Creepgin

    Joined:
    Dec 14, 2010
    Posts:
    232
    Yeah also, I don't think you need a hierarchical conversion tool for ScriptableObjects because... they don't have a hierarchy. =D

    But SO's-to-entity workflow is very powerful. And you can already do it today. If you serialize out your CompDatas (via Odin for example), you can create entities from SO's very easily:



    Code (CSharp):
    1. using Sirenix.OdinInspector;
    2. using Unity.Entities;
    3. using UnityEngine;
    4. using System.Linq;
    5. using System.Reflection;
    6.  
    7. [CreateAssetMenu(menuName = "ECS/SOEntityPrefab")]
    8. public class SOEntityPrefab : SerializedScriptableObject {
    9.  
    10.     [SerializeField] IComponentData[] componentDatas;
    11.  
    12.     MethodInfo SetComponentDataMethod = typeof(EntityManager).GetMethod("SetComponentData", BindingFlags.Instance | BindingFlags.Public);
    13.  
    14.     [Button(ButtonSizes.Gigantic)]
    15.     void CreateEntity() {
    16.         var em = World.Active.GetOrCreateManager<EntityManager>();
    17.         var entity = em.CreateEntity(componentDatas.Select(c => new ComponentType(c.GetType())).ToArray());
    18.         foreach (var cd in componentDatas) {
    19.             var genericMethod = SetComponentDataMethod.MakeGenericMethod(cd.GetType());
    20.             genericMethod.Invoke(em, new object[] { entity, cd });
    21.         }
    22.     }
    23.  
    24. }
    25.  
    This sample is more for editor/playmode testing. But you can easily create entity prefab for runtime usage as well.
     
    Last edited: Mar 7, 2019
  32. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    546
    More for the "single consistent way" of an interface + supporting functions, otherwise we'll all wind up hand rolling a solution.
     
    FROS7 likes this.
  33. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    110
    Since there is a way to save a group of entities to an asset (which is what subscenes are using right?) could we build a "scriptable object" on top of that? Even convert SO->entities asset file->then expose as a singleton.
     
  34. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    You can add the StaticEntityOptimization component at the root of a hierarchy to get rid of it. We use that for all buildings in the megacity. Its a super important optimization. It kills off the whole hierarchy at bake time.
     
  35. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    You can use GameObjectConversionSystem for this purpose. Check out TransformConversion or
    MeshRendererConversion for example code.
     
  36. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    the conversion happens at a scene level and you can pull in any data you like. For example you could read the scriptable object data and turn it into ComponentData or DynamicBuffer on an entity.

    Next release will also have blob assets which is made for sharable immutable resource data. In that case, you could convert a ScriptableObject into a BlobAsset and then share it from multiple instances in the same scene.

    BlobAssets are made for zero cost deserialization for large amounts of data. AnimationClip, CollisionMesh, CurveData is a good example of what we think belongs into a BlobAsset.
     
  37. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
  38. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    1,280
    It's fine for transform system optimisations, but it's only adds Static component to entity in GameObjectConversionMappingSystem, but for example if we use our GO representation for some thing like - data storage after conversion to entity, which not require TRS, and this components just waste space inside chunk and memory itself (of course it's not so huge, but...) :) I mean idea of just pure data storage entity without any representations it's possible in future for conversion tool?
    BTW I found time to test conversion tools and they really cool, I swich all my hardcoded archetypes and own conversion tool for prefabs to built-in conversion tool.
     
    Last edited: Mar 7, 2019
  39. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    110
    Oohhh that is interesting! I guess this data is blittable or at least usable from jobs? Going to be super handy when passing data to jobs :) thanks!

    Also.. strings are immutable.. so.. store strings as blobs? :)
     
    Last edited: Mar 7, 2019
    Jes28 likes this.
  40. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,575
    There is an optimization pipeline and it removes the hierarchy and does a bunch of other data optimization for static entities.
     
    FROS7 and eizenhorn like this.
  41. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    1,280
    Oh good, I think I should refresh my knowledge in code part about Static ICD.
     
  42. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    546
    BlobAssets sounds exactly what I was thinking of, thanks!
     
  43. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,016
    New Entities and Hybrid packages now out on package manager. Entities 0.0.12-preview.27 got Blobs and ComponentQueryBuilder as new, other changes seem to be tweaks to the conversion workflow.

    Edit: Release notes updated: https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/ReleaseNotes.md
     
    Last edited: Mar 8, 2019
    siggigg likes this.
  44. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,016
    I also noticed that release notes didn't tell anything about blobs, I'm guessing the implementation still incomplete despite some chunks of code being there for it?

     
  45. aeldron

    aeldron

    Joined:
    Feb 12, 2013
    Posts:
    23
    Do we have an example of usage of the ConvertAndInjectGameObject conversion mode? What's its intended use?
     
  46. Kender

    Kender

    Joined:
    Nov 16, 2012
    Posts:
    144
    As I started switching over the new GameObject conversion pipeline, I found out that I lost access to the GameObject's components like Camera, Light etc. On the other hand, it seems like I can use
    Code (CSharp):
    1. EntityManager.AddComponentObject(entity, GetComponent<Camera>());
    within conversion and store the entity on my MonoBehaviour. Is this the expected way for linking? I need to have access to entity from Camera for rendering hooks and I need to access Camera from entity to duplicate it later in a customized way
     
  47. Kender

    Kender

    Joined:
    Nov 16, 2012
    Posts:
    144
    Also, it seems like pre-caching of a ComponentGroup and using it with Entities.With is faster than the every frame build (which performs cache lookup on every call) of Entities.WithAll/WithAny/WithNone. Though we could use Entities.WithAll/WithAny/WithNone to pre-build the group.
     
  48. Ziboo

    Ziboo

    Joined:
    Aug 30, 2011
    Posts:
    290
    Awsome work.
    Could you add some more samples, one that actually runs on two different data set in a job.
    for instance: Get every Enemies, and calculate distance between Player(s)

    Thanks
     
  49. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    641
    Sorry for the dumb question, but I'm not quite sure how we're supposed to use this.
    Is it supposed to be a way to still generally use the old structure (monobehaviors) for a lot of things in editor, and then have it all converted to ECS during runtime?

    Does anyone have an example of an application of these features?
     
    Last edited: Mar 20, 2019
    foxnne likes this.
  50. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    703
    There are samples of it being used in different ways here: https://github.com/Unity-Technologies/EntityComponentSystemSamples

    All the links in the first post point to them.