Search Unity

Official New SubScene & ConvertToEntity workflows

Discussion in 'Entity Component System' started by Joachim_Ante, Mar 4, 2019.

  1. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    First, thanks @thelebaron for the time you take to go through this with me.
    I agree that using the translation place the bullet at the right spot on screen but except if there is something wrong in the logic of my ShotHitSystem I don't see why if I reactivate the destruction of the bullet on collision, the bullet gets destroyed instantly. Additionally the ShotHitSystem decrease the heal of the entity that was hit by 1.
    And you can in the sample you ran that the Floor has a start health of 1 which decrease for every bullet that is shot.

    The cast logic should cast a ray from the bullet's position backward based on velocity and time to cover the distance the bullet moved between frames. And in our case the bullet dose not move (speed = 0) so the ray basically is the bullet's position. Then why does my floor lose health ??

    Edit1 : check and I'm missing a "-" and "speed" on my ray cast to make it as described but that does not affect the behavior I described.

    Edit 2 : github repo is up to the fix of edit 1 and the reactivation of the bullet destruction on hit.
     
    Last edited: May 18, 2019
  2. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    857
    Setting the translation in addition to the localtoworld results in the floor not losing any health with the same result as what was displayed in the previous gif(I didnt update the project though so there are assertions that I didnt notice previously)

    Code (CSharp):
    1.  
    2.                 // Place it at the end of the gun
    3.                 // original CommandBuffer.SetComponent(index, instance, new LocalToWorld { Value = location.Value });
    4.              
    5.                 var localToWorld = new LocalToWorld
    6.                    {
    7.                       Value = float4x4.TRS(location.Position,
    8.                       quaternion.LookRotationSafe(location.Forward, math.up()),
    9.                       new float3(1,1,1))
    10.                    };
    11.              
    12.                 CommandBuffer.SetComponent(index, instance, new Translation { Value = location.Position });
    13.                 CommandBuffer.SetComponent(index, instance, localToWorld);
     
    WAYNGames likes this.
  3. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    Yes that work. didn't think of set both of them. I also set the Rotation.

    Code (CSharp):
    1.  
    2.                 // Place it at the end of the gun
    3.                 CommandBuffer.SetComponent(index, instance, new Translation { Value = location.Position });
    4.                 CommandBuffer.SetComponent(index, instance, new Rotation { Value = quaternion.LookRotationSafe(location.Forward, math.up()) });
    5.                 CommandBuffer.SetComponent(index, instance, new LocalToWorld { Value = location.Value });
     
  4. Fou

    Fou

    Joined:
    Mar 11, 2017
    Posts:
    1
    Hey ! I'm using the ConvertToEntity script on my GameObject with the "Convert and Inject Game Object" conversion mode, because I want to keep components such as SpriteRenderer, Rigidbody2D, BoxCollider2D and Animator : that's the only way I found to do this right now, spawner systems and stuff like that don't seem to work well with 2D sprites.
    I tried your suggestion and some other ways to chose or change its World so that it can be different than the Default one, but even when it seems to work I will lose these components in my entity. Do you know of any way to have both things ? (Injected GameObject with the old components working, and the entity from the conversion being in a World of my choice instead of default)
     
  5. ParametrixFX

    ParametrixFX

    Joined:
    Nov 14, 2018
    Posts:
    18
    Subscene is a great optimization for our applications. We really like it.
    Though, we have a small problem with speed trees being inside a subsence. They are not "gone with the wind". Is there any workaround?
     
  6. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    What assembly definition asset do I need for IConvertGameObjectToEntity
     
  7. nantoaqui

    nantoaqui

    Joined:
    Oct 1, 2014
    Posts:
    42
    How do you access the newly created entity like GetComponent<GameObjectEntity>() in this new workflow?
     
  8. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    @francois85
    upload_2019-5-23_23-31-44.png
     
    RoughSpaghetti3211 likes this.
  9. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    @nantoaqui Can you provide more detail on what you want to do and how you create your entity?
     
  10. FilmBird

    FilmBird

    Joined:
    Apr 11, 2015
    Posts:
    26
    Hi.
    DOTS is awe-inspiring.
    Thankyou.

    In "HelloCube_07_ForEach" there is a note that says:
    Component Systems using Entities.ForEach run on the main thread. To take advantage of multiple cores, you can use a JobComponentSystem (as shown in the other HelloECS examples).

    I also heard in one of the talks that you are working on faster C# lambda functions.
    Is Entities.ForEach the lambda function that you talked about or is there a better version that can run in parallel maybe?
     
  11. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    At the moment you want to use IJobForEach whenever you care about performance.

    In the future we want to make Entities.ForEach be able to generate the same code as IJobForEach while using the same Entities.ForEach API, we have ideas on how to do it but it depends on a chain of work that has to be completed first.

    So for now, if you care about perf, use IJobForEach
     
    Spy-Shifty and dadude123 like this.
  12. FilmBird

    FilmBird

    Joined:
    Apr 11, 2015
    Posts:
    26
    Happy to use IJobForEach for now and waiting eagerly for DOTS Physics, Lambda...
    Thanks.
     
  13. nantoaqui

    nantoaqui

    Joined:
    Oct 1, 2014
    Posts:
    42
    @WAYN_Group I would like to have a monobehaviour spawning new entities whenever there is a collision, like this:

    Code (CSharp):
    1.         private void OnTriggerEnter2D(Collider2D collider)
    2.         {
    3.          
    4.                     var sender = GetComponent<GameObjectEntity>().Entity;
    5.                     var other = collider.GetComponent<GameObjectEntity>().Entity;
    6.  
    7. /* create entity */
    8.                
    9.          }
    But since i'm not using GameObjectEntity there's no way to access the entity.
     
  14. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    @nantoaqui Not much to do with the convertion worlkflow IMO but would this work for you ?
    Code (CSharp):
    1. Entity spawnedEntity = World.Active.EntityManager.Instantiate(Prefab);
    "Prefab" should be an game object prefab with the GameObjectEntity or ConvertToEntity component.
    You could also just replace "Prefab" with "sender" or "other" if you wanted to duplicate the coliding objects.

    You could also use :
    Code (CSharp):
    1. Entity spawnedEntity = World.Active.EntityManager.CreateEntity();
    And then set everything up through scripting.
     
    nantoaqui likes this.
  15. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    967
    I like the new conversion workflow. It's more robust than I thought.

    What I don't know is how to deal with lights in gameobjects that are getting converted. Any ideas?
    Non-moving lights are no trouble but do I need a hybrid system to move lights that are supposed to be on pure entities with hyrbid renderer?
     
    Orimay likes this.
  16. Orimay

    Orimay

    Joined:
    Nov 16, 2012
    Posts:
    304
    I'm interested in pure Lights and Cameras too
     
  17. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    We are working on adding support for lights in the conversion process.
     
    Antypodish, Enzi and Orimay like this.
  18. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    967
    Cool, great to hear Joachim! Any ETA?
     
  19. chuyuwei

    chuyuwei

    Joined:
    May 29, 2019
    Posts:
    19
    Why does subscene make performance low? In the HelloCube sample 4 it is 450fbs, but it is 500fbs in the HelloCube sample 2 IJobForEach. And in my project with 357.4k tris, when i make a gameobject change subscene , it is from 500fbs to 300fbs. why is it slower?
     
  20. fps_bill

    fps_bill

    Joined:
    Aug 14, 2015
    Posts:
    4
    Would it be possible to start making some of the built in conversion systems public so that we can use the [UpdateBefore()] / [UpdateAfter()] attributes?

    I can't do [UpdateBefore(typeof(MeshRendererConversion))] for example.
     
  21. alexnown

    alexnown

    Joined:
    Oct 25, 2018
    Posts:
    22
    I'm trying serialize data to BlobAsset. In editor and on an android ARM64 all works fine, but my data not loaded correct on an ARMv7 IL2CPP and Mono builds. I would like to use SubScene workflow for production, it is possible to make correct serialization for 32 bit os? Would it be possible soon?
     
  22. mgmhunt

    mgmhunt

    Joined:
    Apr 1, 2013
    Posts:
    63
    Playing with ECS preview.33. Been following along for a while now and trying to be a good citizen have moved away from the Proxy components to ConvertToEntity workflow.

    I wanted to keep the link between the GameObject and the Entity and ended up making a small tweak to ConvertToEntity.cs (Inject Option... couldn't see what the Inject part of it means... rather than 'keep GameObject'....

    I've added to ConvertToEntity.cs:
    public Entity entity;

    And tweaked the method:
    public static Entity ConvertAndInjectOriginal(GameObject root) to return an Entity to the calling method
    if (ConversionMode == Mode.ConvertAndDestroy)
    ConvertHierarchy(gameObject);
    else
    entity = ConvertAndInjectOriginal(gameObject);

    For syncing the Transforms I've:

    Created a CopyTransformToGameObjectNEW ComponentData which attaches to Entity via the Convert process, rather than CopyTransformToGameObject which requires on GameObjectEntity.

    Also duplicated CopyTransformToGameObjectNEWSystem which just has same functionality as CopyTransformToGameObjectSystem but targets the NEW ComponentData.

    So this seems to work quite well in terms of moving across from the old workflow. I can reference ConvertToEntity component for the new exposed entity property and see which entity was created for the GameObject.

    Unfortunately I'm hacking the ConvertToEntity.cs so it's not a 'stable' solution.

    Am I missing something... ?? I'm not going for anything performant at the mo, just playing with the Object world and the ECS world sync. Other samples seem to focus purely on setting up in Object space and then one-way transfer to ECS, not keeping any reference?
     
  23. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    The inject part meant the fact that
    GameObject
    is not just kept, all of its top level
    MonoBehaviour
    classes are now copied to your new entity as a component object type which also happening with non-inject mode but you could get the component and modify them to reflect on the original GO since they are reference type. In a way those component object are "functioning" and not just migrated. (e.g. on destroy mode a migrated Transform may be useless) Then you could imagine your GO has been injected to the entity. But at first I do think the name is unintuitive before you dig the code.

    The recommended way seems to be using
    IConvertGameObjectToEntity
    added to any MonoBehaviour that is to be converted. In your definition of
    Convert
    method you could receive a new
    Entity
    while the conversion is happening.

    In the same
    Convert
    you could add
    CopyTransformToGameObject
    to that new
    Entity
    .
     
    Last edited: Jun 1, 2019
  24. mgmhunt

    mgmhunt

    Joined:
    Apr 1, 2013
    Posts:
    63
    That was the bit I was missing! Thanks for the clarification. The Inject part I had a brain fart, seems obvious now - bit of domestic blindness when looking at the Entity Inspector.
     
  25. Revolter

    Revolter

    Joined:
    Mar 15, 2014
    Posts:
    216
    PSA: If you're working with ECS, don't import UniRX in your project. Spent a few hours wondering why ConvertToEntity doesn't work
     
  26. mgmhunt

    mgmhunt

    Joined:
    Apr 1, 2013
    Posts:
    63
    I've got UniRX in my project (and using it) and ConvertToEntity is working (?). Couldn't tell you exactly which version of UniRx though, haven't updated for a (few) months.
     
  27. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    The only thing with UniRx with ECS I know is that the Async module also hacks the player loop to put in await continuation point and it came before ECS's hack, so the ECS's hack override its hack. UniRx has PlayerLoopHelper.Initialize so you could use ECS's hacked loop to put into UniRx for it to hack again then you get 2 hacks. (but still I don't think this is related to conversion)

    Code (CSharp):
    1. var playerLoop = ScriptBehaviourUpdateOrder.CurrentPlayerLoop;
    2. PlayerLoopHelper.Initialize(ref playerLoop);
     
  28. Revolter

    Revolter

    Joined:
    Mar 15, 2014
    Posts:
    216
    Latest one with Unity 2019.1.5f1
     
  29. mgmhunt

    mgmhunt

    Joined:
    Apr 1, 2013
    Posts:
    63
  30. daschatten

    daschatten

    Joined:
    Jul 16, 2015
    Posts:
    208
    Is there a possibility to add data to a SubScene (e.g. level id, to load subscene when a specific level loads)? I tried attaching a ComponentData via conversion workflow, but that didn't work.
     
  31. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203

    It's possible but requires a bunch of custom code at the moment it's not been made straightforward yet. Look at SubScene.cs if you want to do it manually.
     
  32. daschatten

    daschatten

    Joined:
    Jul 16, 2015
    Posts:
    208
    At first it seemed to be done easily by modifying
    UpdateSceneEntities() in SubScene.cs:

    Code (CSharp):
    1. var convertibles = GetComponents<IConvertGameObjectToEntity>();
    2.  
    3. for (int j = 0; j < convertibles.Length; j++)
    4. {
    5.     convertibles[i].Convert(sceneEntity, _SceneEntityManager, null);
    6. }
    7.  
    But this change isn't persistent and resets when unity is restarted (and it's not in vcs obviously). Next i tried to copy SubScene.cs to CustomSubScene.cs and apply my changes but there are some internal classes used i can't access this way. Don't know how to proceed right now... i want to avoid using a level id to SubScene (Monobehaviour; this is added to entity as component) mapping.
     
  33. cordlc

    cordlc

    Joined:
    Jul 27, 2018
    Posts:
    11
    Apologies if this has been mentioned before (can't seem to find it), is there a way to load a SubScene onto a separate custom World? What's the best way to go about it?

    I tried to add the SubSceneStreamingSystem along with copying the original scene entity and a RequestSceneLoaded, but it doesn't work.

    I'd like to do this because I have separate presentation / logic Worlds, and both will need their own copy of the scene data. I'm using GameObject prefab conversion as a temporary solution, I'd like the performance of SubScenes though.
     
  34. Knightmore

    Knightmore

    Joined:
    May 11, 2012
    Posts:
    227
    So after updating Entities from .31 to .33 the ConvertToEntity workflow broke for me too, as it is converting (Convert and Inject) the entity but the entity is losing all IComponentData I had put on the GO as ComponentDataProxy.

    @Joachim_Ante As the release notes of .32 and .33 don't tell anything about it, what has changed, that this specific out of the box workflow broke?
     
  35. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    857
    The conversion workflow doesn't take the old ComponentDataProxy into account. You will have to implement them in whichever script you have implementing IConvertGameObjectToEntity(samples has examples of this).
     
  36. Knightmore

    Knightmore

    Joined:
    May 11, 2012
    Posts:
    227
    @thelebaron is this somewhere documented inside the release notes, as I couldn't find it there.

    If I understand the samples SpawnFromMonobehaviour and SpawnFromEntity right, I would have to create a MonoBehaviour with IConvertGameObjectToEntity (and maybe a appropiate system to spawn it) for each specific entity I want?
     
    Last edited: Jun 18, 2019
  37. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    857
    yes that's correct. technically you can still use the old GameObjectEntity with your ComponentDataProxy's as some of the examples in the samples still do, but it may be removed at a later date.
     
  38. thedrok_

    thedrok_

    Joined:
    Apr 24, 2017
    Posts:
    14
    I don't know if this is the correct place to be asking this but what's the status on the dedicated entity editing tools mentioned earlier?
     
  39. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    im getting an Error while creating a subscene.
    the Shared GameObject stored within the "Entity Cache/ Resources" Folder is having multiple instances of the Renderer Mesh Proxy and all of them are referencing the same Material and Mesh.


    im getting this Error:
    error when processing 'AsyncLoadSceneJob(C:/Unity_Projects/GameProject - DOTS Physics/Assets/StreamingAssets/EntityCache/bd80eb46203a2d74b9a2355ac5ef1bb2_0.entities)': While loading C:/Unity_Projects/GameProject - DOTS Physics/Assets/StreamingAssets/EntityCache/bd80eb46203a2d74b9a2355ac5ef1bb2_0.entities. Shared Component 1143 was inserted but got a different index 2 at load time than at build time.
    bd80eb46203a2d74b9a2355ac5ef1bb2_0_shared (Unity.Rendering.RenderMeshProxy) vs Unity.Rendering.RenderMesh


     
  40. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    Hello @Joachim_Ante, you said above you where working on adding support for light in the conversion workflow. Is there alos plans to support other tyoes of elemebts like audio, animations, particules,...
    For now I manage a repository of those things in a singleton list and tel the repository when and where to play them through systems. I don't know if there is a better way know. I'm usong the new particule system and I did not find any other way to triger the effect other than what I have discribed as the vfx graph onlys as class underneath and not struct. I can't have direct reference to them in my ecs components.

    So to sum up will the new "DOTS" systems (audio, animations, particules,...) be usable as part of our component data in any way?

    Thanks.
     
    Opeth001 likes this.
  41. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    OK, I think you already answered here.

     
  42. alexnown

    alexnown

    Joined:
    Oct 25, 2018
    Posts:
    22
    It would be nice if SubSceneStreamingSystem.StreamingState component was public. I need check that scene was loaded, do render for preview image and unload this scene by deleting RequestSceneLoaded component.
     
  43. ZoeyDove

    ZoeyDove

    Joined:
    Nov 12, 2018
    Posts:
    11
    Hi!

    This SubScene workflow is exactly what I've always wanted out of Unity.
    1. The ability to setup a scene script-assisted. These scripts can be messy and bloated with extra data.
    2. Complete control over what in the scene is "actually" used at runtime.
    I want to be messy when designing and clean when building, and the SubScene workflow gives me exactly this.

    I strongly dislike packing component settings into assets and worrying about which assets are in Editor folders.

    I know this is meant as an intermediary step towards something else - designed for ECS, but I just wanted to leave feedback that this is wonderful, and having this ability will remain very important.

    Thanks and awesome job~
     
    temps12 likes this.
  44. supron

    supron

    Joined:
    Aug 24, 2013
    Posts:
    67
    ConvertToEntity doesn't work with RectTransform. It throws:

     
  45. rsodre

    rsodre

    Joined:
    May 9, 2012
    Posts:
    229
    I unexpected behaviour is expected, as the UI is not running on DOTS yet.
     
  46. supron

    supron

    Joined:
    Aug 24, 2013
    Posts:
    67
    I made my own DOTS UI solution, but I was forced to write custom UnityEngine.UI->DOTS conversion system, since ConvertToEntity is bugged.
     
  47. addent

    addent

    Joined:
    Apr 27, 2019
    Posts:
    35
    I'm just not understanding the workflow using the ConvertToEntity with the "Convert and Inject Game Object" option.

    Since it only converts the top-most gameobject in the hierarchy, how can I create entities for the child gameobjects and still keep them as gameobjects too?

    Reading through the forums, there's no clear explanation of how to get around this or the logic behind why this isn't allowed. Any help or clarification would be much appreciated.
     
  48. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    857
    I think we're just supposed to do things manually for child gameobjects, at least that's how Ive gone about it.
    Code (CSharp):
    1.  
    2.             var barrel = em.CreateEntity();
    3.             em.AddComponentObject(barrel, barrelTransform); //add child transform manually
    4.             em.AddComponentData(barrel, new Translation()); //have to add all this stuff manually too
    5.             em.AddComponentData(barrel, new Rotation());
    6.             em.AddComponentData(barrel, new LocalToWorld());
    7.             em.AddComponentData(barrel, new CopyTransformFromGameObject());
    8.  
     
    Last edited: Jul 10, 2019
    Mikael-H likes this.
  49. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    My understanding is that the ConvertToEntity flow will convert the entire hierarchy to entities while still leaving the root available in the editor if need be, allowing us to focus on working with the children as entities only. If you do need to keep the child GameObjects I'd suggest adding the ConvertToEntity script onto each child and enable the "Convert and Inject Game Object" you want to keep as well.
     
  50. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    Here are some thoughts on the current implementation and examples:

    The name IConvertGameObjectToEntity was slightly misleading to me at first because the inclusion of "GameObject" in the name made me think this interface was responsible for converting the whole GameObject at once. Making me assume I would only want one script with this interface on each GameObject. But it really seems to be about converting the component data itself and then adding that to an entity. So this made me think maybe it should be named IConvertToComponentData or just IConvertToEntity/Data instead. However, the current name does seem to make more sense after studying it further. So maybe the confusion here was simply my own misunderstanding?

    Surely there must be a better naming convention for the MonoBehaviour to IComponentData relationship. I've never liked the "Component" suffix for the wrapper/proxy implementation and I also dislike the "Authoring" suffix used now for conversion. My current solution for both cases is to use "Data" as a suffix instead for the actual IComponentData, since this aligns perfectly with the ECS type distinction and makes the type obvious in a hybrid project. You can also combine the MonoBehaviour and IComponentData into the same script to get something like this:

    Code (CSharp):
    1.  
    2. public class Health : MonoBehaviour, IConvertGameObjectToEntity
    3. {
    4.     [SerializeField] int m_Value = 100;
    5.  
    6.     public void Convert(Entity entity, EntityManager manager, GameObjectConversionSystem conversion)
    7.     {
    8.         var data = new HealthData { Value = m_Value };
    9.         manager.AddComponentData(entity, data);
    10.     }
    11. }
    12.  
    13. struct HealthData : IComponentData
    14. {
    15.     public int Value;
    16. }
    17.  
    Much better and cleaner than the current example structure I think. You could alternatively use namespaces to address the problem of conflicting/duplicate names here too.

    Code (CSharp):
    1. namespace MyProject
    2. {
    3.     public class Health : MonoBehaviour, IConvertGameObjectToEntity
    4.     {
    5.         [SerializeField] int m_Value = 100;
    6.  
    7.         public void Convert(Entity entity, EntityManager manager, GameObjectConversionSystem conversion)
    8.         {
    9.             var data = new ECS.Health { Value = m_Value };
    10.             manager.AddComponentData(entity, data);
    11.         }
    12.     }
    13. }
    14.  
    15. namespace MyProject.ECS
    16. {
    17.     struct Health : IComponentData
    18.     {
    19.         public int Value;
    20.     }
    21. }
     
    Last edited: Jul 12, 2019
    AdamBebko, lclemens, Mikael-H and 2 others like this.