Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  3. 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

Bug RenderPiplines DebugUpdater creates duplicate EventSystem and more

Discussion in '2021.2 Beta' started by Kamyker, Aug 10, 2021.

  1. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,092
    This component has multiple issues. Lets look at the code:

    Code (CSharp):
    1.         [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    2.         static void RuntimeInit()
    3.         {
    4.             if (!Debug.isDebugBuild || FindObjectOfType<DebugUpdater>() != null)
    5.                 return;
    6.  
    7.             var go = new GameObject { name = "[Debug Updater]" };
    8.             var debugUpdater = go.AddComponent<DebugUpdater>();
    9.  
    10.             var es = GameObject.FindObjectOfType<EventSystem>();
    11.             if (es == null)
    12.             {
    13.                 go.AddComponent<EventSystem>();
    14. #if USE_INPUT_SYSTEM
    15.                 // FIXME: InputSystemUIInputModule has a quirk where the default actions fail to get initialized if the
    16.                 // component is initialized while the GameObject is active. So we deactivate it temporarily.
    17.                 // See https://fogbugz.unity3d.com/f/cases/1323566/
    18.                 go.SetActive(false);
    19.                 var uiModule = go.AddComponent<InputSystemUIInputModule>();
    20.  
    21.                 // FIXME: In order to activate default input actions in player builds (required for touch input to work),
    22.                 // we need to call InputSystemUIInputModule.AssignDefaultActions() which was added in com.unity.inputsystem@1.1.0-pre.5.
    23.                 // However, there is a problem in InputSystem package version ordering, where it sorts this version as an
    24.                 // older version than it should be. Hence we cannot write a version define to conditionally compile this function call.
    25.                 // Instead, we use reflection to see if the function is there and can be invoked.
    26.                 //
    27.                 // Once com.unity.inputsystem@1.1.0 is available, create an INPUTSYSTEM_1_1_0_OR_GREATER version define and use it
    28.                 // to conditionally call AssignDefaultActions().
    29.                 System.Reflection.MethodInfo assignDefaultActionsMethod = uiModule.GetType().GetMethod("AssignDefaultActions");
    30.                 if (assignDefaultActionsMethod != null)
    31.                 {
    32.                     assignDefaultActionsMethod.Invoke(uiModule, null);
    33.                 }
    34.  
    35.                 go.SetActive(true);
    36. #else
    37.                 go.AddComponent<StandaloneInputModule>();
    38. #endif
    39.             }
    40.             else
    41.             {
    42. #if USE_INPUT_SYSTEM
    43.                 if (es.GetComponent<InputSystemUIInputModule>() == null)
    44.                     Debug.LogWarning("Found a game object with EventSystem component but no corresponding InputSystemUIInputModule component - Debug UI input may not work correctly.");
    45. #else
    46.                 if (es.GetComponent<StandaloneInputModule>() == null)
    47.                     Debug.LogWarning("Found a game object with EventSystem component but no corresponding StandaloneInputModule component - Debug UI input may not work correctly.");
    48. #endif
    49.             }
    50.  
    51. #if USE_INPUT_SYSTEM
    52.             EnhancedTouchSupport.Enable();
    53. #endif
    54.             debugUpdater.m_Orientation = Screen.orientation;
    55.  
    56.             DontDestroyOnLoad(go);
    57.         }
    I'll start from the worst:

    1. In some cases (for ex. when first scene of the game doesn't have EventSystem) this component will create EventSystem. That will keep spamming "There are 2 event systems in the scene. Please ensure there is always exactly one event system in the scene". Error is not the only problem, if someone relies on this EventSystem they will have it missing in non-debug build. This component shouldn't be added by debugger, please just log once that it may not work correctly without it and let user to the rest.

    2. InputSystemUIInputModule also shouldn't be added, same issue as above.

    3. Whole function should be in #if UNITY_EDITOR || DEVELOPMENT_BUILD instead of Debug.isDebugBuild to not slow down every scene load.

    4. Should use singleton instead of slow FindObjectOfType
     
    Last edited: Aug 11, 2021
    apkdev, Bastienre4 and Kichang-Kim like this.
  2. Bastienre4

    Bastienre4

    Joined:
    Jul 8, 2014
    Posts:
    191
    I'm also bothered by this. :)

    In my case, I have a splash scene with the bare minimum that then load a "core" scene with all our common stuff (EventSystem for instance).
    It makes it impossible to test the natural flow of the game in editor because when we enter play mode the DebugUpdater is created and create an EventSystem on it's own (since the EventSystem does not exist yet).

    It would be great to allow the user to disable this behaviour completely.
     
  3. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    3,136
    Bastienre4 likes this.
  4. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
    The proposed solution noted above is now available (in 2022.1 at least - haven't tried older). Here's the code that's necessary to stop the "[Debug Updater]" thing from spawning. It's working for me in Awake of a component. Thanks @Kamyker, @LeonhardP, arttu-peltonen and whoever else contributed to getting that in.

    Code (CSharp):
    1. DebugManager.instance.enableRuntimeUI = false;
     
    LeonhardP likes this.
  5. arttu_p

    arttu_p

    Unity Technologies

    Joined:
    Jan 15, 2021
    Posts:
    25
    Thanks for the feedback everyone! Based on this thread & internal testing, the functionality has been updated in two ways:

    1) As described by @polemical, you can use "DebugManager.instance.enableRuntimeUI = false;" to opt out of Rendering Debugger at runtime. This is available as of 2021.2.0b14/2022.1.0a11.

    2) A subsequent improvement was made where the EventSystem and InputSystemUIInputModule / StandaloneInputModule are no longer automatically added when entering play mode, but instead whenever the debug UI is opened, and only if required. This approach should minimize the conflicts between Rendering Debugger input and the input configured by user's game. Note that the [Debug Updater] GameObject will still appear automatically, but it shouldn't conflict with anything. On the off-chance that it does, you can use step 1) to opt out. This new logic is in 2021.2.0b15/2022.1.0a12.
     
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,342
    Why are you even spawning a GameObject with a script that runs an Update into our scenes at all?

    The entire reason we got into this mess is that every team in Unity just went "out feature is worth a couple of milliseconds on domain reload and/or enter play mode, so we'll add it in", and there's enough teams that it became seconds instead.

    It seems like the object should be spawned when the shortcut for showing it is pressed, not at an earlier point just in case that shortcut gets pressed.
     
    Last edited: Oct 19, 2021
    neonblitzer, DSivtsov and Bastienre4 like this.