- Home /
storing sounds in Array and calling PlayOneShot from other class
Hi Folks,
I have the following newbie problem and its getting frustrating so Im asking you in the hope someone has a hint:
I have two scripts: AudioClipPlayer is attached to an empty gameobject and has an array loaded up with AudioClips. The second scipt has been added multiple Sprite objects and it supposed to call the AudioPlay() function in the AudioClipPlayer whenever the sprite object receives a click.
Calling the AudioPlay() script internally within the class working fine - see the commented section in AudioClipPlayer:
using UnityEngine;
using System.Collections;
public class AudioClipPlayer : MonoBehaviour {
public AudioClip[] audioarray;
public void Start()
{
audioarray = new AudioClip[]
{
Resources.Load("bark") as AudioClip,
Resources.Load("meow") as AudioClip
};
//the following line of code successfully play an audioclip:
//PlaySound();
}
public void PlaySound()
{
audio.PlayOneShot(audioarray[1]);
}
}
Here is the script ( stripped down version ) which is attached to the Sprite objects:
using UnityEngine;
using System.Collections;
public class AnimalScript : MonoBehaviour
{
AudioClipPlayer audioClipPlayer = new AudioClipPlayer();
public Sprite newSprite;
public void OnMouseDown()
{
audioClipPlayer.PlaySound();
}
}
however calling the PlaySound() from this class fails with the following error message:
AudioClipPlayer.PlaySound () (at Assets/AudioClipPlayer.cs:49) AnimalScript.OnMouseDown () (at Assets/AnimalScript.cs:39) UnityEngine.SendMouseEvents:DoSendMouseEvents(Int32, Int32) Hope someone can give me a hint - Thank you guys!NullReferenceException
Answer by kacyesp · Sep 02, 2014 at 08:44 PM
Add a constructor to your AudioClipPlayer and pass in the audio field. There's no need for AudioClipPlayer to implement MonoBehaviour.
Code with the constructor and without MonoBehaviour:
using UnityEngine;
using System.Collections;
public class AudioClipPlayer {
public AudioClip[] audioarray;
public AudioSource audio;
public AudioClipPlayer( AudioSource audio )
{
this.audio = audio;
audioarray = new AudioClip[]
{
Resources.Load("bark") as AudioClip,
Resources.Load("meow") as AudioClip
};
}
public void PlaySound()
{
audio.PlayOneShot(audioarray[1]);
}
}
Code passing in the audio field:
using UnityEngine;
using System.Collections;
public class AnimalScript : MonoBehaviour
{
AudioClipPlayer audioClipPlayer = new AudioClipPlayer( audio );
public Sprite newSprite;
public void OnMouseDown()
{
audioClipPlayer.PlaySound();
}
}
Thanks kacyesp, This solution is working as well! However Im wondering how doest it affect the performance if all my 20 - 30 Animal GameObjects will have an AudioSource on them?
...its a 2D game and doesn't really matter from which direction the sound is co$$anonymous$$g from so I'm not trying to make it stereo.
I don't know how performance heavy AudioSources, and I'm not sure many people do. But I do know that you have 2 options when it comes to this. The first option is what you're already doing. You can use an AudioSource for each game object, but obviously the space you use will increase. The 2nd option is you can pool AudioSources to play sounds, so you'd use like 1 to 4 AudioSources to play all the sounds you want. A single AudioSource can play multiple sounds simultaneously using PlayOneShot(). The problem with this option is that every time you call PlayOneShot(), a brand new AudioSource is created and then destroyed at the end of the clip. I would post another question asking what's a good balance of AudioSources to use. But I think if you're not worried about space, creating an AudioSource for each game object is the best option.
Answer by smoggach · Sep 02, 2014 at 08:42 PM
The problem is that you are instantiating a monobehavior. Monobehavior is only meant to go on script components. Because you instantiate it from another object's Start it never receives a Start function of it's own until the next frame.
I'd recommend using a Singleton. In the Awake function of AudioClipPlayer: DontDestroyOnLoad();
Then attach that script to it's own global gameobject. Now it will exist in all the scenes.
However it's still tricky to access so you'll have to add a static instance variable. public static AudioClipPlayer Instance;
Now back in the Awake function: Instance = this;
Now from any of your scripts you can simply call: AudioClipPlayer.Instance.PlaySound();
Thanks smoggach for pointing out the mistake....I've converted the AudioClipPlayer to singleton and now it works. thanks again!
Answer by pintin · Sep 30, 2015 at 04:51 PM
Yes. you should seo and merketing. Whether you are an owner of a company with hundreds of employees or just own a small shop, business to succeed you need to have an effective marketing strategy and apply it frequently. However, this does not require you to spend too much money and you do not necessarily have to be a creative genius dora, kizi.
Your answer
Follow this Question
Related Questions
Where does streamed audio clip stored and removed? 0 Answers
Microphone Position goes larger than predetermined number of samples 0 Answers
Extract audio clip from VideoPlayer for real-time processing 0 Answers
Microphone capture different channels 0 Answers
How to manage player and enemies shooting sounds at the same time? 1 Answer