ホーム < ゲームつくろー! < Unity/サウンド編
サウンド編
その2 トリガー駆動のタイミングでSEを鳴らす
前章でUnityでのサウンド再生の根っこを見てきました。Audio ClipがくっついたAudio
Soundを世界にポイっと投げれば勝手に音が鳴るんですから簡単です。でも、ゲームで実際に使うにはもう少し考える事があります。
SEは何らかのきっかけで初めて音が鳴ります。例えばマリオがジャンプしたら「ぴゅい〜ん」とジャンプ音がしますよね。「ジャンプをしたら」というのが「きっかけ」で、そういうきっかけの事を「トリガー」と言います。お手元のゲームを観察すると分かると思いますが、SEはトリガー駆動が殆どです。
ではUnityでトリガー駆動なSEを再生するにはどうしたら良いか?試行錯誤してみます。
@ まずはトリガーを作ろう
まずはトリガーそのものを作ってみましょう。実際はあらゆるトリガーが考えられますが、今はテストなので「キーを押したら」にしておきます。
Unityでキー入力を取るには「Input」というグローバルなクラスをスクリプト上で使用します。スクリプトを動かすにはヒエラルキにGameObjectが必要なので、メニューの[GameObject]→[Empty Object]で空のオブジェクトを一つ追加して「Player」という名前に変更しておきましょう。
PlayerゲームオブジェクトにくっつけるPlayerスクリプトをProject内に追加します。このUpdateメソッド内でInputを使ってキーの押し下げを検出します:
Player.cs using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
void Update () {
if ( Input.GetKeyDown(KeyCode.A) == true ) {
// Torigger
Debug.Log( "A!" );
}
}
}
このスクリプトをPlayerゲームオブジェクトにくっつけてゲームを再生すると、Aキーを押すたびにConsoleウィンドウに「A!」と表示されます。これでトリガーが出来ました。
A 「A」を押すたびにSEを鳴らす
音を鳴らすにはどうしたら良いかおさらいします。音を鳴らす人は「AudioSource」さんです。この人に音の素であるAudioClipをくっつけるとその音が鳴ります。AudioSourceさんはComponentなので、GameObjectにくっつけないと存在出来ません。一方AudioClipはリソースなので、スクリプト内に保持する事が出来ます。
そこで、PlayerさんにAudioSourceコンポーネントをくっつけて、AuidoClipを一つ保持させる事にしましょう。AudioSourceコンポーネントは、前章でも行ったヒエラルキ上でメニューの[Component]→[Audio]→[Audio Source]でくっつきます。
一方で上のPlayerスクリプト内にAudioClipを一つ設けます。publicで公開するとInspector上にAudioClipの設定欄が一つできますので、そこにProject内のAudioClip(kaifuku)をドラッグしてあげます。PlayerゲームオブジェクトのInspectorはこんな感じになります:
Player.cs using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public AudioClip audioClip;
void Update () {
if ( Input.GetKeyDown(KeyCode.A) == true ) {
// Torigger
Debug.Log( "A!" );
}
}
}
Audio SourceのAudio Clipは空のままにするのが大切です。ここに入れるとトリガー関係無くいきなり音が鳴ってしまいます。
音を実際に鳴らすのは、大切なので何度でも言いますが、Audio Sourceさんです。今、PlayerスクリプトがくっついているPlayerゲームオブジェクトにはAudio Sourceがあるんだろうなぁ〜という前提になっていますので、Player.StartメソッドでAudio Sourceコンポーネントを取得する事ができるはずです:
Player.cs using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public AudioClip audioClip;
AudioSource audioSource;
void Start() {
audioSource = gameObject.GetComponent<AudioSource>();
}
void Update () {
if ( Input.GetKeyDown(KeyCode.A) == true ) {
// Torigger
Debug.Log( "A!" );
}
}
}
実際これでAudioSourceコンポーネントを取得できます。出来ちゃえばこっちのもんで、鳴らしたいauidoClipをAudioSourceにスクリプト上からくっつけてしまえます。これはAudioSource.clipというメンバに代入するだけです:
Player.cs void Start() {
audioSource = gameObject.GetComponent<AudioSource>();
audioSource.clip = audioClip;
}
さらにスクリプト上からaudioSourceに「再生せよ!」っと命令するにはAudioSource.Playメソッドを呼び出します:
Player.cs void Update () {
if ( Input.GetKeyDown(KeyCode.A) == true ) {
// Torigger
Debug.Log( "A!" );
audioSource.Play();
}
}
これで「A」を押すと音が鳴ります(^-^)。まとめると、スクリプト上からSEを鳴らすには、
・ AudioClipをスクリプト内に用意
・ AudioSourceをスクリプト内に用意
・ AudioSource.clipにAudioClipを代入
・ AudioSource.Playメソッド呼び出し
でOKです。
B SEが重ならない!
さて、上の実装で実際に「A」を押す度にSEが鳴るのですが、「A」をダダダダダダ!っと連打すると、SEがその度に最初から再生されるのがわかります。長いSEを使うと顕著にわかるはずです。状況にもよりますが、SEは重なって鳴って欲しい事が殆どです。
「A」を押す度にSEを重ねるには、AudioSource.PlayメソッドではなくてAudioSource.PlayOneShotメソッドで音を鳴らします。PlayOneShotメソッドはAudioClipを直接引数に取り、呼ばれる度にそのSEをどんどん重ねてくれます:
Player.cs void Update () {
if ( Input.GetKeyDown(KeyCode.A) == true ) {
// Torigger
Debug.Log( "A!" );
audioSource.PlayOneShot( audioClip );
}
}
これで「A」を連打すると、音が途切れずに重なる事がわかります。
PlayメソッドとPlayOneShotメソッドは、多分前者がBGM、後者がSEで使うように出来ているのかなと思います。
このように、AudioClipとAudioSourceがスクリプト上でわかっていれば、任意のタイミングでSEを鳴らす事は簡単です。ただ、これで使い勝手が良いかというと「ん〜〜…」となってしまいます。SEって何かする度に色々な所から鳴ります。それを逐一GUIで追加していくのは正直しんどいのです。どうせならばスクリプトの中だけで完結してくれると気楽です。次の章ではその辺りを考えて行く事にしましょう。