-->

main-navbar

Saturday, June 6, 2015

Button Sounds

For code example, skip to the middle.

The new user interface tools in unity 4.6 and 5 are good...but not for programmers, or when you want to have complex interfaces, with a lot of code generated buttons for example. In my project, I decided to go for a mix: I used the new user interface tools for simple things, like main menu buttons and affects, and used the legacy GUI system for more complex things like hidden or context generated menus.

Using the new ui tools, it is very easy to setup the sounds that play when you mouse over or click a button. Even better, with the prefab system, you can make a default button prefab that has all the sounds and affects already setup, and easily reuse it wherever you need to.

The legacy ui, however, is a little more difficult. Setting up the ui skin is quite tedious, but it is worth it in the long run, especially if you have a lot of code generated ui. I wrote a blog post a while back detailing how to do this with half decent results.

Adding sounds to the legacy GUI system:

There are two main sounds most ui's have: a sound to play when the mouse clicks on a button, and a sound for when the mouse hovers over something. The first is easy, Just call the code to play the sound when GUI.Button returns true. It feels a little inefficient though, having to add that code for every single button. And what if you want to change it? Now you have to go through all the buttons, and change the code inside each. While there are programming patterns that make doing this easier, there is a better way.

The second main sound that ui's have, is the sound that plays when the mouse hovers over a button. One problem: there is no built in way for you to detect if the mouse is hovering over a button! There are several workarounds though, using google turns up several solutions: here, here and here. One solution is to add rects everywhere and detect if the mouse position is inside the rect. The other solutions use the GUI.tooltip.

I like the GUI.tooltip solution, its way less messy then having to spawn a rect for each button. The GUI.tooltip is a litle tricky though, For one, you have to have it unly update during repaint events, like:

if(Event.current.type == EventType.Repaint){
} 
 

In addition, you have to make it only play the sound once when the mouse is over the gui 
element, and play again when the element changes. The code ends up getting a little messy, but in the end, it works very well.

This is my code:

Variables:









//the previous tooltip
var prev: String = "";

//is the mouse button being pressed?
var pressed: boolean = false;

//the tooltip
var hoverButton: String  = "";





Inside OnGUI:





//Play a sound if we mouseover something
hoverButton = GUI.tooltip;
if(Event.current.type == EventType.Repaint){ if(hoverButton != ""){ if(Input.GetMouseButton(0) || Input.GetMouseButton(1)){ if(!pressed){ PlayMyButtonPressedSound(); } pressed = true; } else{ pressed = false; } if(hoverButton != prev){ PlayMyButtonHoverSound(); } }
 prev = hoverButton;
}




Just make sure each ui element has a GUIContent with the correct parameters, and each tooltip for each button has to be different. So for example:






if (GUI.Button(SomeRect, GUIContent ("Text displayed on the button", "Unique Tooltip")){
 DoSomething();
}

No comments:

Post a Comment