Search Unity

Reverse UI Button OnClick()

Discussion in 'Scripting' started by Volcanicus, Jun 19, 2019.

  1. Volcanicus

    Volcanicus

    Joined:
    Jan 6, 2018
    Posts:
    169
    I get that you can set up an empty object with a script and an OnClick() command with a UI button; I was wondering if it was possible to do it in reverse where the scripting happens elsewhere and that upon clicking the button, an input is made.

    Essentially, rather than having the UI button have an onClick() event specific to another script, you instead have a general onClick() input.

    What I am trying to accomplish in terms of unity is having a UI button "1" have the same input as the keyboard key 1 regardless of what the situation is. I was hoping that the input manager could use the UI button as an alt positive but it doesn't seem to be able to do so. I was also hoping I could just set it up to "SendKey", but this function doesn't exist in Unity (i think).

    Are there alternatives to this?
     
  2. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    If I understand correctly what you are trying to achieve, you can try the following: Create a custom MonoBehaviour script and put an instance somewhere in you scene. Add a public instance method HandleButtonInput(int code). In the Unity UI Button add a onClick UnityEvent receiver and hook up the custom method that receives an int. You can now setup a specific id via the inspector on the button. Now create multiple buttons with different ids. Alternatively, you can also pass strings; note that enums are not supported. Now you have a single method that receives all button inputs. Next, decide how to forward these events. For example, create a static C# event of delegate type Action<int> if you want to make the button inputs globally available from every script.

    The builtin (now almost legacy) InputManager does not support actions triggered via Unity UI. In the future, the new input manager may be able to handle these cases but until then we have to create custom scripts to handle ui components.
     
  3. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    I'm contemplating a master input class like so:

    Code (CSharp):
    1. public class InputMaster : MonoBehaviour {
    2.  
    3. bool[] alpha = new bool[10];
    4.  
    5.  
    6. void Update(){
    7.  
    8.    for (int i = 0; i < alpha.Length; i++){
    9.       if(alpha[i]){
    10.          //Trigger what ever
    11.          alpha[i] = false;
    12.       }
    13.    }
    14. }
    15.  
    16. public void SetKey(int i){
    17.  
    18.    alpha[i] = true;
    19. }
    20. }
    the button would call SetKey with what ever key you want ( 0-9 ) and in the update you see every frame if one of them has been clicked and if so - do the action and reset the key to false.

    this can be extended to have functionality like the Down Up and the normal Held, and obv the rest of the keyboard.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,752
    I have a function like this in my Datasacks package. It is a generic mechanism for proxying any sort of input event to simulate firing the .onClick event of any given button.

    This is a link to my DSButtonProxy script:

    https://github.com/kurtdekker/datasacks/blob/master/datasacks/Assets/Datasack/Input/DSButtonProxy.cs

    The relevant codelet you are looking for is line 64 above, which is just a good old GetComponent to find the Button on this GameObject, and then line 56 where it conditionally invokes the onclick behavior when the proxying mechanism decides the input is relevant for this button.

    Datasacks operates through a subscriber/observer pattern and this script is specifically designed for script driving of an existing UI (such as an escorted tour through the software under script control), with a minimum of changes to the underlying UI.

    In your specific use case, you could just make something like what @SparrowsNest posted above and trigger the proxying mechanism on his line 10.

    The entire Datasacks package is presently hosted at these locations:

    https://bitbucket.org/kurtdekker/datasacks

    https://github.com/kurtdekker/datasacks

    https://gitlab.com/kurtdekker/datasacks