Search Unity

Official New SubScene & ConvertToEntity workflows

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

  1. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    You have to build using that asset. When you open the the build settings file, it should show build option on the top in the inspector. If you hit the build button on the old build dialog, you are still on the old system.
     
  2. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,643
    is there a recommended way to load and convert a set of prefabs to be created as prefab entities? I create my own solution (using IConvertGameObjectToEntity and IDeclareReferencedPrefabs), but it still needs to rely on the ConvertGameObjectHierarchy method. I wonder if there is a way to create a subscene and serialise prefabs without need to convert them (so that I can also remove the load of the addressables as well) @5argon maybe you know?
     
    Last edited: Feb 9, 2020
    adammpolak likes this.
  3. Nyarlathothep

    Nyarlathothep

    Joined:
    Jun 13, 2013
    Posts:
    398
    Is it possible to have multiple Monobehaviours of the same type attached to a GameObject which is converted? In my system I want to have multiple behaviours (so they can be easily configured in the inspector etc) and then in the
    IConvertGameObjectToEntity
    method they will all be converted to entries in a single buffer on the entity.

    As far as I can see this is impossible to do just because the ConvertToEntity behaviour checks for duplicate behaviours and refuses to convert the entire object (even though there's no actual conversion problem here). Is this some way to simply disable this check?
     
  4. L2GX

    L2GX

    Joined:
    Aug 19, 2016
    Posts:
    42
    I just went and switched my next game over from dots to pure mono.
    I was still using World.Active and now I realised that I’d need a complete new way to transfer game objects to entities, and that there was no guarantee that even that new way would remain functional until release.
    If the samples project was updated and working it’d be a bummer but surmountable.
    Instead we have the new FPS demo that tells you it’s not stable up front...
    So, maybe create a new samples project when there’s enough stability one could swing a release?
     
  5. BackgroundMover

    BackgroundMover

    Joined:
    May 9, 2015
    Posts:
    224
    I want to send some appreciation to the team at Unity behind [GenerateAuthoringComponent]. I'm snooping around the Entities ILPostProcessor and it seems like a lot of cognitive effort and expertise went into crunching down the functionality into the attribute we can just apply.

    I do have a question, I'm getting ready to ask an asset developer if they'll support DOTS, and the generated code aspect (Entities.ForEach job generation in particular) seems like it will be non-trivial. Does anyone know if [GenerateAuthoringComponent] is pretty much how its going to be for Entities 1.0 ? If it was just generating .cs files it'd be one thing, but from what I can tell its doing some kind of in-memory assembly stuff, which is way beyond me. I'd hate to ask them to add support for codegen classes, if something easier is coming down the pipe.

    EDIT: Actually the solution was easier, just putting the ECS code alongside an asmdef file, so the code gets generated into a DLL which the asset is capable of interacting with.
     
    Last edited: Mar 8, 2020
    cultureulterior likes this.
  6. CWatsonT2

    CWatsonT2

    Joined:
    Jan 9, 2019
    Posts:
    114
    I'm trying to build for android using the hybrid renderer and I'm getting the error: "No run step provided for AndroidHybrid." when I try to build and run from my android build asset. I'm also not seeing the subscene objects show on the build. Are there any additional steps I'm missing? I tried the sample files and I can see those when they are built to the device but I haven't been able to figure out what is different between the two projects.

    Edit: What's with the assembly definition files? Do I need those. It's one of the things the demo project has that I don't.
     
    Last edited: Mar 4, 2020
  7. nicolasgramlich

    nicolasgramlich

    Joined:
    Sep 21, 2017
    Posts:
    231
    This works for me (on
    2019.3.3f1
    ):
    upload_2020-3-4_13-41-35.png
     
  8. CWatsonT2

    CWatsonT2

    Joined:
    Jan 9, 2019
    Posts:
    114
    I appreciate that. My settings appear to be the same but I'm still getting the error:

    Run Android-Build failed.
    No run step provided for AndroidHybrid.

    Anyone know what that means?

    UPDATE: It seems it might have something to do with the BuildPipeline but I can't find any documentation about what that is or find it in the ECSSamples. Can anyone help?

    Updated Update: I added the RunStepNotImplemented to the androidHybrid build pipeline asset and updated the hybrid renderer package to 0.3.5 and now it's building.
     
    Last edited: Mar 6, 2020
  9. aveakrause

    aveakrause

    Joined:
    Oct 3, 2018
    Posts:
    70
    Subscene workflow is still TOTALLY broken.
    While a subscene is open, I can see that my component data is properly being added to my entities. When I close that subscene some of my component data is just plain out missing.

    BRING BACK THE FORCE CACHE RELOAD. WE REQUIRE IT TO FIX THESE ERRORS.
     
    Tunkali, filod and e199 like this.
  10. CWatsonT2

    CWatsonT2

    Joined:
    Jan 9, 2019
    Posts:
    114
    My results when using subscenes for VR on the Quest weren't good. I went from 30FPS without it to 10FPS with 1 subscene. I've abandoned entity conversion for now. I was hoping this would give me the performance boost I needed but no luck.
     
  11. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    @CWatsonT2 have you profiled why precisely this is happening?
     
  12. CWatsonT2

    CWatsonT2

    Joined:
    Jan 9, 2019
    Posts:
    114
    Not really. If I run it via the link cable and then profile it it runs amazingly fast. It only chokes when I build it onto the quest. I didn't profile that beyond watching the fps crash. Then I reverted my project to pre-hyrbid because I've already spent too much time on it.
     
  13. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    Unfortunately without any actual profiling it's hard to tell if the build process is being run correctly. With the conversion workflow there's bound to be performance spikes if entities get constructed through instantiating prefabs, but it doesn't sound like this is your issue. With the link cable, my understanding is that it's actually not building to the Quest and rather running the build on your computer and streaming data to- and from the Quest. It could be that the build for the Quest isn't correctly compiling the subscenes which could be the root of the issue.
     
  14. tarahugger

    tarahugger

    Joined:
    Jul 18, 2014
    Posts:
    129
    Getting these warnings after creating SubScenes; seems like a bug as these won't be used like regular scenes?

    Code (CSharp):
    1. Your current multi-scene setup has inconsistent Lighting settings which may lead to different lighting when loading scenes individually or in a different order! Consider homogenizing the following:
    2. 1/3 scenes have Auto baking enabled.
    3. 2/3 scenes use different skyboxes.
    4.  
     
    lclemens likes this.
  15. Cynicat

    Cynicat

    Joined:
    Jun 12, 2013
    Posts:
    290
    Question for the ECS Team: What is the workflow now for working with GameObjects from systems? One of the most useful workflows for me before was being able to attach GameObjectEntity and iterate over GameObjects. That way I could just work as normal with GameObjects and then I could migrate what really needed the performance over the entities representation.

    I'd really, really like to use the new SystemBase API in concert with GameObjects, because the Job.WithCode() would be incredible for pulling main logic off the main thread while still getting all the existing features/workflow of unity.
    eg:
    Code (CSharp):
    1. protected override void OnUpdate() {
    2.     Entities.ForEach((Transform transform, Rigidbody rigidbody) => {
    3.         // setup planet gravity job data
    4.     }).Run();
    5.  
    6.     Job.WithCode(() => {
    7.         // compute planetary gravities
    8.     }).Schedule();
    9.  
    10.     Entities.ForEach((Rigidbody rigidbody) => {
    11.         // apply gravities to rigidbodies
    12.     }).Run();
    13. }

    ECS currently lacks many core features and the conversion workflow requires lots of boilerplate just to get access to them on the gameobject side.

    I have to be honest this has been massively frustrating to try to figure out. I've tried writing tons of conversion systems, every single configuration I could think of for subscenes. But they all seem to make the assumption i'm making some tech demo where it's ok to just, drop 90% of the existing features in unity.

    ConvertAndInject seems like it would be for exactly this, but it just duplicates every component. Now you have two renderers, transforms, etc... I really don't get how that would ever be useful.

    If there is no workflow for querying gameobjects, can i request an option in the convert to entities dropdown that's just "Linked Entity" or something? I'm not going to drop all the features of existing unity, all my code is there already. I was loving getting to convert over bit by bit as needed, but this all or nothing approach is hellish to actually try to make things with.

    Anyway, if anybody knows of an actual solution i'd love to hear it.
     
    PixelMind and elJoel like this.
  16. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    Hello I'm having an issue with a subscene.

    I have a custom auhtoring component that allow me to add a list of struct. When the authoring component is converted to an entity, the list of struct is stored in a IComponentData class that I then use to initialize some data at runtime.

    When the scene is opened in the editor (edit mode) everything work fine but when I close it I get this error :

    Error when processing 'AsyncLoadSceneJob(VirtualArtifacts/Extra/23/23319d88e2738c325162389e980f80b7.0.entities)': System.NullReferenceException: Object reference not set to an instance of an object
    at Unity.Entities.TypeManager.GetTypeInfo (System.Int32 typeIndex) [0x00001] in C:\Users\Marc HANICOT\Documents\GitHub\MGM\Library\PackageCache\com.unity.entities@0.9.1-preview.15\Unity.Entities\Types\TypeManager.cs:348
    at Unity.Entities.Serialization.SerializeUtility.DeserializeWorld (Unity.Entities.ExclusiveEntityTransaction manager, Unity.Entities.Serialization.BinaryReader reader, System.Object[] unityObjects) [0x00110] in C:\Users\Marc HANICOT\Documents\GitHub\MGM\Library\PackageCache\com.unity.entities@0.9.1-preview.15\Unity.Entities\Serialization\SerializeUtility.cs:82
    at Unity.Scenes.AsyncLoadSceneOperation+AsyncLoadSceneJob.Execute () [0x00057] in C:\Users\Marc HANICOT\Documents\GitHub\MGM\Library\PackageCache\com.unity.entities@0.9.1-preview.15\Unity.Scenes.Hybrid\AsyncLoadSceneOperation.cs:98
    UnityEngine.Debug:LogWarning(Object)
    Unity.Debug:LogWarning(String) (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/Stubs/Unity/Debug.cs:15)
    Unity.Scenes.SceneSectionStreamingSystem:UpdateLoadOperation(AsyncLoadSceneOperation, World, Entity) (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Scenes.Hybrid/SceneSectionStreamingSystem.cs:373)
    Unity.Scenes.SceneSectionStreamingSystem:processActiveStreams() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Scenes.Hybrid/SceneSectionStreamingSystem.cs:276)
    Unity.Scenes.SceneSectionStreamingSystem:OnUpdate() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Scenes.Hybrid/SceneSectionStreamingSystem.cs:480)
    Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/ComponentSystem.cs:108)
    Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/ComponentSystemGroup.cs:134)
    Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/ComponentSystemGroup.cs:114)
    Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/ComponentSystem.cs:108)
    Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/ComponentSystemGroup.cs:134)
    Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/ComponentSystemGroup.cs:114)
    Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/ComponentSystem.cs:108)
    Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.9.1-preview.15/Unity.Entities/ScriptBehaviourUpdateOrder.cs:200)

    Now all the data I need is in fact a list of list in that the form you'll see below. I found a workaround that make it work in build and with the scene closed in hte editor by adding a dummy int to the thing I store.

    The IComponentDataClass
    Code (CSharp):
    1. using System;
    2. using Wayn.Mgm.Events.Registry;
    3. using Unity.Entities;
    4. using System.Collections.Generic;
    5.  
    6. [Serializable]
    7. public class EffectComponentData : IComponentData
    8. {
    9.     public List<ISelfRegistringAuhtoringComponent> listOfManagedBuffer = new List<ISelfRegistringAuhtoringComponent> ();
    10. }
    11.  
    The element of the stored list in the IComponentDataClass :
    Code (CSharp):
    1. using Wayn.Mgm.Events;
    2. using System;
    3. using Wayn.Mgm.Events.Registry;
    4. using Unity.Entities;
    5. using System.Collections.Generic;
    6.  
    7. [Serializable]
    8. public class EffectComponentDataElement<ELEMENT, BUFFER> : ISelfRegistringAuhtoringComponent
    9.      where ELEMENT : IRegistryElement
    10.      where BUFFER : struct, IEffectReferenceBuffer
    11. {
    12.     //public int number; // Without this, the subscene fails to load
    13.  
    14.     public List<ELEMENT> elements;
    15.  
    16.     public EffectComponentDataElement()
    17.     {
    18.         elements = new List<ELEMENT>();
    19.         //number = elements.Count;
    20.     }
    21.     public EffectComponentDataElement(List<ELEMENT> elements)
    22.     {
    23.         this.elements = elements;
    24.     }
    25.  
    26.     public void Register(EntityCommandBuffer ecb, Entity entity)
    27.     {
    28.         var buffer = ecb.AddBuffer<BUFFER>(entity);
    29.         foreach (var effect in elements)
    30.         {
    31.             buffer.Add(new BUFFER() { EffectReference = EffectRegistry.Instance.AddEffect((IEffect)effect) });
    32.         }
    33.     }
    34. }
    35.  
    Is that a bug are can't we have only list as serialzed data in subscenes ?
     
  17. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    Is it possible to create a subscene during the runtime (e.g. procedural generated scene) and serialize it, write it to disk and load it on the next run?
     
  18. lmml

    lmml

    Joined:
    May 2, 2020
    Posts:
    6
    Hi there, I was reading this thread and I think u could help me with my problem. I am working on a kind of plugin package for unity so i was wondering to convert certain gameobjects on entities to use ecs. But my problem is that i want to do that on editor and not on runtime so i was thinking that maybe subscenes were my solution but i dont know how to attach gameobjects to a subscene on editor via code. I hope u can understand me , the main idea is to get on editor certain entities from gameobjects. I am noob on DOTS so dont be so hard with me :)
     
  19. Krajca

    Krajca

    Joined:
    May 6, 2014
    Posts:
    347
    Is there a way to predict the order of converted objects and components? I'm asking because I need some data before others to be able to properly initialize my entities. What are the best practices for data conversion?
     
  20. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    It seems what you might be describing is a custom conversion system. It's not too difficult to write one and I think there is mention in the documentation of how to do something like that. I'm assuming you have authoring components that push data into the EntityManager that you need for other components to be fully ordered. Having a conversion system you could then schedule it to run after the main conversion system, which should yield a state where you're able to handle the correct items as expected.
     
  21. Krajca

    Krajca

    Joined:
    May 6, 2014
    Posts:
    347
    Yeah, that's the case. I found the option to manually call the conversion of an object. It will suffice I think.
     
  22. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    154
    I am using Unity 2020.1.0b12.3931 and Entites 0.11.0-preview.7


    So, I'm a little confused as to how to affect the Entities that exist after I close a Sub-Scene.

    For example, I have this MonoBehaviour script attached to each one of my GameObjects.

    Code (CSharp):
    1. using Unity.Entities;
    2. using UnityEngine;
    3.  
    4. public class ItemProxy : MonoBehaviour, IConvertGameObjectToEntity
    5. {
    6.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    7.     {
    8.         dstManager.SetName(entity, gameObject.name);
    9.     }
    10. }
    However, according to the EntityDebugger it only seems to affect the Entities while the Sub-Scene is in LiveLink mode. As soon as I turn it off, the Entities created no longer seem to go through my Convert method, as their names remain unchanged.

    This same behavior happens if I attempt to add new Components. The Entities while the Sub-Scene is in LiveLink mode has the new Components, but the ones when LiveLink mode is off do not.

    Am I misinterpreting how Subscenes are supposed to work? It seems like my Convert method never fires when the SubScene's LiveLink is off.




    Edit:

    I just discovered if you put this attribute above your
    IConvertGameObjectToEntity
    it seems to fire the
    Convert
    method when LiveLink mode is off everytime you increase the second paramter (which is a version number).

    [ConverterVersion("joe", 2)]


    This did not seem to affect Setting the Entity name, but it did allow me to add my own
    IComponents
    and have them appear on the Entities when LiveLink mode was off.
     
    Last edited: Jun 15, 2020
    Quatum1000 likes this.
  23. nicolasgramlich

    nicolasgramlich

    Joined:
    Sep 21, 2017
    Posts:
    231
    I might be wrong, but I think the reason you don't see name show up in closed subscenes is because they're effectively turned into a runtime binary format and entity names are editor only.
     
  24. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    I'm sticking since long time with the same issue. When closing a SubScene all data are converted into a raw entity format. The loading process of the SubScene entity data is also handled by the entity manager internally..

    I thought about to add a special iComponent with the special value to identify the entity later, when reading through the entities, by mono or job. This is a ugly behavior and not very efficient, but I did not get the component back for reading the special value. They are simply filtered out.

    An efficient way would be to pass a double index to a component and entity. This will make sure if entities are re- or moved from the entity manger, it's possible to access them as long as they are exist and it doesn't matter what position they own. You can access them directly at any time, instead if iterating through all.

    If anyone have a solution for this, or able to do that would be great!

    If you have an idea to solve the behavior to access and find a specified enyity in the EM by mono or job that would be absolutely awesome.

    Currently a SubScene is isolated in the EM and there are no abilities to access them from the outside-code-world without hacking the original dots system code.
     
  25. nasos_333

    nasos_333

    Joined:
    Feb 13, 2013
    Posts:
    13,360
    Hi,

    I am trying to convert old code to unity 2019.3 and get a million errors, everything seem changed and broken.

    Is there a manual for the conversion to the latest versions ?

    I get "Render Mesh Proxy has been deprecated, Please use the new gameobject to entity conversion workflows instead." and some similar warnings.

    The problem is that i created all entities without a gameobject, so now seems to not working.

    Here is the code where i try to create the particles at run time, and the particles prefab scripts

    Code (csharp):
    1.  
    2.   private void AddParticles(int _amount)
    3.     {
    4.         NativeArray<Entity> entities = new NativeArray<Entity>(_amount, Allocator.Temp);
    5.         manager.Instantiate(sphParticlePrefab, entities);
    6.         for (int i = 0; i < _amount; i++)
    7.         {
    8.             manager.SetComponentData(entities[i], new Translation { Value = new float3(i % 16 + UnityEngine.Random.Range(-0.1f, 0.1f), 2 + (i / 16 / 16) * 1.1f, (i / 16) % 16) + UnityEngine.Random.Range(-0.1f, 0.1f) });
    9.         }
    10.         entities.Dispose();
    11.     }
    12.  
    Any help on the conversion would be greatly appreciated.

    Thanks in advance
     

    Attached Files:

    • sph.jpg
      sph.jpg
      File size:
      125.3 KB
      Views:
      459
  26. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    You can remove the following components:
    • Game Object Entity
    • Translation
    • RenderMeshProxy
    Then make sure to add the traditional rendering components you would've normally used for the GameObject. I'm specifically referring to the ones mentioned in this documentation.

    Lastly, depending on your use-case, make sure you add the ConvertToEntity component which will tell the Entities package it should convert this object to an entity. The conversion pipeline will pull all the translation and rotation from the GameObject's Transform component and convert it to the ECS counterparts. It will also take the Mesh Renderer component and convert it to the relevant rendering components if you have the Hybrid Rendering package installed.

    I'm not completely sure where you're doing calling the `AddParticles` method from, but there might be some more things required to correctly replicate the prefab in the EntityManager so that it can quickly and easily instantiate multiple entities. There has been lots of mention on this exact thread about how the conversion pipeline works and I do think it's referenced somewhere in the documentation, but I'm not finding it right now.
     
  27. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    Does anyone know why this doesn't work?
    Code (CSharp):
    1. public class GOEProxy : MonoBehaviour, IConvertGameObjectToEntity
    2. {
    3.     public Entity _entity;
    4.     public int index;
    5.     public int version;
    6.  
    7.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    8.     {
    9.         this._entity = entity;
    10.         this.index = entity.Index;
    11.         this.version = entity.Version;
    12.  
    13.         conversionSystem.AddHybridComponent(this);
    14.     }
    15.  
    16.     void Update() {
    17.         if (Time.frameCount == 100)
    18.             Debug.Log($"({_entity}) - ({index}:{version})");
    19.             // outputs: (Entity.Null) - (0:1)
    20.     }
    21. }
    Why is _entity getting null'd while the other two instance variables keep their values? This is on a GameObject in the scene with ConvertAndDestroy on it.
    I need to be able to access the Entity from the GameObject. I can fudge this by just using the exploded variables but I can't understand why _entity is not preserved. Is Unity actively destroying it during cloning or is it just not serializable in this context?
    Is there some other way like GetPrimaryEntity already built into the api where we can get the Entity from a GameObject outside of conversion?
     
  28. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    Check der variables of the entity. Entity is an struct and can't be null and have always an value. You do not have to save the index and version separately. Even if the entity is destroyed, _entity retains its value.

    ConvertAndDestroy means the GameObject will destroy after convert. index=0 can be equal to entity.Null.

    Maybe the update output before the conversion?
    You can create an test variable and set in den convert method and output the value, or use an breakpoint in visual studio.
     
  29. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    he is waitting for the 100th frame to ouput the debug so it's not impacted by the order of update/convert.
    I agree at this point I dont' see why it would not work, I did similar thing for input management and ahd no issue...
    I would try with convert and inject to see if that works.
    Also, not likely but, I would try with a different naming for the Entity variable, one not starting with '_'.
    Or try to make it private / non serialized.
    maybe the editor update it avert loading the scene.
     
  30. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    Thanks for the responses.
    Yes by null'd I just meant defaulted, not null referenced. I'm storing the index/version variables just to show that they keep their value during cloning whereas Entity does not. Unfortunately I don't have debug capabilities atm.
    Changing name, visibility, serialization makes no difference and Convert and Inject works but that's as expected.
    I'm pretty sure the problem is related to the AddHybridComponent process which clones these objects under the hood but I don't get why it would default just Entity values. Probably related to it maintaining internal Entity references during conversion or something.
    Even if I wrap Entity in a struct, Unity defaults the entire struct. Go figure.
    Code (CSharp):
    1. public class GOE : MonoBehaviour, IConvertGameObjectToEntity
    2. {
    3.     struct StructEntity {
    4.         public Entity myEntity;
    5.         public int index;
    6.         public int version;
    7.  
    8.         public StructEntity(Entity entity) {
    9.             myEntity = entity;
    10.             index = entity.Index;
    11.             version = entity.Version;
    12.         }
    13.     }
    14.  
    15.     StructEntity structEntity;
    16.  
    17.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    18.     {
    19.         this.structEntity = new StructEntity(entity);
    20.         conversionSystem.AddHybridComponent(this);
    21.     }
    22.  
    23.     void Update() {
    24.         if (Time.frameCount == 100) {
    25.             Debug.Log($"({structEntity.myEntity}) - ({structEntity.index}:{structEntity.version})");
    26.             // outputs: (Entity.Null) - (0:0) <- whole struct is defaulted, not just myEntity
    27.         }
    28.     }
    29. }
     
  31. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    Try an Debug.Log in the Convert method and compare with the Update version. if it different, then AddHybridComponent does something.

    Yo can also change the structEntity to an Property and set a Log in the setter to check if it called multiple times.
     
  32. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    Thanks runner, yes they're different in convert and update. I just didn't add it to the posted code.
    Turns out it was a serialization issue. I just assumed simple structs would be automatically serialised but that's not the case.
    This works.
    Code (CSharp):
    1. public class GOE : MonoBehaviour, IConvertGameObjectToEntity, ISerializationCallbackReceiver
    2. {
    3.     public Entity Entity;
    4.  
    5.     [SerializeField]
    6.     private int _index, _version;
    7.  
    8.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    9.     {
    10.         this.Entity = entity;
    11.         conversionSystem.AddHybridComponent(this);
    12.     }
    13.  
    14.     public void OnBeforeSerialize()
    15.     {
    16.         _index = Entity.Index;
    17.         _version = Entity.Version;
    18.     }
    19.  
    20.     public void OnAfterDeserialize()
    21.     {
    22.         Entity.Index = _index;
    23.         Entity.Version = _version;
    24.     }
    25. }
     
  33. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    try this in that case :

    [field:SerializeField] public Entity Entity;
     
  34. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    Thanks. I tried all various combinations of serialize but nothing worked unless the struct itself had the [Serializable] attribute which Entity does not.
    This is good enough for me for now anyway
     
  35. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    Can we have an overload for `public static Entity ConvertGameObjectHierarchy(GameObject root, GameObjectConversionSettings settings)` which takes an IList of GameObject and return an entities list ?

    Can be useful for performance reason to not convert one by one each gameobject
    Context : I can't use subscene and I need to do modifications over my converted prefab just after conversion
     
  36. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Use IConvertGameObjectToEntity with IDeclareReferencedPrefabs. The primary object you convert you could just ignore, it serves to hold all the referenced prefabs which is basically your list. Then call conversionSystem.GetPrimaryEntity on each of the referenced prefabs in Convert to get the entities.
     
  37. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    The whole reason why subscenes prove to be more performant isn't that it is converting multiple objects at the same time, but rather that when the game starts up it doesn't have to do any conversion at all. A subscene conversion happens at build time which creates an ECS ready binary file which is loaded directly into memory.

    I'm a little unsure why the need for modifications though. Instead of trying to hook into just after the conversion step, it makes more sense for me to hook into just before conversion, which is achievable with IConvertGameObjectToEntity with IDeclareReferencedPrefabs. You could even write your own conversion system that slots into the conversion step and do this. This ultimately sounds like either the conversion pipeline doesn't support what you're trying to do or you haven't exactly found the parts of the pipeline that you can utilize.

    I'd highly advise you read through this blog post by @5argon to get a better understanding of the tools available, especially if you need to do some further massaging of data during the conversion process.
     
    florianhanke likes this.
  38. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    I know that, I just anticipate comments like "use subscene"

    I know perfectly 5argon articles which have a great value for ECS users.

    IConvertGameObjectToEntity is used to convert gameobject to entity but that not my problem, my problem is before that.
    I don't want create 10000 conversion world because I have 10000 prefabs to convert.
    From an explication of @eizenhorn, I have realized that API "GameObjectConversionUtility.ConvertGameObjectHierarchy" is not efficient if you have multiple GO.
    In his side, he is doing what snacktime said.

    Indeed this approach does the job :)
    But from my point of view, it's far more complicated ( in comparison, we even call it a 'hack') that with a ConvertGameObjectHierarchy variation.
     
  39. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    The main point I'm trying to make is that I don't think there would be much of a performance impact between converting a single gameobject or converting many. You're still going to have stutters on startup because the conversion step is happening.

    Nothing is stopping you from writing a static method that can convert many entities and the reality is that if Unity does provide it they will probably still use the hierarchy conversion for the process and do a simple iteration on all.

    The most important part for you would be to test this and see if it's performing badly. It's sounding more like you're making a suggested based off an assumption that it would be more performant without providing your test case and how it's performing badly.
     
  40. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    679
    Also, for those modifications just after the conversion you can write a conversion system that runs after the usual conversion to do those extra modifications (unless you are relying on some runtime data, then what snacktime suggested will fit you better).
     
  41. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    If I can reduce this just with a API swap, I take it because it's almost free.

    Yes, CreateConversionWorld and Convert method are internals in 'GameObjectConversionUtility' class.
    I can duplicate them but I don't want maintain that with so many API changes.
    To go further, in 'GameObjectConversionUtility', you can already ask for GO or Scene conversion via public API so
    all are already in place for doing what I ask. We just need a new overload.

    In reality, ConvertGameObjectHierarchy already do what your suggesting.
    So from my code understanding, it makes sense to have convert API for One gameobject, a list/array of gameobjects and scene.

    Code (CSharp):
    1.         public static Entity ConvertGameObjectHierarchy(GameObject root, GameObjectConversionSettings settings)
    2.         {
    3.             using (s_ConvertScene.Auto())
    4.             {
    5.                 Entity convertedEntity;
    6.                 using (var conversionWorld = CreateConversionWorld(settings))
    7.                 using (var conversion = new Conversion(conversionWorld))
    8.                 {
    9.                     using (s_CreateEntitiesForGameObjects.Auto())
    10.                         conversion.MappingSystem.AddGameObjectOrPrefab(root);
    11.  
    12.                     Convert(conversionWorld);
    13.  
    14.                     convertedEntity = conversion.MappingSystem.GetPrimaryEntity(root);
    15.  
    16.                     settings.ConversionWorldPreDispose?.Invoke(conversionWorld);
    17.  
    18.                     s_DestroyConversionWorld.Begin();
    19.                 }
    20.                 s_DestroyConversionWorld.End();
    21.                 return convertedEntity;
    22.             }
    23.         }

    it's exactly that. I "compile" raw datas at runtime for modding and others reasons
     
    Last edited: Aug 6, 2020
    brunocoimbra likes this.
  42. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    It will, and the difference will be very noticeable. Using GameObjectConversionUtility.ConvertGameObjectHierarchy for many objects even just for 100 it's a bad thing, GameObjectConversionUtility.ConvertGameObjectHierarchy fine for converting couple GO as it creates and destroys whole conversion pipeline for every call, for big amount of converted objects it must be subscene (if possible) or only one conversion through utility GO which will convert everything through one conversion world iteration, and in this case, there are no noticeable stutters at all (in our game for ~300 prefabs from addressable we haven't any stutters, for GameObjectConversionUtility they will (we tested it a long time ago - GameObjectConversionUtility slow, and tested it again when we did addressable converter)
     
  43. elJoel

    elJoel

    Joined:
    Sep 7, 2016
    Posts:
    125
    Is there any way to quickly select all GameObjects in a Subscene?
     
  44. Rob-A

    Rob-A

    Joined:
    Aug 7, 2012
    Posts:
    33
    Does ECS conversion has a way to quickly see what types are we having a GameObjectConversionSystem for?
     
  45. Dipak_Sorathia

    Dipak_Sorathia

    Joined:
    Jul 6, 2014
    Posts:
    4
    Hi there, I'm getting multiple texture/mesh loading into memory even if different SubScene using same assets.
    The scenario is like when 2 SubScene sharing same texture but when loading both scene it treats as 2 different textures.
    If 10 SubScene sharing same texture it treats as 10 different asset and so on.
    In my case I've 20x20 tiled mesh terrain and vegetation which loads/unload dynamically.
    So all of the SubScene treats it's assets under it as separate causing very high memory usage.
    Can anyone confirm this?
    I'm using 2019.4.6f1 LTS and Hybrid Renderer version 0.3.4[preview.24]
    Here is profile screen shot. Which is from two subscene sharing same texture but it loads separately. ProfilerShot.png
     
  46. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    Last edited: Sep 4, 2020
    Quatum1000 and Dipak_Sorathia like this.
  47. Dipak_Sorathia

    Dipak_Sorathia

    Joined:
    Jul 6, 2014
    Posts:
    4
    Profiled in windows build.

    -edit-
    After updating package and now issue gone [tested in 2020.1.3f1]. But some how I can't see latest packages update in package manager. Need to edit manifest for specific packages.
     
    Last edited: Sep 4, 2020
    lclemens likes this.
  48. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    I've just updated to NetCode 0.4.0, where it says: "please use the sub-scene conversion workflow instead".

    I've been having trouble finding any official documentation regarding the sub-scene conversion workflow (also looking for info how to mark pieces of the scene hierarchy as client or server only). Could anyone point me to it?
    Also, does anyone know what happened to @5argon's blog which has been mentioned several times in this thread? For example, https://gametorrahod.com/game-object-conversion-and-subscene/ appears to be unreachable.
     
  49. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Oh! My 5$ Digital Ocean running that Ghost blog reached 1GB RAM limit for most of latter half of this year and I need to manually restart it from time to time. There are even readers that mail me to restart it whenever it happen! So unless, I won't realize it is down until I decided to write something new but I was busy with new work lately I didn't add anything for quite sometime.. I never thought this day would come but I just upgrade it to the tier with 2GB RAM. Unless DOTS gets extremely mainstream I don't think we can exhaust it this time!
     
    apkdev, MNNoxMortem, MaNaRz and 5 others like this.
  50. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Hi, is this fix for SubScene2 only?

    Our project is using the standard render pipeline and SubScene - PC, I'm afraid that the fix is only done for SubScene2 and Udrp. And we are using a lot of scene with the same material and textures. OMG!

    Is there any acknowledge about id this issue with double loading happen also in SubScene? Were working now since 5 years on the PC stuff and transferring to HDRP is impossible at this stage.