Let's create a C# script to do this. Unlike the script we created last time, we're going to create this one through the Project view. From within the Asset pane right click and select: Create C# Script. Name the script "AudioHelper" and paste the following code:
using UnityEngine;
using System.Collections;
public class AudioHelper : ScriptableObject {
public static GameObject PlayClipAt(AudioClip clip, Vector3 pos){
GameObject tempGO = new GameObject("TempAudio"); // create the temp object
tempGO.transform.position = pos; // set its position
AudioSource aSource = tempGO.AddComponent<AudioSource>(); // add an audio source
aSource.clip = clip; // define the clip
// set other aSource properties here, if desired
aSource.Play(); // start the sound
Destroy(tempGO, clip.length); // destroy object after clip duration
return tempGO; // return the AudioSource reference
}
}
This script exposes one function called "PlayClipAt" which does the following:
A note on performance: there is significant overhead in creating and destroying GameObjects dynamically. While the above script should be fine under light load, best practice is to create a "pool" of GameObjects and recycle the "dead" ones. This is beyond the scope of this article and would likely require the expertise of a more advanced programmer. (if you'd like to know more, here's a good post on the topic)
Now let's revisit our "Sphere" script from last time. As you may recall, the script simply detects when the player clicks the sphere and triggers the Audio Source called "sfx". Let's modify the script to play a random sound instead.
Start by renaming the "sfx" asset to "sfx1" and loading another audio file called "sfx2". Next, create a new folder called "Resources" and move both audio assets in. This "Resources" folder has a special meaning to Unity: it's the folder from which we can dynamically load resources such as Audio Clips, which you'll see in a moment.
Finally, let's remove the "sfx" child GameObject from the "Sphere" GameObject:
Your Project view should now look like this, with the "sfx1" and "sfx2" assets contained within the Resources folder:
Now let's revisit the Sphere script. I've disabled the line from last time (in green) and added a few new lines below it:
using UnityEngine;
using System.Collections;
public class Sphere : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnMouseDown() {
// transform.Find ("sfx").audio.Play ();
AudioHelper.PlayClipAt (
Resources.Load<AudioClip> ("sfx" + Random.Range(1, 3)),
GameObject.FindGameObjectWithTag ("MainCamera").transform.position);
}
}
Let's break it down a bit.
This line says "we want to call the function PlayClipAt from the class called AudioHelper"
AudioHelper.PlayClipAt (
The next two lines define the arguments being passed to the function (AudioClip, Vector3). You don't need to be too concerned with what a Vector3 is, but simply put it stores X, Y and Z coordinates in 3D space.
This line loads an asset of type "AudioClip" from the resources library. Specifically, it will load a file named either "sfx1" or "sfx2". The call to Random.Range (1 , 3 ) is a bit misleading--it actually returns a number between 1 and 2, per the documentation)
Resources.Load<AudioClip> ("sfx" + Random.Range(1, 3)),
The final line finds the position of the "MainCamera" GameObject:
GameObject.FindGameObjectWithTag ("MainCamera").transform.position);
Play the Scene and click the sphere a few times. You'll notice it randomly plays one of the two clips. You'll also notice GameObjects named "TempAudio" appearing and disappearing from the Hierarchy as you do so.
Developments for Korg's instrument have been slow but promising.
The Avila Brothers talk about their journey to the recent Super Bowl Halftime Show