OnMouseDown vs OnGui

I did this script to play a sound when I press a button. I realized that it plays only when I release the button.

var MySound: AudioClip;

function OnGUI () {
	if (GUI.Button (Rect (150,150,60,60), "Play Sound")) {
 
   audio.PlayOneShot(MySound);
              
        }
}

I tried many different ways to use onMouseDown but I can’t make it work with the GUI. Any ideas?

Thanks

Robert

Like buttons in Mac OS, Windows, etc., buttons in the Unity GUI don’t register as being clicked until you press AND release the mouse-button while over the same button. This gives the nice option of stopping an accidental click by moving the mouse cursor away from the button before releasing the mouse-button. Think of it as a safety feature :slight_smile:

The OnMouseDown event does not work with UnityGUI. UnityGUI is about the OnGUI event and all the controls you can draw while handling an OnGUI event.

The Manual states OnMouseDown is sent, when mousing-down-over a GUIElement. A GUIElement is part of the older, though still useful, means of displaying an in game GUI. It also involves GUI Layers, GUI Text and GUI Texture.

Have said all that, for you purposes try a RepeatButton instead of a plain Button. From the manual:

HTH

Hi DGuy,

I can’t use the RepeatButton because I’m playing a sound and it just plays the sound non-stop like crazy. So I guess I need to do this the old way but I have no idea on how to do it. Can you help? Just need a script to play a sound on mouse down on a texture GUI.

Thanks,

Robert

I spend hours trying to get onMouseDown working on the iPhone and I just couldn’t make it work for the simple reason that it’s disabled on the iPhone version of Unity! It would have been nice to know that… it’s not written in the documentation! But hey, it’s a version 1 do I guess there’s a lot to change in the docs. Anyway, I finally found a workaround here to get my onMouseDown working anyway:

http://forum.unity3d.com/viewtopic.php?p=122914#122914

Use a boolean to ensure the sound is only triggered once?

Ok, and how would I do that?

By wrapping the sound activation in a little state machine?

// Forum Code
var soundPlaying = false;

OnGUI() {

if RepeatButton() {

 if (soundPlaying == false) {
  sound.PlayOneShot();
  soundPlaying = true;
 }
// Do other button crap
}
 else
 soundPlaying = false;

I tried this but it still doesn’t work. Sound continue to repeat non-stop

var soundPlaying = false;
print (soundPlaying);
function OnGUI () {

if (GUI.RepeatButton (Rect (210,0,60,60), "North")) {

 if (soundPlaying == false) {
  audio.PlayOneShot(Cymbale);
  soundPlaying = true;
 }
animation.CrossFade("NorthAnim");


}
 else
 soundPlaying = false;   
print (soundPlaying);
} else { 
 soundPlaying = false;    
print ("I just reset my bool");
}

Try making this change and see what’s going on.

Alternately you can explicitly reset the bool on mouse up.

As soon as I press play I get the “I just reset my bool” message. If I press my button it stays the same.

This entire issue is because there’s no mouseUp / mouseDown on the iPhone version. Can’t do that.

I’m still working on the workaround I mention before but I ran into another problem. The script is attach to the GUI Texture but it call for an animation on another asset and I don’t know how to do that either. It keeps looking for the anim on the GUI texture.

I’m exhausted… I spend 6 hours trying to get this fixed…

That would imply that RepeatButton is both returning true and false at the same time, which wouldn’t make much sense.

I don’t know what to tell you. What happens if you try it on you side?

You could just use an image instead of a button and then detect where the mouse is and whether or not it’s in your button area.

So, here’s some psuedo code:

function OnGUI() {
   var myImageRect = Rect (150,150,60,60);

   GUI.DrawTexture (myImageRect, playSoundImage);

   // Get a left click
   if ( Input.GetMouseButtonDown(0) ) {
      var myMousePos = Input.mousePosition;

      // Convert from screen coordinates to GUI coordinates since screen's y = 0 is bottom and GUI's y = 0 is at the top
      myMousePos.y = Camera.main.pixelHeight - myMousePos.y;

      // Psuedo code!!! You'll probably need at least 4 if statements... don't forget the window rect if this button is in a GUI.Window()
      if ( myMousePos is within myImageRect ) {
         audio.PlayOneShot(MySound);
      }
   }
}

edit: corrected some code

Hope this helps,
Nathan

Untested code, but you get the idea:

var _mySound : AudioClip;

private var _buttonRect = new Rect(150.0, 150.0, 60.0, 60.0);

function OnGUI()
{
    GUI.Button(_buttonRect, "Play Sound");
    
    if (Event.current.type == EventType.MouseDown)
    {
        if(_buttonRect.Contains(Event.current.mousePosition)
        {
            if(!audio.IsPlaying())
            {
                audio.PlayOneShot(MySound);
                Event.current.Use(); 
            }
        }
    }
}

-Jeremy

While you can see people are pretty helpful around here, for future reference, when asking a technical question, just so everyone is on the same page, so to speak … mention what version of Unity your using.

While in the vast majority of cases, it won’t or shouldn’t make a difference … It just might help someone offer up a solution quicker.

:slight_smile:

It was so simple (once you know how to do it…)

After plugging the onMouseDown script on my camera (available here:

http://forum.unity3d.com/viewtopic.php?p=122914#122914

all I needed was to assign this to my GUITexture:

var Cymbale : AudioClip;


function OnMouseDown( ) {

audio.PlayOneShot (Cymbale);
GameObject.Find("Sphere").animation.Play("Default");
 
}

et voilà!