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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

How to get OnCancel() or other UI callbacks called

Discussion in 'Input System' started by Evercloud, May 19, 2020.

  1. Evercloud

    Evercloud

    Joined:
    Apr 29, 2013
    Posts:
    15
    Hello everybody,
    can you please give me a hint on how to get OnSubmit() or OnCancel() called in my scripts with the new Input System during UI navigation?
    Input System UI Input Module and EventSystem are apparently correctly configured as i can move through UI as intended and even trigger OnClick() in UI buttons, but no callbacks such as OnCancel() or OnMove() are actually called in my scripts.
    During gameplay, other actions set in another action map inside my InputActionAsset are called without any problem after players have joined the Player Input Manager. I can't understand why during menus I can navigate and "click" without joining but I can't get the input system callbacks to be triggered.

    The following code does not work:
    Code (CSharp):
    1.  
    2. using UnityEngine.EventSystems;
    3. using UnityEngine.InputSystem;
    4.  
    5. [...]
    6.  
    7.         public void OnCancel(InputAction.CallbackContext context)
    8.         {
    9.             Debug.Log("This is never called!");
    10.         }
    Thanks!
     
  2. Evercloud

    Evercloud

    Joined:
    Apr 29, 2013
    Posts:
    15
    55 reads and no answer? Was it such a bad question? :D
    I will let you know if I can find a solution :)
     
    Last edited: May 22, 2020
  3. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    The submit and cancel callbacks in uGUI are received through the ISubmitHandler and ICancelHandler interfaces. This works like with the old input system.

    If you have one or both of the interfaces on your MonoBehaviour and you implement the respective OnSubmit/OnCancel methods, you should see the method(s) getting called when your object is selected and a submit or cancel action is triggered.
     
  4. Konaju-Games

    Konaju-Games

    Joined:
    Jul 11, 2012
    Posts:
    22
    How would the Input System know which GameObject to trigger it on then?
     
  5. codegasm

    codegasm

    Joined:
    May 3, 2015
    Posts:
    38
    Since there still is no answer in this thread I'm sharing my workaround in case someone else gets here from Google like I did. Just like OP I found that attaching events to the UI/Cancel event on the PlayerInput component doesn't work. The ICancelHandler also did nothing, I guess because that only works on active UI elements? I was able to get around it by defining my own action under Player instead of under UI. Using the "Cancel [Any]" binding I was able to capture the back button/gesture on Android which was my use case.

    I really think that something needs to be clarified in the documentation about this. Are the actions under the UI category only available to the Unity's UI? It would also be good to know what the official approach to handling the back button/gesture on Android in the new input system since my approach feels a bit hacky.
     
    jay3sh likes this.
  6. pixelminer

    pixelminer

    Joined:
    Jul 24, 2011
    Posts:
    26
    Hi. The following works for me.

    First I have a singleton which holds the InputSystemUIInputModule component because, you know, why waste the memory.

    Code (CSharp):
    1. public class UIInputModuleBridge : MonoBehaviour {
    2.  
    3.     public static UIInputModuleBridge instance ;
    4.  
    5.     public InputSystemUIInputModule module ;
    6.  
    7.     private void Awake () => instance = this ;
    8. }
    Then wherever I need back button functionality I add the following component and set events as needed.

    Code (CSharp):
    1. public class BackButtonInput : MonoBehaviour {
    2.  
    3.     [ SerializeField ] private UnityEvent onTriggered ;
    4.  
    5.     private void OnEnable () => UIInputModuleBridge.instance.module.cancel.action.performed += Trigger ;
    6.  
    7.     private void OnDisable () => UIInputModuleBridge.instance.module.cancel.action.performed -= Trigger ;
    8.  
    9.     private void Trigger ( InputAction.CallbackContext context ) => onTriggered.Invoke () ;
    10. }
    Voila! Enjoy! :D