サウンド再生と可読と保守について

今回はサウンドの再生について見てみたいと思います。

現状

結構雑なつくりしてました。

シーン制御の箇所に

Unity上のインスペクターからBGMをつける
public AudioClip OverBGM;


クリップをつけて再生
GameObject.Find("BGM").GetComponent<AudioSource>().clip = OverBGM;
GameObject.Find("BGM").GetComponent<AudioSource>().Play();

雑ですね…

問題点として。

  • GameObject.Findでわざわざ検索してるのでBGM変えるたびに全部ジェクトの検索が入るため、あまりよろしくない                                   (メモリの無駄なので検索してるという解釈もあるが、そもそもこんなところで改善するなら他の無駄を探した方がいい)
  • GameObject.Find自体が非表示のオブジェクトを検索してくれないのでヒットしないことがある
  • 検索がヒットしない場合アプリが停止する
  • BGM増えたら変数追加して2行書く必要がある
  • 「BGM」という名前がソースコードでじかに書いてあるので保守性が最悪         (実際苦労を今しました)
  • シーン制御に書くべきものではないと思われる

等々わずか3行ですが問題点はキリがないです。

改善方法

まずはシーン制御のスクリプトからBGM制御を切り離して「サウンド再生に特化したマネージャ」スクリプトを作成します。

↓サウンド再生に特化したマネージャ

public class SoundPlayer : MonoBehaviour
{
	/// <summary>サウンドタイプ</summary>
	public enum Type
	{
		None,
		Victory,    // 勝利
		Defeat,     // 敗北
		BossBattle, // ボスバトル
		Normal,     // 道中
	}

	/// <summary>サウンドタイプごとのオーディオデータ</summary>
	[System.Serializable]
	private class AudioType
	{
		[SerializeField]
		private Type      m_type = Type.None;

		[SerializeField]
		private AudioClip m_clip = null;

		public Type Type      { get { return m_type; } }

		public AudioClip Clip { get { return m_clip; } }

	}

	// ----------------------------------------------
	// 設定項目

	// サウンドタイプごとのオーディオデータの設定を行う
	[SerializeField]
	private AudioType[] m_audioTypes = null;

	// サウンド再生用
	[SerializeField]
	private AudioSource m_source = null;

	/// <summary>
	/// サウンド再生
	/// </summary>
	/// <param name="type">サウンドタイプ</param>
	public void PlaySound(Type type)
	{
		var sound = m_audioTypes.FirstOrDefault((a) => a.Type == type);
		if(sound != null)
		{
			m_source.clip = sound.Clip;
			m_source.Play();
		}
	}
}

↓シーン制御に新しく追加する

[SerializeField]
private SoundPlayer m_soundPlayer = null;

と、インスペクターでセットできるように追加しておく

こうすることで

  • わざわざGameObject.Findを実行して検索せずに済む
  • 新しく「Type」を追加し新しくオーディオを設定することで追加と変更が非常に容易
  • 再生側も「PlaySound」を呼ぶだけで完結

余談ですがクラスこれをつけることでデータセットしたい項目を構造体にしてUnity上で設定することができます。

※ただし、やりすぎるとか可読性が低下する場合があるのでMonoBehaviorを継承して作るかは今後どういう風にするかを考え見極める必要があります。

[System.Serializable]

まとめ

今見たら、思いのほか非常に雑なつくりで驚きました。

ただし、作り直したソースコードも問題点を上げるとしたら「Type」を追加する必要がある点です。

なるべくアプリのバージョン上げたくない昨今では若干問題ですが、

今回は可読性を上げるために今回はこうしました。

現在の一人の作業ですが未来の自分やGitでの複数人作業で他人に迷惑をかけないよう

可読性はプログラムを書く上で重要項目の一つなので気をつけていきたいです。


コメントを残す

メールアドレスが公開されることはありません。

ABOUT US
vuniformity誰でもない人
トレンドの行く末を見守っている
仮名を名乗るエンジニア

ゲーム開発は仕事であり趣味である
プログラムだけでなく多種多様なスキルを数多く持つ

ゲーム開発は
ソーシャルゲームを開発運用の経験アリ
ゲーム以外にも経験アリ
Webサービス保守開発等に携わる

ゲームプレイの主な戦場は
FGO
FEH
MTGA
マビノギ
ここでは主にunityroomで公開しているゲーム作り直しの軌跡を綴っていきます