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

Bug [SOLVED] Enter Play Mode Options Enabled leads to multiple code executions

Discussion in 'Input System' started by BTStone, Oct 11, 2022.

  1. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,424
    Hey support,

    using Unity 2021.3.10f1
    using Unity Input System 1.4.1

    So I noticed that whenever I have the play mode options enabled (meaning that reload domain and reload scene are disabled, just the Enter play Mode Options are checked in order to quickly enter the play mode)
    my Input code behaves faulty:

    For example:

    Code (CSharp):
    1. public void OnProgressDialogue(InputAction.CallbackContext context)
    2.         {
    3.             if (context.performed)
    4.             {
    5.                 Message.Raise(new ProgressDialogueEvent());
    6.             }
    7.         }
    OnProgressDialogue gets called when I hit the spacebar.
    Now this method will get called twice in this scenario, which means the event will get raised twice.

    This does not happen with a build and also it does not happen when the EnterPlayModeOptions are disabled, than the method gets executed exactly as it should: once.

    I've read like about two years ago that the Input System didnt yet support EnterPlayModeOptions, is this still the case? Or is there a another setting I need to enable to make it work with EnterPlayModeOptions?



    Edit: This is the whole class I use:

    Code (CSharp):
    1. public class DialogueInputBehaviour : MonoBehaviour,
    2.                                           IUiInputBehaviour,
    3.                                           MOHInputActions.IDialogueActions
    4.     {
    5.         private IGameInput gameInput;
    6.  
    7.         public void InitInputBehaviour(IGameInput input)
    8.         {
    9.             gameInput = input;
    10.         }
    11.  
    12.         public void RegisterInputCallbacks()
    13.         {
    14.             gameInput.GameInputActions.Dialogue.SetCallbacks(this);
    15.         }
    16.  
    17.         public void UpdateInputBehaviour()
    18.         {
    19.         }
    20.  
    21.  
    22.         public void OnProgressDialogue(InputAction.CallbackContext context)
    23.         {
    24.             if (context.performed)
    25.             {
    26.                 Message.Raise(new ProgressDialogueEvent());
    27.             }
    28.         }
    29.  
    30.         public void OnEnterMainMenu(InputAction.CallbackContext context)
    31.         {
    32.             if (context.performed)
    33.             {
    34.                 Message.Raise(new OpenMainMenuEvent());
    35.             }
    36.         }
    37.  
    38.         public void DisposeInputBehaviour()
    39.         {
    40.             // Didnt work
    41.             gameInput.GameInputActions.Dialogue.SetCallbacks(null);
    42.  
    43.             // Didnt work
    44.             gameInput.GameInputActions.Dialogue.Disable();
    45.  
    46.             // Didnt work:
    47.             gameInput.GameInputActions.Dialogue.ProgressDialogue.Dispose();
    48.             gameInput.GameInputActions.Dialogue.EnterMainMenu.Dispose();
    49.         }
     
    Last edited: Oct 12, 2022
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,444
    I've been using Input system with Enter Play Mode options (domain and scene reload disabled) just fine.

    What is this Message.Raise? Couldn't find that this is Unity built-in. Is it possible this is using a static event handler behind the scenes? Just in case the Raise method duplicates the call, rather than OnProgressDialogue running twice.

    Try setting a breakpoint and check the call stack, is it both coming from the exact same source for both initial and repeated calls?
     
  3. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,424
    Message.Raise is a method I wrote, but that is not the problem. OnProgressDialogue gets called multiple times, when I debug I land multiple times in the method and the if-condition also gets called multiple times
     
  4. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,424
    Just for the record, here is the whole class I use. @CodeSmile you made think about the fact that I maybe don't correctly unsubscribe from the callbacks, but sadly that does also not work, this is my whole class:

    Code (CSharp):
    1. public class DialogueInputBehaviour : MonoBehaviour,
    2.                                           IUiInputBehaviour,
    3.                                           MOHInputActions.IDialogueActions
    4.     {
    5.         private IGameInput gameInput;
    6.  
    7.         public void InitInputBehaviour(IGameInput input)
    8.         {
    9.             gameInput = input;
    10.         }
    11.  
    12.         public void RegisterInputCallbacks()
    13.         {
    14.             gameInput.GameInputActions.Dialogue.SetCallbacks(this);
    15.         }
    16.  
    17.         public void UpdateInputBehaviour()
    18.         {
    19.         }
    20.  
    21.  
    22.         public void OnProgressDialogue(InputAction.CallbackContext context)
    23.         {
    24.             if (context.performed)
    25.             {
    26.                 Message.Raise(new ProgressDialogueEvent());
    27.             }
    28.         }
    29.  
    30.         public void OnEnterMainMenu(InputAction.CallbackContext context)
    31.         {
    32.             if (context.performed)
    33.             {
    34.                 Message.Raise(new OpenMainMenuEvent());
    35.             }
    36.         }
    37.  
    38.         public void DisposeInputBehaviour()
    39.         {
    40.             // Didnt work
    41.             gameInput.GameInputActions.Dialogue.SetCallbacks(null);
    42.  
    43.             // Didnt work
    44.             gameInput.GameInputActions.Dialogue.Disable();
    45.  
    46.             // Didnt work:
    47.             gameInput.GameInputActions.Dialogue.ProgressDialogue.Dispose();
    48.             gameInput.GameInputActions.Dialogue.EnterMainMenu.Dispose();
    49.         }

    DisposeInputBehaviour() gets called in the OnDisable method of another class, that same class also calls InitInputBehaviour and RegisterInputCallbacks in OnEnable and gets called correctly (debugged it) but neither of the options I tried in DisposeInputBehaviour seperately to unsubscribe from the callbacks did the trick.
    When EnterPlayModeOptions are enabled InitInputBehaviour and RegisterInputCallbacks gets only called once while the callback OnProgressDialogue gets called multiple times for a reason.
     
  5. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,424
  6. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,424
    Alrighty, I fixed it. The issue was indeed the way to unsubscribe. gameInput.GameInputActions.Dialogue.SetCallbacks(null) actually works, when I debugged it I looked into the wrong spot, the code executes just fine with EnterPlayModeOptions enabled now :)