Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Potential bug with Disabled component?

Discussion in 'Project Tiny' started by SorenPP, Nov 20, 2020.

  1. SorenPP

    SorenPP

    Joined:
    Nov 13, 2020
    Posts:
    3
    Hey

    Has anybody else had problems with entities sometimes not behaving correctly after having Disabled removed or am I using it wrong?

    I am having some issues that I am having a hard time identifying whether I am doing something wrong or if it is a bug in the engine.
    It looks like systems sometimes fails to recognise that entities have had Disabled removed. I have experienced two cases related to this.

    First I have a character entity with a rigidbody that have a bunch of sprite entities as children with some nested under each other. They all start out with the Disabled component which gets removed together at some point in the game. These entities were the only ones that used parenting and this used to work fine. At some point I tried to add a child to another unrelated entity and after I did this the sprite entities described above stopped following the parent after they have Disabled removed (they still appear on screen so the removal of Disabled seems to work). I also tried to add an empty child to an empty gameobject and it seems like whenever there are other objects using parenting the original entities will fail to start updating the parent relation after Disabled is removed. If I remove the other nested objects it works fine again.

    The second case I experienced was with a custom system that uses RequireForUpdate to make sure the system only updates when the entities with the relevant components are not disabled (with the Disabled component) using this code
    RequireForUpdate(GetEntityQuery(ComponentType.ReadOnly<LevelSelector>()));
    This used to work but after refactoring some scenes it stopped catching that the entities had the Disabled component removed. (They start out disabled and get the component removed later). Instead I tried to use the check
    if (GetEntityQuery(ComponentType.ReadOnly<LevelSelector>()).CalculateEntityCount() <= 0) return;
    at the start of OnUpdate and that seems to work as a workaround although now I cant rely on OnStartRunning.

    I am having a hard time debugging this without the entity debugger so I hope somebody can help shed some light on what is going on.

    I am continuing work on some old code that I started in 0.22 that I upgraded to 0.31 and its a 2D game made for web-wasm but I am also testing on windows .NET
     
    Seaqqull likes this.
  2. AbdulAlgharbi

    AbdulAlgharbi

    Unity Technologies

    Joined:
    Jul 27, 2018
    Posts:
    319
    Few things that I recommend doing:
    - Don't disable game objects in the scene they won't get converted, instead add a tagging component and during the runtime initialization disable them.
    - If you have a system that disable/enable entities, schedule it after the TransformSystemGroup
    Add bedore the system definition
    [UpdateAfter(typeof(TransformSystemGroup))]
    - If you want to enable entities back you can query them with the following
    Code (CSharp):
    1.  
    2. Entities.WithEntityQueryOptions(EntityQueryOptions.IncludeDisabled)
    3.             .WithAll<YourTag, Disabled>().ForEach((Entity entity) =>
    4.              {
    5.                     EntityManager.RemoveComponent<Disabled>(entity);
    6.              }).WithStructuralChanges().Run();
    I hope this helps you
    You can check how we've implemented the UI Menu systems in Tiny Racing
     
  3. SorenPP

    SorenPP

    Joined:
    Nov 13, 2020
    Posts:
    3
    I think I may have found the problem although I am not yet sure if it covers all of them.
    I did not disable GameObjects in the hierarchy but added the Disabled component through authoring. At first this seemed to work fine as simple sprites would work correctly but as other systems got involved it started breaking.

    The key is, as said above, is to first add the Disabled component at runtime. In my case I used a custom tag component that is then replaced with the Disabled component by a system.
    But not only that it seems like you ALSO need to make sure that the system that adds the Disabled component at runtime updates after the affected system (in my case it was the transform system it broke), AND that the system that spawns the "to be disabled" entities updates before the affected system.
    I am guessing that the transform system has to be able to update its related components before the entity is disabled.

    In my case I added
    [UpdateBefore(typeof(TransformSystemGroup))]
    to my spawning system and
    [UpdateInGroup(typeof(LateSimulationSystemGroup))]
    to my runtime disabling system. (I am not sure if this is the correct place to do that but it seems to work).

    This seems very unintuitive to me and I could see it becoming an issue if the spawning code for some reason has to run after the TransformSystemGroup in which case I cant think of a better way to get it to work than leaving information for yet another system to spawn them at the start of the next frame which sounds very clunky.