Skip to content

tetr4lab/SoundManager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

title tags
シンプルなサウンドマネージャー (Unity)
Unity C# uGUI

シンプルなサウンドマネージャー (Unity)

前提

  • Unity 2020.3.33f1
  • 使用に際して、C#でスクリプトを書く必要があります。
  • UIの操作音やBGMなど、音源の位置が画面に固定されている場合に適しています。

できること

  • 音源の内容にかかわらず、ループ再生するものをBGM、しないものをSEとして扱います。
    • 例えば、ファンファーレのような一度だけ再生する楽曲はSEとして扱います。
  • SEとBGMの番号を指定して再生できます。
    • SE
      • あらかじめ、インスペクタで、最大同時再生数を指定します。
      • 再生時に、「同じ音でも重ねて鳴らす」、「同じ音が鳴っていたら止めてから鳴らす」、「同じ音が鳴っていない場合だけ鳴らす」ことが選択可能です。
      • 再生はループしません。
    • BGM
      • あらかじめ、インスペクタで、フェードイン、フェードアウト、インターバルの時間を指定します。
        • 最大同時再生数は2で固定です。(クロスフェード用)
      • プレイリストに対応しています。
      • 再生はループします。
  • SEとBGMの音量を独立して設定できます。
  • 全体の一時的なミュートが可能です。

導入と設定

サンプル・プロジェクト

  • プロジェクトをUnityエディタで開くだけです。
  • 設定を変更する際は、次項を参照してください。

任意のプロジェクト

  • プロジェクトにSound.csをインポートしてください。
  • シーンの適当なオブジェクトに、スクリプトSound.csをアタッチしてください。
  • インスペクタで、Sound Effect ClipSound Music ClipのSizeを必要なだけ増やし、オーディオクリップを設定してください。
  • 必要に応じてパラメータを調整してください。

18d361cc-4516-56f0-2839-09e6a6e96ba2

項目 説明 初期値 範囲 動的変更
Sound Effect Max SE同時再生数 int 5 1~ 不可
Sound Effect Initial Volume SE初期音量 float 0.5 0~1.0 不可
Sound Music Initial Volume BGM初期音量 float 0.5 0~1.0 不可
Sound Music Fade In Time BGMフェードイン時間 float 0.0 0~ Sound.MusicFadeInTime
Sound Music Fade Out Time BGMフェードアウト時間 float 0.0 0~ Sound.MusicFadeOutTime
Sound Music Interval Time BGMインターバル時間 float 0.0 ~ Sound.MusicIntervalTime
Sound Effect Clip SEオーディオクリップ AudioClip [] null - SoundE.EffectClip
Sound Music Clip BGMオーディオクリップ AudioClip [] null - Sound.MusicClip

使い方

  • 使用するスクリプトの冒頭で以下を宣言してください。
    • あるいは、以降でSound.~と書かれている部分をSoundManager.Sound.~とすることで、宣言せずとも使用可能です。
Using SoundManager;

SEを再生する

同じSEでも重ねて鳴らす

Sound.Effect = number;
  • 空きのチャネル(AudioSource)で再生します。
  • 空きがない場合は、最も古くに再生開始されたチャネルの再生を止めて使います。

同じSEが鳴っていたら止めてから鳴らす

Sound.StopAndEffect = number;
  • 以下と同じ処理です。
Sound.EffectStop = number;
Sound.Effect = number;

同じSEが鳴っていない場合だけ鳴らす

Sound.EffectIfNot = number;
  • 既に同じ音を再生中であれば、新たに再生しません。

最後に再生中の効果音番号を得る

int number = Sound.Effect;
  • 何も再生されていない場合は、Sound.Silentが得られます。

再生中の効果音番号一覧を得る

int [] numbers = Sound.Effects;
  • 何も再生されていない場合は、空の配列が得られます。

効果音が再生中か検査する

if (Sound.IsPlayingEffect) {

指定したSEを止める

Sound.EffectStop = number;
  • 複数チャネルで再生している場合は、最も古い再生チャネルだけが止まります。

全てのSEを止める

Sound.Effect = Sound.Silent;
// or
Sound.EffectStop = Sound.Silent;

SE音量を設定する

Sound.EffectVolume = volume;
  • 正規化された値(0~1f)を設定します。取得もできます。
  • 音量を0にしても再生は停止しません。

登録されているSE数を得る

int count = Sound.EffectCount;

BGMを再生する

Sound.Music = number;
  • インスペクタで設定されたフェードイン、フェードアウト、インターバルの時間(秒)を勘案して曲を再生します。
    • 既に再生中の曲の場合は、単に再生を継続します。
    • 別の曲を再生中の場合は、まず、再生中の曲がフェードアウトします。
      • フェードアウト時間が0なら即座に止まります。
      • 負値は指定できません。
    • 次に、インターバル時間だけ、次の再生開始を待機します。
      • 負値の場合は、フェードアウト中に遡って待機を終えます。
      • フェードアウトに先だって待機を終える(フェードアウトの開始を越える負値を指定する)ことはできません。
    • 待機を終えると、指定された曲のフェードインを開始します。
      • フェードイン時間が0なら即座に既定音量で再生されます。
      • 負値は指定できません。
    • 再生中でない場合は、即座にフェードインが開始されます。
    • クロスフェード中に新たな再生指示があった場合は、以下の特例処理を行います。
      • 前の(フェードアウト中の)曲が再生指示された場合は、2曲のフェード方向が切り替わります。
      • フェードアウト・イン中のどちらとも異なる第3の曲が再生指示された場合は、再生中だった2曲の内で音量の大きい方をフェードアウトさせ、音量の小さい方は即座に停止して次の曲の開始シーケンスに移行します。
    • 曲はループ再生されます。ループの際にはフェードやインターバルは適用されません。
    • 全ての時間が0なら、即座に切り替わります。
    • 全ての時間が1なら、前の曲が1秒でフェードアウト、1秒無音で、次の曲が開始され1秒でフェードインします。
    • フェードインとフェードアウトが3でインターバルが-1だと、前の曲が3秒でフェードアウトし、その終了1秒前に次の曲が再生を開始して3秒でフェードインします。フェードアウト開始からフェードイン終了までは5秒になります。

再生中の曲番号を得る

int number = Sound.Music;
  • 再生されていない場合は、Sound.Silentが得られます。
  • プレイリストの再生中であっても、単に曲番号が得られます。

再生中の曲番号一覧を得る

int [] numbers = Sound.Musics;
  • 再生待機中も再生中と見なされます。
  • クロスフェード中であれば要素2個、通常の再生中であれば要素1個、何も再生されていない場合は空の配列が得られます。

BGMが再生中か検査する

if (Sound.IsPlayingMusic) {
  • 再生待機中も再生中と見なされます。

BGM音量を設定する

Sound.MusicVolume = 0.5f;
  • 正規化された値(0~1f)を設定します。取得もできます。
  • 音量を0にすると再生が停止します。

BGM音量を一時的に変更する

MusicTmpVolume = 0.5f;
  • 無音を最小(0)、MusicVolumeを最大(1f)として、正規化された値を設定します。取得もできます。
    • 初期値は1fです。
    • MusicVolumeとは独立した設定で、MusicVolumeの設定値は影響を受けません。
  • 音量を0にしても再生は停止しません。
  • 一時的にBGMの音量を下げてSEを聴かせ、その後、元の音量に戻すような場合に使用します。

登録されているBGM数を得る

int count = Sound.MusicCount;

BGM再生を止める

Sound.Music = Sound.Silent;
  • フェードアウト時間の設定が0でない場合は、フェードアウトします。
  • フェードアウト時間が0の場合は即座に止まります。

BGM再生を即座に止める

Sound.Music = Sound.ShutUp;
  • フェードアウトの設定に関わらず即座に止まります。

BGMプレイリストを再生する

  • プレイリストはBGMの再生の一部で、BGMの音量の設定や再生の停止などによって制御されます。
  • プレイリスト再生中に単曲の再生を開始した場合、プレイリストの再生はキャンセルされます。
    • その際、単曲で再生開始した曲がプレイリストで再生中の曲だった場合は、そのまま再生が継続し単曲でループします。

プレイリストを再生する

Sound.Playlist = new int [] { number, number1, number2, number3, };
  • 順に再生し全体を繰り返します。
    • 設定に従って曲間にフェードとインターバルが適用されます。
  • 単一曲の再生中に同一の曲を含むプレイリストを再生した場合は、リストの途中からの開始として曲の再生が継続されます。
全曲プレイリストを再生する
Sound.Playlist = Sound.AllMusicPlaylist;

再生中のプレイリストを得る

int [] playlist = Sound.Playlist;
  • プレイリストが再生されていない場合は、nullが得られます。
  • 再生中の曲番号を得る場合は、Sound.Musicを参照します。
    • 再生中のインデックスを得ることはできません。

プレイリストの曲を送る

Sound.MusicPlayNext ();

プレイリストの曲を戻す

Sound.MusicPlayNext (-1);

プレイリストの再生を停止する

Sound.Music = Sound.Silent;
Sound.Music = Sound.ShutUp;
  • BGM再生を停止することで、プレイリストの再生が停止します。
Sound.Music = number;
  • BGMを単曲再生することでも、プレイリストの再生が停止します。

再生中のプレイリストのインデックスを得る

int index = Sound.MusicPlayNext (0);

一時的に全ての音を消す、戻す

Sound.Mute = true; // 一時的に音を消す
Sound.Mute = false; // 音を戻す
  • 音が出ないだけで、既存の再生は継続しますし、新たな再生も有効です。

コンポーネントの挙動と制御

  • シングルトン風(厳密には異なります)に動作し、シーンにインスタンスが複数存在する場合でも、常に一つだけが稼働します。
  • インスタンスが生成されAwakeが呼ばれると初期化が試みられます。
    • 最初のインスタンスが初期化されると、他のインスタンスの初期化は抑制されます。
    • 未初期化のインスタンスは何も処理しません。
  • 稼働していたインスタンスが破棄されると、次に登録されていた一つが初期化されて稼働を始めます。
    • 破棄時には全ての再生が停止します。
  • インスペクタや動的生成で設定可能なパラメータの一部は、動的に再設定可能です。
    • オーディオクリップを再設定すると再生が停止します。

動的な生成

  • 指定したオブジェクトに、コンポーネントを動的にアタッチすることが可能です。
  • 指定されたオブジェクトの既存のSoundコンポーネントは、新しいインスタンスの生成直後に全て削除されます。
  • サンプルでは、あらかじめシーンにコンポーネントをアタッチしてありますが、Resetボタンを押すとコンポーネントが再生成されます。
引数に応じて生成する
  • コンポーネントをアタッチするゲームオブジェクトを指定し、生成されたインスタンスを得ます。
Sound sound = Sound.Attach (gameObject, effectMax, effectInitialVolume, musicInitialVolume, musicFadeInTime, musicFadeOutTime, musicIntervalTime, effectClip, musicClip);
  • デフォルトの設定で生成する場合は、ゲームオブジェクト以外の引数を省略可能です。
Sound sound = Sound.Attach (gameObject);
複製して生成する
  • コンポーネントをアタッチするゲームオブジェクトを指定し、生成されたインスタンスを得ます。
  • あくまでも設定内容の複製であり、インスタンス間での再生状況の引き継ぎが行われるわけではありません。
Sound sound = Sound.Attach (gameObject, origin);

謝辞

以下の素材を使わせていただきました。 どうもありがとうございました。