(Solved) Share One AudioSource Between Several GUI Buttons

Put this on “Unity Answers” but have now moved it to Forum because there’s no obvious way of doing it (yet).

I’ve got a menu set up with a series of colored buttons. The game is for kids who can’t read, so when they click a button a sound file plays with instructions.

I’ve got each button set up so that if the player repeatedly clicks on ONE of the buttons repeatedly, the playing sound stops and starts again from the beginning, so that the same sound doesn’t play over itself.

However, if the player repeatedly clicks MORE THAN ONE button, by going quickly and repeatedly from one button to another, the sounds for each button play over one another. because they’re kids, they are likely to do this!

Anyone please got any idea how I can prevent more than one sound being played at a time when they are activated from separate sources and from separate scripts?

The first answer I got was to write code like this for each button:

var audioSources[] : GameObject; // add all of your audio sources

if (GUILayout.Button("1")){
   for(eachAudio in audioSources)
      eachAudio.audio.Stop();
   audio.clip = clip1;
   audio.Play();
}

but when I enter the first line. The symbols threw up an error.

The second answer I got was to

.

I tried this by deleting all but one of the audio sources.
On a button without an audio source (redButton) I attached a code starting

var ohdear : AudioClip;
var press : AudioSource;

In the inspector of that object, I linked the “press” variable to the Audio Source of the single button that had one (blueButton). I then continued the code with

function OnMouseUp () { 
press.audio.PlayOneShot (ohdear); 
}

This still brings up an error of “There is no ‘AudioSource’ attached to the redButton game object, but a script is trying to access it”.

I’ve been tearing my hair out on this for three days now, and being in my 60’s I had hardly any hair to start with. My wife’s complaining and wearing sun glasses because of the glare.

Anyone please got any ideas of how I can do this?

Kukuku…the detestable fat chicken laughs

More seriously, why don’t you make a single game object with an AudioSource and a special script ?
Make a simple function, like :

function SetAndPlay (audioClip : AudioClip)
{
	if (audio.isPlaying)
		audio.Stop ()
		
	audio.clip = audioClip;
	audio.Play ();
}

Sorry Akilae. Getting tired now, so haven’t understood. The Alzheimer’s is obviously setting in.

I have only got one game object with an AudioSource now, but I also have several buttons that don’t have an AudioSource, but which need to play audio files when they’re clicked.

Do you mean that I should create the above script and add it to the buttons that don’t have an AudioSource?

You put that script on the game object with the AudioSource, you call it SoundPlayer.js, for example (therefore, you make a SoundPlayer class).

In the scripts, with the button script, you add :

public var soundPlayer : SoundPlayer;
public var soundToPlay : AudioClip;

if (GUI.Button) soundPlayer.SetAndPlay (soundToPlay);

Akilae,

Thanks for your patience with this old git. I’ve decided coding is a young man’s game. Trying to learn it’s making my brain hurt.

On my blueButton (the button with an AudioSource) I’ve now attached a SoundPlayer script as follows

function SetAndPlay (audioClip : AudioClip)
{   
if (audio.isPlaying)
audio.Stop ();
audio.clip = audioClip;
audio.Play ();
}

On my redButton (the one without an AudioSource) I’ve got the following code attached

var welldon : AudioClip;
public var soundPlayer : SoundPlayer;
public var soundToPlay : AudioClip;

function OnMouseUp () {
soundPlayer.SetAndPlay(welldon);

Still getting the error

Yes and no.

You make a game object with an AudioSource, and the SoundPlayer script on it. The object is only used to play sounds that must not overlap, by using the SetAndPlay function.

For every other script that plays an AudioClip that do not overlap each other, you add in those script two variables : a variable stating which AudioClip to play (soundToPlay), and the gameobject who will play it (soundPlayer).

In the inspector, you define the first game object, with the SoundPlayer component and the AudioSource component in the soundPlayer variable…

Since the component SoundPlayer has the function SetAndPlay, and soundPlayer is a variable of type SoundPlayer, if the variable soundPlayer contains a component, you are able to make it run the function (by writing soundPlayer.SetAndPlay (soundToPlay).

var welldon : AudioClip;
public var soundPlayer : SoundPlayer;
public var soundToPlay : AudioClip;

Why two AudioClip ?

In my post to your thread at Unity Answers, I suggested that you try:

press.PlayOneShot (ohdear);

In place of:

press.audio.PlayOneShot (ohdear);

But looking at the code you’ve posted here, it looks like you still have:

press.audio.PlayOneShot (ohdear);

Did you get a chance to try my earlier suggestion? If so, what were the results?

AkilaeTribe has already offered a solution, but just to give you another view of the problem, let’s back up and take another run at it.

The idea is not to attach an audio source to any one button object, but to attach it to a single, separate game object whose only purpose is to play sounds. This is the game object to which you’d attach the code that AkilaeTribe posted.

Note that this object will need an audio source component. The error you’re getting currently:

MissingComponentException: There is no 'AudioSource' attached to the "HereIsJim" game object, but a script is trying to access it. 
You probably need to add a AudioSource to the game object "HereIsJim". Or your script needs to check if the component is attached before using it.

Is telling you that there’s no AudioSource component attached to the specified game object, and that you probably need to add one. Does the ‘HereIsJim’ game object have an AudioSource component attached to it?

Picking up where we left off, you’ll need to somehow make the ‘sound player’ game object accessible to the buttons. One way to do this is to drag the object onto a public field, as you’ve been doing. If there aren’t that many buttons this shouldn’t be too hard, but if there are many buttons, you might want to acquire a reference to the game object in the button Start() function instead, e.g. using GameObject.Find() or GameObject.FindWithTag().

Thanks Akilae.

I’ll try this tomorrow when I’m fresh. I’ve been trying to sort this out for the past ten hours so my brain’s spinning a bit (I was trying all day yesterday as well!).

It’s a game for kids that can’t read, so all the instructions need to be in sound files. Hence the menu with several different coloured buttons all playing different sound files when they’re clicked on.

Being kids, I’m anticipating them messing about by clicking all the buttons quickly one after another, setting all the sounds off on top of one another. So I’m trying to ensure that only one button works at a time, or only one sound plays at a time.

If they repeatedly click ONE button, I can control the sound. But if they repeatedly click on SEPERATE buttons, I can’t stop the sounds overlapping.

Jesse,

When I replaced

press.audio.PlayOneShot (ohdear);

with

press.PlayOneShot (ohdear);

I still got the error.

When I tried it with an Audio Source on every button, the sound from severable buttons was still playable at the same time.

When I tried it with an Audio Source on only one button, but with ‘press’ of every other button linked to the audio button with the one remaining Audio Source, pressing any of the other buttons brought up the ‘No audio Source attached’ error.

Jesse / Akilae,

Next, I deleted all the audio sources.

I then created a new empty game object soundPlayer’ and attached a new audio source to it.

I attached Akilae’s SoundPlayer.js script to the ‘soundPlayer’.

function SetAndPlay (audioClip : AudioClip)
{
   if (audio.isPlaying)
      audio.Stop ();      
   audio.clip = audioClip;
   audio.Play ();
}

I added the following to the code on each of the buttons:

public var soundPlayer : SoundPlayer;
public var soundToPlay : AudioClip;

and because each button plays different sounds depending upon conditions I used

function OnMouseUp () {
soundToPlay = welldon;
soundPlayer.SetAndPlay (welldon);
}

or something similar, for each of the sounds I wanted each button to play.

In the Inspector, I attached SoundPlayer to the soundPlayer AudioSource.

The whole thing works exactly as I wanted it to. You guys are brilliant!! I couldn’t have worked this out on my own.

Thanks for the clear explanation.

I am really very obliged (and as I’m now no longer worrying about how to do this; I’m now going to bed)!

Thank you.

I don’t think anyone mentioned this, but the reason your original code threw an error was because you misplaced the brackets.

var audioSources[ ] : GameObject;

should be

var audioSources : GameObject[ ];

Here it is the working souce code.

First add sound source to your object gui then this:

This thread is a couple of months old; also, I’m not entirely sure how applicable your code is to the OP’s problem.

In any case, when posting code, you can use ‘code’ tags (rather than quote tags) to get a code box with formatting.

tks for the tip:)

hey man, when you say attatched SoundPlayer to the soundPlayer AudioSource… what do you mean exactly, this looks like an awesome approach, i’m getting error: The name ‘SoundPlayer’ does not denote a valid type (‘not found’). Did you mean ‘System.Net.Mail.SmtpFailedRecipientException’?

would be awesome to know, i have been trying all day with stopping all audio sources to no avail :frowning: x

hey man, when you say attatched SoundPlayer to the soundPlayer AudioSource… what do you mean exactly, this looks like an awesome approach, i’m getting error: The name ‘SoundPlayer’ does not denote a valid type (‘not found’). Did you mean ‘System.Net.Mail.SmtpFailedRecipientException’?

would be awesome to know, i have been trying all day with stopping all audio sources to no avail x