- Home /
GameObject Audio On Mouse Click
Ok so I have a cube, made in unity. When I click on that cube Id like for an audio sample to play. I have this code but sound doesnt happen, any idea what im missing? I tried looking but I keep seeing this same basic code. There is an audio source on the cube as well.
var Trigger : AudioClip;
function OnMouseDown(){
if (Input.GetButtonDown ("Fire1")) {
audio.Play();
Debug.Log("audio is working");
}
}
Does the Debug appear in the console when you try :
var Trigger : AudioClip;
function On$$anonymous$$ouseDown(){
audio.clip = Trigger;
audio.Play();
Debug.Log("audio is working");
}
Thanks for the Reply Alucardj! So I used what you got there and added some things. The sound does indeed play, and a Gui message pops up when you mouseover the cube BUT, a issue still stands, if you click multiple cubes, you hear multiple audios at the same time. how would I go about, letting the first audio play though before you can hear another if I click elsewhere? Any ideas, THANks again
var stringToEdit = " "; var showgui = false; var playClip : AudioClip;
function OnGUI () { if (showgui) { // $$anonymous$$ake a multiline text area that modifies stringToEdit. stringToEdit = GUI.TextArea (Rect (10, 10, 300, 100), stringToEdit, 200); } }
function On$$anonymous$$ouseDown(){
audio.clip = playClip;
audio.Play();
}
function On$$anonymous$$ouseOver(){ showgui = true; }
function On$$anonymous$$ouseExit(){ showgui = false;
}
I have submitted an answer for one cube that will not play until it has finished playing. For one sound playing at a time, I would do it differently, sorry.
Answer by AlucardJay · Nov 16, 2012 at 07:48 AM
To play music from one cube, then the cube has to finish playing before you can click it to play again :
#pragma strict
var Trigger : AudioClip;
var isPlayingAudio : boolean = false;
function OnMouseDown()
{
if (!isPlayingAudio)
{
isPlayingAudio = true;
audio.clip = Trigger;
audio.Play();
Debug.Log("audio is Playing");
Invoke( "AudioIsFinished", Trigger.length );
}
}
function AudioIsFinished()
{
Debug.Log("audio is Stopped");
isPlayingAudio = false;
}
To Do what you are suggesting of only having one audio but multiple cubes, I would do it totally differently :
On one script, raycast from the mouse position.
If music is not playing :
for the cube that has been hit, assign an audioclip based on its name, and play it.
Set boolean to isPlaying true so that no other cubes can play anything.
same as above to reset the boolean to allow cubes to become playable again.
Did all that make sense?
Alternative 2 :
Actually, I finished it sooner than I thought! Scenario :
Multiple cubes are in the scene. When a cube is clicked, audio is played. No other cube can be clicked until the audio is finished.
There are some rules to make this work.
name your cubes in this format : trackNN e.g. track01 track07 track10 track11 track19 track75 track99 . You can use a capitol T, but the number must be between 00 and 99. You must start at Track01, or it will break. If you dont use 0 in front of single digits it will break . So Track07 is fine, track14 also fine, track1 or Track5 will make it break.
Create an empty gameObject. Attach the below script. (An AudioSource will be added when the script is attached). Let's call it AudioManager
Make all your music cubes children of AudioManager (drag and drop them on the empty object).
In the Inspector of AudioManager, drop your sounds into musicTracks ( it will appear as Music Tracks ).
Important : you must have the same amount of clips as there are cubes, or it will break . The audio must be in the correct order e.g. for music cube 1 (called track01) the first audio in musicTracks will be associated with it. cube track02 is the second audio in musicTracks , etc.
If I have made this not too confusing, you should have no problems inplementing this. The good news is as long as you start your naming with track01 to track10, you can keep adding up to 99 cubes! just make the new cube a child of the AudioManager and drop the sound in the inspector.
Ok finally here's the new script :
#pragma strict
@script RequireComponent( AudioSource );
public var musicTracks : AudioClip[];
private var musicManager : Transform;
private var musicCubes : Transform[];
var isPlayingAudio : boolean = false;
function Start()
{
audio.Stop(); // incase PlayOnAwake is ticked
// check there is music in the Inspector
if ( musicTracks.Length == 0 )
{
Debug.Log( " musicTracks are missing ..." );
}
// load all Music Cubes into array
SetupArrays();
}
function Update()
{
if ( Input.GetMouseButtonDown(0) && !isPlayingAudio )
{
CheckForMusicCube();
}
}
function SetupArrays()
{
musicManager = this.transform;
musicCubes = new Transform[ musicManager.childCount ];
var i : int = 0;
for ( var theTrack in musicManager )
{
musicCubes[i++] = theTrack as Transform;
}
}
function CheckForMusicCube()
{
// raycast to find next clicked cube
var ray : Ray = Camera.main.ScreenPointToRay( Input.mousePosition );
var hit : RaycastHit;
if ( Physics.Raycast( ray, hit, 1000 ) )
{
//Debug.Log( "Ray Hit " + hit.collider.gameObject.name );
var theName : String = hit.collider.gameObject.name;
//var theSubName : String = theName.Substring( 0, 5 );
//Debug.Log( theName + " : " + theSubName );
if ( theName.Substring( 0, 5 ) == "track" || theName.Substring( 0, 5 ) == "Track" )
{
//Debug.Log( theName.Substring( 5, 2 ) + " : " + parseInt( theName.Substring( 5, 2 ) ) );
// get clip from array based on clicked cube
var nextClipIndex : int = parseInt( theName.Substring( 5, 2 ) ) - 1;
var nextClip : AudioClip = musicTracks[ nextClipIndex ];
audio.clip = nextClip;
isPlayingAudio = true;
audio.Play();
//Debug.Log("audio is Playing");
Invoke( "AudioIsFinished", nextClip.length );
}
}
}
function AudioIsFinished()
{
//Debug.Log("audio is Stopped");
isPlayingAudio = false;
}
I have left lots of Debugs in there ready to be uncommented, for troubleshooting if needed. Constructive feedback is welcome. Have Fun =]
Alternative 3 :
If you want to just stop the current audio and play the new audio, you can modify the second example like this :
#pragma strict
@script RequireComponent( AudioSource );
public var musicTracks : AudioClip[];
private var musicManager : Transform;
private var musicCubes : Transform[];
function Start()
{
audio.Stop(); // incase PlayOnAwake is ticked
audio.loop = false; // incase loop is ticked
// check there is music in the Inspector
if ( musicTracks.Length == 0 )
{
Debug.Log( " musicTracks are missing ..." );
}
// load all Music Cubes into array
SetupArrays();
}
function Update()
{
if ( Input.GetMouseButtonDown(0) )
{
CheckForMusicCube();
}
}
function SetupArrays()
{
musicManager = this.transform;
musicCubes = new Transform[ musicManager.childCount ];
var i : int = 0;
for ( var theTrack in musicManager )
{
musicCubes[ i ] = theTrack as Transform;
i ++;
}
}
function CheckForMusicCube()
{
// raycast to find next clicked cube
var ray : Ray = Camera.main.ScreenPointToRay( Input.mousePosition );
var hit : RaycastHit;
if ( Physics.Raycast( ray, hit, 1000 ) )
{
//Debug.Log( "Ray Hit " + hit.collider.gameObject.name );
var theName : String = hit.collider.gameObject.name;
//var theSubName : String = theName.Substring( 0, 5 );
//Debug.Log( theName + " : " + theSubName );
if ( theName.Substring( 0, 5 ) == "track" || theName.Substring( 0, 5 ) == "Track" )
{
audio.Stop(); // stop the current track
//Debug.Log( theName.Substring( 5, 2 ) + " : " + parseInt( theName.Substring( 5, 2 ) ) );
// get clip from array based on clicked cube
var nextClipIndex : int = parseInt( theName.Substring( 5, 2 ) ) - 1;
var nextClip : AudioClip = musicTracks[ nextClipIndex ];
audio.clip = nextClip;
audio.Play(); // play the new track
}
}
}
Alternative 4 :
Here is how to check if the selected cube is the same as the last selected cube, if so then do nothing.
#pragma strict
@script RequireComponent( AudioSource );
public var musicTracks : AudioClip[];
private var musicManager : Transform;
private var musicCubes : Transform[];
private var lastHitCube : GameObject;
function Start()
{
audio.Stop(); // incase PlayOnAwake is ticked
audio.loop = false; // incase loop is ticked
// check there is music in the Inspector
if ( musicTracks.Length == 0 )
{
Debug.Log( " musicTracks are missing ..." );
}
// load all Music Cubes into array
SetupArrays();
}
function Update()
{
if ( Input.GetMouseButtonDown(0) )
{
CheckForMusicCube();
}
}
function SetupArrays()
{
musicManager = this.transform;
musicCubes = new Transform[ musicManager.childCount ];
var i : int = 0;
for ( var theTrack in musicManager )
{
musicCubes[ i ] = theTrack as Transform;
i ++;
}
}
function CheckForMusicCube()
{
// raycast to find next clicked cube
var ray : Ray = Camera.main.ScreenPointToRay( Input.mousePosition );
var hit : RaycastHit;
if ( Physics.Raycast( ray, hit, 1000 ) )
{
// Check if this is not the current selected cube
if ( hit.collider.gameObject != lastHitCube )
{
//Debug.Log( "Ray Hit " + hit.collider.gameObject.name );
var theName : String = hit.collider.gameObject.name;
//var theSubName : String = theName.Substring( 0, 5 );
//Debug.Log( theName + " : " + theSubName );
if ( theName.Substring( 0, 5 ) == "track" || theName.Substring( 0, 5 ) == "Track" )
{
// this is now the lastHitCube
lastHitCube = hit.collider.gameObject;
audio.Stop(); // stop the current track
//Debug.Log( theName.Substring( 5, 2 ) + " : " + parseInt( theName.Substring( 5, 2 ) ) );
// get clip from array based on clicked cube
var nextClipIndex : int = parseInt( theName.Substring( 5, 2 ) ) - 1;
var nextClip : AudioClip = musicTracks[ nextClipIndex ];
audio.clip = nextClip;
audio.Play(); // play the new track
}
}
}
}
yeah dude your suggestion sounds much better, I was actually trying to figure out how to use raycast last night for another script. Im script dumb haha I understand it persay to read, but writing it is a nightmare
if you get some time and feel up to it, give your suggestion a go, I'd love to try it!
Just tried the script above, works great! Thanks alot, your answers always pull though lol.
Thanks. I shall look into making the script I think would be useful to your purpose over the weekend sometime .... =]
Actually, I finished it sooner than I thought! Scenario :
$$anonymous$$ultiple cubes are in the scene. When a cube is clicked, audio is played. No other cube can be clicked until the audio is finished.
Check the edit to the answer. But this part is important, there are some rules to make this work.
name your cubes in this format : trackNN e.g. track01 track07 track10 track11 track19 track75 track99 . You can use a capitol T, but the number must be between 00 and 99. If you dont use 0 in front of single digits it will break . So Track07 is fine, track14 also fine, track1 or Track5 will make it break.
Create an empty gameObject. Attach the below script. (An AudioSource will be added when the script is attached). Let's call it Audio$$anonymous$$anager
$$anonymous$$ake all your music cubes children of Audio$$anonymous$$anager (drag and drop them on the empty object).
In the Inspector of Audio$$anonymous$$anager, drop your sounds into musicTracks ( it will appear as $$anonymous$$usic Tracks ).
Important : you must have the same amount of clips as there are cubes, or it will break . The audio must be in the correct order e.g. for music cube 1 (called track01) the first audio in musicTracks will be associated with it. cube track02 is the second audio in musicTracks , etc.
If I have made this not too confusing, you should have no problems inplementing this. The good news is as long as you start your na$$anonymous$$g with track01 to track10, you can keep adding up to 99 cubes! just make the new cube a child of the Audio$$anonymous$$anager and drop the sound in the inspector.
Answer by Hybris · Nov 15, 2012 at 04:29 PM
1: Get rid of Input.GetButtonDown You dont need it. That might be the problem. further explaination below
2: Make sure you have a Collider attached to the cube
Why are you using a variable for the AudioClip when you dont use it?
3: Make sure you have an audioClip attached to the cube
4: The silly question, did you apply the script to the cube
Why you need to get rid of Input.GetButtonDown: What the script does now is it checks if you clicked your mouse while hovering over the object the script is attached to, but because you have another if statement checking if you clicked with the mouse youll need to click twice in 1 frame. So thats probably your problem. If that doesnt work, use the other 3 checks.
So this is what I was talking about:
//Start code
#pragma strict
private var play = false;
function Update(){
if(play){
audio.Play();
}
}
function OnMouseDown(){
play = true;
yield WaitForSeconds(audio.clip.lenght);
play = false;
}
This should work fine. I havent tested it though.
Thanks for the reply $$anonymous$$! I got rid of Input.GetButtonDown but the audio still doesnt play lol there is a collider on the cube, and the scripts attached to the cube... so strange..
Never$$anonymous$$d I got it, you were right, I took out the audio var it works fine now, stupid mistake haha Thanks a bunch! works great
And boom! I have an idea why it doesnt work. When you click it, it activates in 1 frame right? and so the sound DOES play, but only for 1 frame. You might wanna consider adding some stuff, and ill update my answer to help you.
oh, lol! I made an update nevertheless. hahaha, well at least its fixed! Take a look at the code, or dont!
I would appreciate it if you would accept my answer.
LOL the code above, i tried it, when I click the cube the sound goes really crazy like its playing a million times
Your answer
Follow this Question
Related Questions
Audio to play with mouse axis. 0 Answers
Click Sound 1 Answer
How to prevent more mouse clicks that trigger sound. 3 Answers
Audio stutters at gameObject teleport 1 Answer
Camera rotate with mouse in TPC 0 Answers