Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Is There Any Way to Enable/Disable IEnableable Components from Baker

Discussion in 'Entity Component System' started by tgkthefirst, Oct 15, 2022.

  1. tgkthefirst

    tgkthefirst

    Joined:
    Dec 27, 2020
    Posts:
    13
    I've been searching the scripting API to see If I can access the enableable components from baker, while I can add those components to the Entity, however I cannot find any methods regarding enableable components from baker
    One solution would be to Enable/Disable said components from a system, But I really find that counterintuitive.
    Is this the intended way? Or am I missing something?
     
  2. scottjdaley

    scottjdaley

    Joined:
    Aug 1, 2013
    Posts:
    152
    I don't think there is any way to do this at the moment. IEnableableComponents will be enabled by default on the baked entities. I haven't tested this myself, but I also heard that disabling the component in a baking system does not work either. If so, the option at the moment is to disable the component at runtime.

    I really hope that they add a SetComponentEnabled(bool) to Baker in a future version.
     
    Krajca and tgkthefirst like this.
  3. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    For now use Baking systems for that (
    [WorldSystemFilter(WorldSystemFilterFlags.BakingSystem)]
    ) where you can safely use ECB, EntityManager etc. and change enablable components state.
     
    tgkthefirst likes this.
  4. tgkthefirst

    tgkthefirst

    Joined:
    Dec 27, 2020
    Posts:
    13
    Thanks @eizenhorn, I didn't have the time but I'm gonna check the baking systems out tomorrow
     
  5. scottjdaley

    scottjdaley

    Joined:
    Aug 1, 2013
    Posts:
    152
    This didn't work in my testing. Calling SetComponentEnabled(entity, false) in a baking system resulted in the component still being enabled at runtime.

    Here is the code I used to test with:

    Code (CSharp):
    1. public class EnableableComponentAuthoring : MonoBehaviour
    2. {
    3.     public bool Enabled = true;
    4.     public float2 Value;
    5. }
    6.  
    7.  
    8. public class EnableableComponentBaker : Baker<EnableableComponentAuthoring>
    9. {
    10.     public override void Bake(EnableableComponentAuthoring authoring)
    11.     {
    12.         AddComponent(new MyEnableableComponent { Value = authoring.Value });
    13.         AddComponent(new MyEnableableComponentBake { Enabled = authoring.Enabled });
    14.     }
    15. }
    16.  
    17. [TemporaryBakingType]
    18. public struct MyEnableableComponentBake : IComponentData
    19. {
    20.     public bool Enabled;
    21. }
    22.  
    23. public struct MyEnableableComponent : IComponentData, IEnableableComponent
    24. {
    25.     public float2 Value;
    26. }
    27.  
    28. [WorldSystemFilter(WorldSystemFilterFlags.BakingSystem)]
    29. // [UpdateInGroup(typeof(PostBakingSystemGroup))]
    30. public partial class MyEnableableComponentBakingSystem : SystemBase
    31. {
    32.     protected override void OnCreate()
    33.     {
    34.         RequireForUpdate<MyEnableableComponentBake>();
    35.     }
    36.  
    37.     protected override void OnUpdate()
    38.     {
    39.         ComponentLookup<MyEnableableComponent> lookup = SystemAPI.GetComponentLookup<MyEnableableComponent>();
    40.         Entities.WithEntityQueryOptions(EntityQueryOptions.IncludePrefab)
    41.             .ForEach(
    42.                 (Entity entity, in MyEnableableComponentBake bake) =>
    43.                 {
    44.                     Debug.Log(
    45.                         $"Baking: Setting enabled bit on {EntityManager.GetName(entity)} {entity} to {bake.Enabled}"
    46.                     );
    47.                     lookup.SetComponentEnabled(entity, bake.Enabled);
    48.                     bool enabled = lookup.IsComponentEnabled(entity);
    49.                     Debug.Log($"Baking: Enabled bit on {EntityManager.GetName(entity)} {entity} is {enabled}");
    50.                 }
    51.             )
    52.             .WithoutBurst()
    53.             .Run();
    54.     }
    55. }
    Authoring setup:
    upload_2022-10-16_12-26-34.png

    Output from baking:
    Baking: Setting enabled bit on Quad Entity(21:1) to False
    Baking: Enabled bit on Quad Entity(21:1) is False


    Entity inspector at runtime:
    upload_2022-10-16_12-26-2.png

    It would seem that when the baked entities are copied over to the runtime world, the enabled bits are lost and default to true. Even moving the baking system to PostBakingSystemGroup did not work.

    If there is a way around this, I would love to know. The only option that has worked for me is disabling the component at runtime.
     
  6. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    908
    Enabled flags are not serialized while baking.
     
    TWolfram likes this.
  7. TWolfram

    TWolfram

    Joined:
    Aug 6, 2017
    Posts:
    75
    That seems like a bug/oversight to me, do you happen to know of any particular reason why this behavior might be intended? Seems like working around this would be a pain in the ass.
     
  8. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Well, while I haven't tested that yet (as we on 0.51 and 1.0 I've touched on my free time just for checking changed stuff :D), but it definitely feels like a bug, and they should be serialized.
    @s_schoener can you please give a comment about that?
     
  9. mattdymott

    mattdymott

    Joined:
    Dec 27, 2016
    Posts:
    29
    I copied your test code and tried it, only works if you close the subscene.
     
    TWolfram likes this.
  10. scottjdaley

    scottjdaley

    Joined:
    Aug 1, 2013
    Posts:
    152
    Oh you're right, forgot to test with the subscene closed. It seems like closing the subscene does actually result in correctly baked disabled IEnableableComponents. That definitely sounds like a bug.

    For what its worth, I also tested this with prefab game objects. I have a prefab with the "EnableableComponentAuthoring" MonoBehaviour that bakes the disabled component in a baking system. Then I have a spawner game object in the subscene that references this prefab. When the subscene is open, the entity version of the prefab has the incorrect enabled bit. But when the subscene is closed, the prefab is correctly disabled. Entities instantiated from this prefab will keep whatever enabled bit the prefab had (which is dependent on the subscene being opened or closed).


    Somewhat unrelated, but the documentation for EntityCommandBuffer.SetComponentEnabled says that it can not set enabled bits on a prefab:


    /// <remarks> Behavior at Playback: Will throw an error if this entity is destroyed before playback,
    /// if this entity is still deferred, if the entity has the <see cref="Prefab"/> tag, or if the entity doesn't have the component type.</remarks>


    From my testing, this is not true. All of the methods of setting enabled bits (EntityManager, ComponentLookup, and EntityCommandBuffer) appear to work as expected for entities with the Prefab tag.
     
    TWolfram and mattdymott like this.
  11. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    908
    Good job finding the bug!
    I've tested this 3 times with different methods but never closed the subscene! :rolleyes:
     
    TWolfram and mattdymott like this.
  12. mattdymott

    mattdymott

    Joined:
    Dec 27, 2016
    Posts:
    29
    I'm only closing my subscenes because of another bug where physics objects just fall through the floor if I click on them! I keep them open normally.
     
    TWolfram likes this.
  13. TWolfram

    TWolfram

    Joined:
    Aug 6, 2017
    Posts:
    75
    I've been making a habit of closing my subscenes whenever possible; feels like the editor is much more stable whenever they're closed.
     
  14. mattdymott

    mattdymott

    Joined:
    Dec 27, 2016
    Posts:
    29
    Until you get the 'Loading Entity Scene failed because the entity header file couldn't be resolved' error message and you have to open the subscene or clear the entity cache which is now moved in a preference option instead of the menu.
     
    zandalus and WAYNGames like this.