GUI Button keyboard?

I have created a simple Main Menu using GUI.Buttons. The work fine with the mouse, but how can I make them work with the keyboard? (Arrow keys for choosing an entry, enter to confirm)

Grab the events you need from the Input class and use those to trigger the effects you want. Unity’s GUI does not support keyboard input natively, so you will have to manually trigger a lot of the effects that you take for granted with the mouse, for example, the hover effects to indicate the current selection.

Using arrow keys to change button focus:

You need to set the “name” of each button via [GUI.SetNextControlName();][1] then you switch focus with [GUI.FocusControl();][2]

Using buttons with keypresses:

GUI.Button returns a boolean value. You store the button in a boolean variable and change the value of it whenever the keystroke triggers.

Example (in C#):

string[] buttonNames = {"Resume", "Main Menu"};
bool[] buttons;
int currentSelection = 0;    // current button selected

void Start() {
    buttons = new bool[buttonNames.Length];
}

void OnGUI() {
	// Generate buttons, store into buttons array
	for (int i = 0; i < buttonNames.Length; i++) {
		GUI.SetNextControlName(buttonNames*);*

buttons = GUI.Button(new Rect(10, 70 + (20 * i), 80, 20), buttonNames*);*
* }*

* // Using button with keystroke*
* if (Input.GetButton(“Use”)) {*
* // When the use key is pressed, the selected button will activate*
* buttons[currentSelection] = true;*
* }*

* // Button conditions*
if (buttons[0]) {
// resume
}
if (buttons[1]) {
// return to main menu
}

// Cycling through buttons
if (Input.GetButton(“Down”)) {
GUI.FocusControl(buttonNames[currentSelection + 1]);
}
if (Input.GetButton(“Up”)) {
GUI.FocusControl(buttonNames[currentSelection - 1]);
}
}
Bear in mind that this snippet of code doesn’t check whether or not currentSelection is outside of the buttons array index. I also haven’t tested this exact code myself. I sort of copied it from my own project (I have a separate class handling menu navigation via gamepad).
I hope this helps :slight_smile:
*[1]: http://unity3d.com/support/documentation/ScriptReference/GUI.SetNextControlName.html*_
*[2]: http://unity3d.com/support/documentation/ScriptReference/GUI.FocusControl.html*_

I answered something similar on another forum. Here’s what you do (the same logic applies for C# but I will do it in javascript/unityscript):

#pragma strict
@script ExecuteInEditMode;

var selGridInt : int = 0;    //This integer is the index of the button we are hovering above or have selected

var selStrings : String[] = ["Grid 1", "Grid 2", "Grid 3", "Grid 4"];

private var maxButton : int;    // The total number of buttons in our grid

function Start()
{
    maxButton = selStrings.Length;    // Set the total no. of buttons to our String array size
}

funtion Update()
{
    // Get keyboard input and increase or decrease our grid integer
    if(Input.GetKeyUp(KeyCode.UpArrow))
    {
        // Here we want to create a wrap around effect by resetting the selGridInt if it exceeds the no. of buttons
        if(selGridInt > 0)
        {
            selGridInt--;
        }
        else
        {
            selGridInt = maxButton - 1;
        }
    }

    if(Input.GetKeyUp(KeyCode.DownArrow))
    {
        // Create the same wrap around effect as above but alter for down arrow
        if(selGridInt < (maxButton-1))
        {
            selGridInt++;
        }
        else
        {
            selGridInt = 0;
        }
    }

    if(Input.GetKeyUp(KeyCode.Return))
    {
        switch(selGridInt)
        {
            case 0: Debug.Log("Button "+(selGridInt + 1 )+ " pressed.");
                break;
            case 1: Debug.Log("Button "+(selGridInt + 1 )+" pressed.");
                break;
            case 2: Debug.Log("Button "+(selGridInt + 1 )+ " pressed.");
                break;
            case 3: Debug.Log("Button "+(selGridInt + 1 )+ " pressed.");
                break;
        }
    }
}

function OnGUI () 
{
    selGridInt = GUI.SelectionGrid (Rect (Screen.width/2-75, Screen.height/2-25, 150, 200), selGridInt, selStrings, 1);
}