I have 10 buttons (like a hotbar). But I don’t want to use a mouse ingame. So I need to make the buttons respond to the key-presses 0-9.
Note: I DON’T want to attach some code to the onclick event. I know how to do that. I also know how to configure the Input manager. I basically need to bind the keyboard keys to specific UI-Buttons and disable the mouse input on them.
Hotbar panel script (with the hotbar buttons as children):
void OnGUI()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
GetComponent<Transform>().FindChild("Hotbar1").... ? // show button-down transition
else if (Input.GetKeyUp(KeyCode.Alpha1))
GetComponent<Transform>().FindChild("Hotbar1").... ? // show button-up transition AND actually click it so that it fires the attached on-click() methods.
// TODO: do this in a for-loop for all 10 buttons.
}
Where are my Button.click() or Button.down() & up() methods? I also tried manually setting the transition state (dirty method though) but I don’t seem to be able to access that either. Is this even possible without coding my very own button?
I also checked out: http://unity3d.com/learn/tutorials/modules/beginner/ui/ui-button but it didn’t explain it either. It assumes that you always use a mouse. But I read that Unity does not support keyboard-input for their GUI other than [Spacebar] for pressing the currently selected button…
Well that was trickier than I expected… but I have come up with a clean solution using only public interfaces to the Unity UI system.
Attach the KeyButton script to a regular UI.Button
Set the key to whatever KeyCode you want to bind to
Configure colors and transition normally via inspector (normalColor and pressedColor). Note: the script co-opts disabled state so disabling is not supported in the current form… it would be easy enough to add.
Configure onClick events as normal via the inspector.
You can create a prefab to make initial creation easier but you will still need to set the key to indicate which key press the button is bound to.
There were quite a few edge cases to cater for (mouse movement initiating state changes, app losing focus etc) but the script seems fully armed an operational now.
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Button))]
public class KeyButton : MonoBehaviour {
public KeyCode key;
public Button button {get; private set;}
Graphic targetGraphic;
Color normalColor;
void Awake() {
button = GetComponent<Button>();
button.interactable = false;
targetGraphic = GetComponent<Graphic>();
ColorBlock cb = button.colors;
cb.disabledColor = cb.normalColor;
button.colors = cb;
}
void Start() {
button.targetGraphic = null;
Up();
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(key)) {
Down();
} else if (Input.GetKeyUp(key)) {
Up();
}
}
void Up() {
StartColorTween(button.colors.normalColor, false);
}
void Down() {
StartColorTween(button.colors.pressedColor, false);
button.onClick.Invoke();
}
void StartColorTween(Color targetColor, bool instant) {
if (targetGraphic == null)
return;
targetGraphic.CrossFadeColor(targetColor, instant ? 0f : button.colors.fadeDuration, true, true);
}
void OnApplicationFocus(bool focus) {
Up();
}
public void LogOnClick() {
Debug.Log ("LogOnClick() - " + GetComponentInChildren<Text>().text);
}
}
— Previous Answer —
You need to add an EventTrigger to expose the full suite of UI events, including OnPointerDown and Up.
EventTrigger is added to the GameObject containing the UI element that needs to handle the events.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class KeyEnter : MonoBehaviour {
public string inputName;
Button buttonMe;
// Use this for initialization
void Start () {
buttonMe = GetComponent<Button>();
}
void Update() {
if(Input.GetButtonDown(inputName))
{
buttonMe.onClick.Invoke();
}
}
}
Just create script with name KeyEnter, put there this code, attach it to a button, and from there You can just add in inspector key name You want to work with (all key names are edited in input manager).
I would use IEnumerable for better performance, but this way Im sure buttons only works when they are enabled (Im not so sure in case of coroutines).
Of course You can add any additional effects, but I didn`t needed them.
So… Why is everyone using so much code here? Super Simple:
Just apply this script to your button and choose what button you want to trigger.
using UnityEngine;
using UnityEngine.UI;
public class triggerButtonWithKey : MonoBehaviour
{
public KeyCode key;
void Update()
{
if (Input.GetKeyDown(key))
{
GetComponent<Button>().onClick.Invoke();
}
}
}