今回はゲームっぽくする為にUnityでBGMの設定と細かなところに効果音を設定してみます。
前回は主人公と敵が攻撃を受けた時に血のエフェクトを発生させました。

BGM(Background Music)はゲーム中にずっと流す音でループ再生して永遠に流れるようにします。
効果音はインスペクタで音声を指定し、スクリプトで音声を鳴らすようにします。
BGMは常に流れるのでMainCameraに設定し、効果音は敵が攻撃してくる時と剣を振る時に鳴らします。
↑のような感じにゲームに豪華さがうまれます。(^^)/
懐中電灯を持っている時は攻撃のアニメーションをしても鳴らさないようにするので、今持っているのがただの持ち物か武器かを判定して区別する必要があります。
今回の記事では以前作成したスクリプトに処理を追加していますが、以前作成したスクリプトはどんなだったかを知りたい方は

の記事で今までの流れが確認出来ます。
MainCameraにAudio Sourceコンポーネントを追加する
MainCameraにAdd Component→Audio Sourceを追加し、AudioClipを設定します。
PlayOnAwakeでインスタンスが登場したと同時に再生されます。Loopにチェックを入れているので、音声が永遠に流れます。
BGMに使う音声は
Asset Store→オーディオ→その他→Free music packをインポートしました。
Free Pack→Short epic trailer(free)をAudio SourceのAudio Clipに選択しました。
これでBGMの設定は終了です。
敵がうめき声を出すようにする
次に敵が攻撃する時にうめき声を出すようにします。
敵の行動を処理するスクリプトEnemyにフィールドを宣言します。
1 2 3 4 5 6 | // 攻撃をする時の音 [SerializeField] private AudioClip attackSound; private AudioSource audioSource; |
attackSoundにはFree Pack→Monster screams→Monster screams – 57を選択しました。
Startメソッド内に
1 2 3 | audioSource = GetComponent<AudioSource> (); |
とコンポーネントを取得する処理を追加します。
AudioSourceは

で使っているので、すでに追加されています。追加されてない場合は追加してください。
AudioSourceのPlayOnAwakeのチェックを外し、Loopのチェックも外します。
AudioClipには何も設定する必要はありません。
スクリプトから追加するようにAppearSEスクリプトでしている場合は追加処理を削除した処理に書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | using UnityEngine; using System.Collections; public class AppearSE : MonoBehaviour { private AudioSource audioSource; // 鳴らす音声クリップ [SerializeField] private AudioClip appearSE; void Start () { audioSource = GetComponent <AudioSource> (); audioSource.PlayOneShot (appearSE); } } |
あとはEnemyスクリプトのSetStateメソッドのAttack状態へと変更する処理で音を鳴らすようにします。
1 2 3 4 5 6 7 | } else if (tempState == EnemyState.Attack) { velocity = Vector3.zero; animator.SetFloat("Speed", 0f); animator.SetBool("Attack", true); audioSource.PlayOneShot(attackSound); |
これで敵キャラが攻撃時にうめき声をあげる事になります。
敵キャラの攻撃機能に関しては

を参照してください。
剣を振った時に効果音を鳴らす
最後に主人公が剣を振る時に音声を鳴らす処理です。
主人公のインスペクタのAdd ComponentからSound→Audio Sourceを取り付けておきます。
PlayOnWakeとLoopのチェックを外しておきます。
AssetStoreでオーディオ→効果音→武器のBlade Soundsをインポートしました。
主人公の攻撃機能に関しては

を参照してください。
剣を振る時ということはアニメーションイベントAttackStartを受け取った時に音声を鳴らせばいいので、ProcessCharaAnimEventスクリプト内に
1 2 3 4 5 6 7 | private AudioSource audioSource; [SerializeField] private AudioClip attackSound; [SerializeField] private Transform equipTransform; |
を宣言します。
attackSoundにはBlade Sounds→Slashing→Slash1を設定しました。
equipTransformは今装備している武器を知る為に主人公のEquipゲームオブジェクトをインスペクタで設定します。
StartメソッドにAudioSourceコンポーネントを取得する処理を記述します。
1 2 3 | audioSource = GetComponent <AudioSource> (); |
主人公のアニメーションイベント受け取りスクリプトであるProcessCharaAnimEventのAttackStartメソッドが剣を振り始める時に実行されるので、剣を振る音もそこで鳴らす事にします。
1 2 3 4 5 6 7 | void AttackStart() { weaponCollider.enabled = true; if (equip.GetChild (0).CompareTag ("Sword")) { audioSource.PlayOneShot (attackSound); } } |
装備をスクリプトからインスタンス化しひとつしか持たないようにしている場合はequipの子要素の1番目が武器になるので、その武器にSwordタグが設定されているかどうかを調べ、Swordであれば攻撃用の音声を鳴らしています。
武器となるインスタンスまたはプレハブにSwordというタグを作り、Tagに指定しておきます。
こうする事で、武器でなければ剣を振った時の音をならさないようにします。
持ち物にタグを指定すれば鳴らす音を変更させるという事もできるようになります。
タグを使わずとも
1 2 3 4 5 | if (equipTransform.GetChild(0).name == "Broadsword(Clone)") { audioSource.PlayOneShot(attackSound); } |
上のようにゲームオブジェクトの名前で判断することも出来ます。
Broadsword(Clone)となっているのは武器のプレハブをインスタンス化する時に名前を設定していないので、デフォルトで『プレハブ名(Clone)』という名前になるためです。
インスタンス化したゲームオブジェクトに名前を付ける時は、
1 2 3 4 | var weapon = Instantiate<GameObject>(weapons[equipment]); weapon.name = weapons[equipment].name; |
上のようにインスタンス化したゲームオブジェクトの名前を指定すると(Clone)が付かなくなります。
2Dサウンドと3Dサウンド
今回はMainCameraに耳にあたるAudioListenerコンポーネントが付いている為、効果音を鳴らすAudioSourceコンポーネントの設定ではSpatial Blendの設定を2Dにして必ず聞こえるようにしています。
音が鳴った場所によって音声の聞こえ方を変えたい場合はMainCameraのAudioListenerを削除し、主人公にAudioListenerを取り付けて主人公の位置に応じて音声の強弱が変わるようにします。
その際には敵の攻撃時、主人公の攻撃時のAudioSourceのSpatial Blendを3Dにドラッグします。
これで主人公の位置に応じて効果音の強弱が変わります。
終わりに
これでBGM、敵キャラの声、剣を振る音を付ける事ができました。
やはり音声があるとグッとゲームっぽくなりますね~。
敵が声を発するのは攻撃開始時にしてますが、主人公と同じようにアニメーションイベントの受け取りに反応して音声を鳴らすようにしてもいいですね。
でも攻撃開始時の方が敵が攻撃するぞ!というのがわかって良いのかも?悪いのかも?
次回はキャラクター毎に独自のステータス保持スクリプトを持って管理出来るようにしてみます。