[SOLVED]Invoke A Unity Button Click Event From C# Script?

Hi,

We are working on our button system now.

Is there anyway to do the below?:
Invoke a Unity button click event from C# script.

We ask as we are trying to create a custom keyboard system for button actions.
When the [Enter] key is pressed we would like to activate the “click” event of the selected button.

Let us know, thanks!

Jesse

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ButtonsKeyboard : MonoBehaviour
{
    GameObject ButtonSelectorLeftSprite;
    GameObject ButtonSelectorRightSprite;
    Vector3 position;

    // Start is called before the first frame update
    void Start()
    {
       
    }
    public void SetupButtonSelectors(float posY)
    {
        ButtonSelectorLeftSprite = GameObject.Find("ButtonSelectorLeft");
        position = ButtonSelectorLeftSprite.transform.position;
        position.y = (posY / 100.0f);
        ButtonSelectorLeftSprite.transform.position = position;

        ButtonSelectorRightSprite = GameObject.Find("ButtonSelectorRight");
        position = ButtonSelectorRightSprite.transform.position;
        position.y = (posY / 100.0f);
        ButtonSelectorRightSprite.transform.position = position;
    }

    // Update is called once per frame
    void Update()
    {
        if (GlobalVariables.DelayAllUserInput > 0)  GlobalVariables.DelayAllUserInput--;

        if (GlobalVariables.DelayAllUserInput == 0)
        {
            if (GlobalVariables.ScreenToDisplay == 2)
            {
                if (Input.GetKey("up"))
                {
                    if (GlobalVariables.CurrentlySelectedButton > 0)
                    {
                        GlobalVariables.CurrentlySelectedButton--;
                    }
                    else
                    {
                        GlobalVariables.CurrentlySelectedButton = 5;
                    }

                    float yPos = ( 110 - (50*GlobalVariables.CurrentlySelectedButton) );
                    SetupButtonSelectors(yPos);
                   
                    GlobalVariables.SoundEffectToPlay = 3;
                    GlobalVariables.DelayAllUserInput = 5;
                }
                else if (Input.GetKey("down"))
                {
                    if (GlobalVariables.CurrentlySelectedButton < 5)
                    {
                        GlobalVariables.CurrentlySelectedButton++;
                    }
                    else
                    {
                        GlobalVariables.CurrentlySelectedButton = 0;
                    }

                    float yPos = (110 - (50 * GlobalVariables.CurrentlySelectedButton));
                    SetupButtonSelectors(yPos);

                    GlobalVariables.SoundEffectToPlay = 3;
                    GlobalVariables.DelayAllUserInput = 5;
                }
                else if (Input.GetKey("enter"))
                {
                    // "Click" selected button?

                    GlobalVariables.SoundEffectToPlay = 2;
                    GlobalVariables.DelayAllUserInput = 5;
                }
            }
        }
    }
}

You need to reference the Button component attached to the button GameObject and call Invoke() on its onClick event.
Example:

using UnityEngine.UI; //Namespace required for Button objects.

public class Example : MonoBehaviour {
   //The UI Button we want to programmatically click.
   public Button button;

   void Update() {
      //Check if the Enter key has been pressed.
      if(Input.GetKeyDown(KeyCode.Return)) {
      
         //Invoke the button's onClick event.
         button.onClick.Invoke();
      }
   }
}

I don’t see any explicit references to a Button component in this script, but I’m assuming your ButtonSelectorLeftSprite and ButtonSelectorRightSprite GameObjects have Button components attached to them, and if so, you’ll need to get the component reference before invoking the event.

1 Like

Hi,

Did some Googling…
We have below new code but it does not “Click” the button that is selected by the keyboard?
Any ideas?
Thanks!

Jesse

                }
                else if ( Input.GetKey("space") || Input.GetKey("return") )
                {
                    // "Click" selected button?
                    GlobalVariables.SoundEffectToPlay = 2;

                    Button button;
                    button = GameObject.FindGameObjectWithTag("ButtonSTART").GetComponent<Button>();
                    if (GlobalVariables.CurrentlySelectedButton == 1)
                    {
                        button = GameObject.FindGameObjectWithTag("ButtonOptions").GetComponent<Button>();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 2)
                    {
                        button = GameObject.FindGameObjectWithTag("ButtonHowToPlay").GetComponent<Button>();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 3)
                    {
                        button = GameObject.FindGameObjectWithTag("ButtonHighScores").GetComponent<Button>();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 4)
                    {
                        button = GameObject.FindGameObjectWithTag("ButtonAbout").GetComponent<Button>();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 5)
                    {
                        button = GameObject.FindGameObjectWithTag("ButtonExit").GetComponent<Button>();
                    }
                    button.onClick.Invoke(); // <--- Does not work?
                    GlobalVariables.DelayAllUserInput = 10;
                }

Something is definitely not working above…

Please look at below screenshot of the button:

You’re trying to find a GameObject tagged as “ButtonSTART”, but in the image you’ve posted, the GameObject is untagged.

On a side note, I would restructure your system here, as there are much easier/better ways of referencing objects than using the various Find... methods everywhere.
An approach that would be easier to maintain would be to simply define an array of Buttons that can be selected in your ButtonsKeyboard script, and just iterate through them with a cached index value.

Example:
With comments

public class ButtonsKeyboard : MonoBehaviour {
   public Button[] buttons; //The array of Buttons that the user can select with the keyboard. Assigned from the inspector.

   private int buttonsIndex; //The index to iterate over the array of Buttons when the user changes the selected Button.
   private Button selectedButton; //The Button that the user has currently selected with the keyboard.

   //Set the first Button reference in the array of Buttons as the selected Button by default.
   private void Awake() {
      buttonsIndex = 0;
      selectedButton = buttons[buttonsIndex];
   }

   private void Update() {
      //When the user presses the up arrow key, select the next Button in the array of Buttons.
      if(Input.GetKeyDown(KeyCode.UpArrow)) {
         SelectNextButton();
      }

      //When the user presses the down arrow key, select the previous Button in the array of Buttons.
      if(Input.GetKeyDown(KeyCode.DownArrow)) {
         SelectPreviousButton();
      }

      //When the user presses the space-bar, click the selectedButton.
      if(Input.GetKeyDown(KeyCode.Space)) {
         selectedButton.onClick.Invoke();
      }
   }

   private void SelectNextButton() {
      //Increment the index value
      buttonsIndex++;

      //Check if the index value is greater or equal to the length of the Buttons array.
      //If it is, then we've reached the end of all selectable Buttons, and the index should be set back to 0.
      if(buttonsIndex >= buttons.Length) {
         buttonsIndex = 0;
      }

      //Set the selectedButton to the reference of the Button in the new index of the Buttons array.
      selectedButton = buttons[buttonsIndex];
   }

   private void SelectPreviousButton() {
      //Decrement the index value
      buttonsIndex--;

      //Check if the index value is less than or equal to 0.
      //If it is, then we've reached the beginning of all selectable Buttons, and the index should be set back to the last reference in the array.
      if(buttonsIndex <= 0) {
         buttonsIndex = buttons.Length - 1; //The minus one here is due to the Length method returning one greater than the array's actual length.
      }

      //Set the selectedButton to the reference of the Button in the new index of the Buttons array.
      selectedButton = buttons[buttonsIndex];
   }
}

Without comments

public class ButtonsKeyboard : MonoBehaviour {
   public Button[] buttons;

   private int buttonsIndex;
   private Button selectedButton;

   private void Awake() {
      buttonsIndex = 0;
      selectedButton = buttons[buttonsIndex];
   }

   private void Update() {
      if(Input.GetKeyDown(KeyCode.UpArrow)) {
         SelectNextButton();
      }

      if(Input.GetKeyDown(KeyCode.DownArrow)) {
         SelectPreviousButton();
      }

      if(Input.GetKeyDown(KeyCode.Space)) {
         selectedButton.onClick.Invoke();
      }
   }

   private void SelectNextButton() {
      buttonsIndex++;

      if(buttonsIndex >= buttons.Length) {
         buttonsIndex = 0;
      }

      selectedButton = buttons[buttonsIndex];
   }

   private void SelectPreviousButton() {
      buttonsIndex--;

      if(buttonsIndex <= 0) {
         buttonsIndex = buttons.Length - 1;
      }

      selectedButton = buttons[buttonsIndex];
   }
}

Hi,

We have made changes, but still not working…
We have attached the script to each Unity GUI button.
Updated info is below:

Jesse

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ButtonsKeyboard : MonoBehaviour
{
    GameObject ButtonSelectorLeftSprite;
    GameObject ButtonSelectorRightSprite;
    Vector3 position;

    public Button button;

    // Start is called before the first frame update
    void Start()
    {
       
    }
    public void SetupButtonSelectors(float posY)
    {
        ButtonSelectorLeftSprite = GameObject.Find("ButtonSelectorLeft");
        position = ButtonSelectorLeftSprite.transform.position;
        position.y = (posY / 100.0f);
        ButtonSelectorLeftSprite.transform.position = position;

        ButtonSelectorRightSprite = GameObject.Find("ButtonSelectorRight");
        position = ButtonSelectorRightSprite.transform.position;
        position.y = (posY / 100.0f);
        ButtonSelectorRightSprite.transform.position = position;
    }

    // Update is called once per frame
    void Update()
    {
        if (GlobalVariables.DelayAllUserInput > 0)  GlobalVariables.DelayAllUserInput--;

        if (GlobalVariables.DelayAllUserInput == 0)
        {
            if (GlobalVariables.ScreenToDisplay == 2)
            {
                if (Input.GetKey("up"))
                {
                    if (GlobalVariables.CurrentlySelectedButton > 0)
                    {
                        GlobalVariables.CurrentlySelectedButton--;
                    }
                    else
                    {
                        GlobalVariables.CurrentlySelectedButton = 5;
                    }

                    float yPos = ( 110 - (50*GlobalVariables.CurrentlySelectedButton) );
                    SetupButtonSelectors(yPos);
                   
                    GlobalVariables.SoundEffectToPlay = 3;
                    GlobalVariables.DelayAllUserInput = 10*6;
                }
                else if (Input.GetKey("down"))
                {
                    if (GlobalVariables.CurrentlySelectedButton < 5)
                    {
                        GlobalVariables.CurrentlySelectedButton++;
                    }
                    else
                    {
                        GlobalVariables.CurrentlySelectedButton = 0;
                    }

                    float yPos = (110 - (50 * GlobalVariables.CurrentlySelectedButton));
                    SetupButtonSelectors(yPos);

                    GlobalVariables.SoundEffectToPlay = 3;
                    GlobalVariables.DelayAllUserInput = 10*6;
                }
                else if ( Input.GetKey("space") || Input.GetKey("return") )
                {
                    GlobalVariables.SoundEffectToPlay = 2;

                    if (GlobalVariables.CurrentlySelectedButton == 0 && button.name == "ButtonSTART")
                    {
                        button.onClick.Invoke();
                        Debug.Log(button.name);
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 1 && button.name == "ButtonOptions")
                    {
                        button.onClick.Invoke();
                        Debug.Log(button.name);
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 2 && button.name == "ButtonHowToPlay")
                    {
                        button.onClick.Invoke();
                        Debug.Log(button.name);
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 3 && button.name == "ButtonHighScores")
                    {
                        button.onClick.Invoke();
                        Debug.Log(button.name);
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 4 && button.name == "ButtonAbout")
                    {
                        button.onClick.Invoke();
                        Debug.Log(button.name);
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 5 && button.name == "ButtonExit")
                    {
                        button.onClick.Invoke();
                        Debug.Log(button.name);
                    }

                    GlobalVariables.DelayAllUserInput = 10*6;
                }
            }
        }
    }
}

You haven’t assigned/reassigned a reference to your Button. It’s always going to remain as what it originally was set from the inspector.

At this point, I’d suggest viewing some C# tutorials.
https://learn.unity.com/project/beginner-gameplay-scripting?courseId=5c61706dedbc2a324a9b022d

Got it working:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ButtonsKeyboard : MonoBehaviour
{
    GameObject ButtonSelectorLeftSprite;
    GameObject ButtonSelectorRightSprite;
    Vector3 position;

    public Button buttonSTART;
    public Button buttonOptions;
    public Button buttonHowToPlay;
    public Button buttonHighScores;
    public Button buttonAbout;
    public Button buttonExit;

    // Start is called before the first frame update
    void Start()
    {
       
    }
    public void SetupButtonSelectors(float posY)
    {
        ButtonSelectorLeftSprite = GameObject.Find("ButtonSelectorLeft");
        position = ButtonSelectorLeftSprite.transform.position;
        position.y = (posY / 100.0f);
        ButtonSelectorLeftSprite.transform.position = position;

        ButtonSelectorRightSprite = GameObject.Find("ButtonSelectorRight");
        position = ButtonSelectorRightSprite.transform.position;
        position.y = (posY / 100.0f);
        ButtonSelectorRightSprite.transform.position = position;
    }

    // Update is called once per frame
    void Update()
    {
        if (GlobalVariables.DelayAllUserInput > 0)  GlobalVariables.DelayAllUserInput--;

        if (GlobalVariables.DelayAllUserInput == 0)
        {
            if (GlobalVariables.ScreenToDisplay == 2)
            {
                if (Input.GetKey("up"))
                {
                    if (GlobalVariables.CurrentlySelectedButton > 0)
                    {
                        GlobalVariables.CurrentlySelectedButton--;
                    }
                    else
                    {
                        GlobalVariables.CurrentlySelectedButton = 5;
                    }

                    float yPos = ( 110 - (50*GlobalVariables.CurrentlySelectedButton) );
                    SetupButtonSelectors(yPos);
                   
                    GlobalVariables.SoundEffectToPlay = 3;
                    GlobalVariables.DelayAllUserInput = 10;
                }
                else if (Input.GetKey("down"))
                {
                    if (GlobalVariables.CurrentlySelectedButton < 5)
                    {
                        GlobalVariables.CurrentlySelectedButton++;
                    }
                    else
                    {
                        GlobalVariables.CurrentlySelectedButton = 0;
                    }

                    float yPos = (110 - (50 * GlobalVariables.CurrentlySelectedButton));
                    SetupButtonSelectors(yPos);

                    GlobalVariables.SoundEffectToPlay = 3;
                    GlobalVariables.DelayAllUserInput = 10;
                }
                else if ( Input.GetKey("space") || Input.GetKey("return") )
                {
                    GlobalVariables.SoundEffectToPlay = 2;

                    if (GlobalVariables.CurrentlySelectedButton == 0)
                    {
                        buttonSTART.onClick.Invoke();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 1)
                    {
                        buttonOptions.onClick.Invoke();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 2)
                    {
                       //buttonHowToPlay.onClick.Invoke();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 3)
                    {
                        //buttonHighScores.onClick.Invoke();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 4)
                    {
                        //buttonAbout.onClick.Invoke();
                    }
                    else if (GlobalVariables.CurrentlySelectedButton == 5)
                    {
                        buttonExit.onClick.Invoke();
                    }

                    GlobalVariables.DelayAllUserInput = 10;
                }
            }
        }
    }
}

I had to use using UnityEngine.UI;. Not using UnityEngine.UIElements;