Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Resolved SystemAPI.GetSingleton causing crash in build Windows / Android

Discussion in 'Entity Component System' started by Tony_Max, Dec 29, 2022.

  1. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    354
    As title says using
    SystemAPI.GetSingleton
    causing crash in build. Full code bellow. Baker mono used as separate gameobject inside subscene. Commenting
    var animationSettings = SystemAPI.GetSingleton<AnimationSettings>();
    line fixes issue. Also in editor in edit / play mode all works fine.

    System code
    Code (CSharp):
    1. sing NSprites;
    2. using Unity.Burst;
    3. using Unity.Collections;
    4. using Unity.Entities;
    5.  
    6. #pragma warning disable CS0282 // I guess because of DOTS's codegen
    7. // https://forum.unity.com/threads/compilation-of-issues-with-0-50.1253973/page-2#post-8512268
    8.  
    9. [BurstCompile]
    10. public partial struct MovableAnimationControllSystem : ISystem
    11. {
    12.     [BurstCompile]
    13.     private partial struct ChangeAnimation : IJobEntity
    14.     {
    15.         public int setToAnimationID;
    16.         public double time;
    17.  
    18.         public void Execute(ref AnimationIndex animationIndex, ref AnimationTimer timer, ref FrameIndex frameIndex, in AnimationSetLink animationSetLink)
    19.         {
    20.             // find animation by animation ID
    21.             ref var animSet = ref animationSetLink.value.Value;
    22.             var setToAnimIndex = 0;
    23.             for (int i = 1; i < animSet.Length; i++)
    24.                 if (animSet[i].ID == setToAnimationID)
    25.                 {
    26.                     setToAnimIndex = i;
    27.                     break;
    28.                 }
    29.  
    30.             if (animationIndex.value != setToAnimIndex)
    31.             {
    32.                 animationIndex.value = setToAnimIndex;
    33.                 // here we want to set last frame and timer to 0 (equal to current time) to force animation system instantly switch
    34.                 // animation to 1st frame after we've modified it
    35.                 frameIndex.value = animSet[setToAnimIndex].FrameDurations.Length;
    36.                 timer.value = time;
    37.             }
    38.         }
    39.     }
    40.     private struct SystemData : IComponentData
    41.     {
    42.         public EntityQuery gotUnderWayQuery;
    43.         public EntityQuery stopedQuery;
    44.     }
    45.     [BurstCompile]
    46.     public void OnCreate(ref SystemState state)
    47.     {
    48.         var systemData = new SystemData();
    49.         var queryBuilder = new EntityQueryBuilder(Allocator.Temp)
    50.             .WithNone<CullSpriteTag>()
    51.             .WithAll<AnimationIndex>()
    52.             .WithAll<AnimationTimer>()
    53.             .WithAll<FrameIndex>()
    54.             .WithAll<AnimationSetLink>()
    55.             .WithAll<Destination>()
    56.             .WithAll<MoveTimer>();
    57.         var gotUnderWayQuery = state.GetEntityQuery(queryBuilder);
    58.         gotUnderWayQuery.AddOrderVersionFilter();
    59.         systemData.gotUnderWayQuery = gotUnderWayQuery;
    60.  
    61.         queryBuilder.Reset();
    62.         _ = queryBuilder.WithNone<CullSpriteTag>()
    63.             .WithAll<AnimationIndex>()
    64.             .WithAll<AnimationTimer>()
    65.             .WithAll<FrameIndex>()
    66.             .WithAll<AnimationSetLink>()
    67.             .WithAll<Destination>()
    68.             .WithNone<MoveTimer>();
    69.         var stopedQuery = state.GetEntityQuery(queryBuilder);
    70.         stopedQuery.AddOrderVersionFilter();
    71.         systemData.stopedQuery = stopedQuery;
    72.  
    73.         _ = state.EntityManager.AddComponentData(state.SystemHandle, systemData);
    74.  
    75.         queryBuilder.Dispose();
    76.     }
    77.  
    78.     public void OnDestroy(ref SystemState state)
    79.     {
    80.     }
    81.     [BurstCompile]
    82.     public void OnUpdate(ref SystemState state)
    83.     {
    84.         var systemData = SystemAPI.GetComponent<SystemData>(state.SystemHandle);
    85.         // next line causing crash in build
    86.         var animationSettings = SystemAPI.GetSingleton<AnimationSettings>();
    87.         var time = SystemAPI.Time.ElapsedTime;
    88.     }
    89. }

    Component and baker code
    Code (CSharp):
    1. using Unity.Entities;
    2.  
    3. namespace NSprites
    4. {
    5.     public struct AnimationSettings : IComponentData
    6.     {
    7.         public int IdleHash;
    8.         public int WalkHash;
    9.     }
    10. }
    Code (CSharp):
    1.  
    2. using Unity.Entities;
    3. using UnityEngine;
    4.  
    5. namespace NSprites
    6. {
    7.     public class AnimationSettingsAuthoring : MonoBehaviour
    8.     {
    9.         private class AnimationSettingsBaker : Baker<AnimationSettingsAuthoring>
    10.         {
    11.             public override void Bake(AnimationSettingsAuthoring authoring)
    12.             {
    13.                 AddComponent(new AnimationSettings
    14.                 {
    15.                     IdleHash = Animator.StringToHash("idle"),
    16.                     WalkHash = Animator.StringToHash("walk")
    17.                 });
    18.             }
    19.         }
    20.     }
    21. }
    22.  

    Also generated code looks completely normal for me, can't figure out what is problem here.
    Code (CSharp):
    1. #pragma warning disable 0219
    2. #line 1 "E:\UnityProjects\NSprites-Dev\Temp\GeneratedCode\Assembly-CSharp\MovableAnimationControllSystem__System_1455874136.g.cs"
    3. using NSprites;
    4. using Unity.Burst;
    5. using Unity.Collections;
    6. using Unity.Entities;
    7.  
    8. [global::System.Runtime.CompilerServices.CompilerGenerated]
    9. public partial struct MovableAnimationControllSystem : Unity.Entities.ISystem, Unity.Entities.ISystemCompilerGenerated
    10. {
    11.     [Unity.Entities.DOTSCompilerPatchedMethod("OnUpdate_ref_Unity.Entities.SystemState")]
    12.     void __OnUpdate_6E994214(ref SystemState state)
    13.     {
    14.             #line 84 "E:\UnityProjects\NSprites-Dev\Assets/Sources/Rome/Systems/MovableAnimationControllSystem.cs"
    15.             state.EntityManager.CompleteDependencyBeforeRO<MovableAnimationControllSystem.SystemData>();
    16.             #line hidden
    17.             __MovableAnimationControllSystem_SystemData_RO_ComponentLookup.Update(ref state);
    18.             #line hidden
    19.             var systemData = __MovableAnimationControllSystem_SystemData_RO_ComponentLookup[state.SystemHandle];
    20.         #line 85 "E:\UnityProjects\NSprites-Dev\Assets/Sources/Rome/Systems/MovableAnimationControllSystem.cs"
    21.         var animationSettings = __query_920542869_0.GetSingleton<AnimationSettings>();
    22.         #line 86 "E:\UnityProjects\NSprites-Dev\Assets/Sources/Rome/Systems/MovableAnimationControllSystem.cs"
    23.         var time = state.WorldUnmanaged.Time.ElapsedTime;
    24.     }
    25.  
    26.     Unity.Entities.EntityQuery __query_920542869_0;
    27.     Unity.Entities.ComponentLookup<MovableAnimationControllSystem.SystemData> __MovableAnimationControllSystem_SystemData_RO_ComponentLookup;
    28.     public void OnCreateForCompiler(ref SystemState state)
    29.     {
    30.         __query_920542869_0 = state.GetEntityQuery(new Unity.Entities.EntityQueryDesc{All = new Unity.Entities.ComponentType[]{Unity.Entities.ComponentType.ReadOnly<NSprites.AnimationSettings>()}, Any = new Unity.Entities.ComponentType[]{}, None = new Unity.Entities.ComponentType[]{}, Options = Unity.Entities.EntityQueryOptions.Default | Unity.Entities.EntityQueryOptions.IncludeSystems});
    31.         __MovableAnimationControllSystem_SystemData_RO_ComponentLookup = state.GetComponentLookup<MovableAnimationControllSystem.SystemData>(true);
    32.     }
    33. }

    Also using this API in other parts of project doesn't cause any issues in build.

    Resolve: the problem was in accessing singleton component which is not loaded yet by subscene loading system because system just runs before loading done. Be careful, because systems update always by default. So
    SystemAPI.TryGetSingleton
    with early out solves the problem. Also it can be solved by adding any require query / singleton for system to filter its update.
     
    Last edited: Dec 30, 2022
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,688
    What crash dump shows you? If you‘ll put require for update for that singleton type it will solves your issue? I’m 100% sure the issue is not yet loaded singleton in build
     
  3. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    354
    Somehow
    Yep, just a moment ago I was trying to use
    SystemAPI.TryGetSingleton
    + early out on fail and build works and system doesn't perform logic, so as you mentioned singleton not loaded in build. What can be a reason? It works in editor, so baker works fine.

    UPD: Was my fault with inverted if, so with
    SystemAPI.TryGetSingleton
    build works. Does it mean that system runs before subscene loaded?
     
    Last edited: Dec 29, 2022
  4. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    505
    Yes this can happen. You can work around it if you know how, but I'm not sure and can't check right now cause I'm just using some code @tertle gave me to prevent systems running until subscenes are loaded :D.
     
    Tony_Max likes this.
  5. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,688
    Yes it can, because subscene loading is async.
    upload_2022-12-30_10-18-24.png
     
    Tony_Max likes this.