実現したいこと
マインスイーパーにて
- タイルを開けたとき
- フラグを立てたとき
- 爆弾を開けたとき
でそれぞれ別のSEを流したい。
前提
Unity初心者です。アセットストアの Minesweeper - Game Template を元にどのようなことが出来るかを試しています。Unity 2021.3.15f1 を使用し、下記の順で作業・確認しました。
①新たなprefabsであるSound Managerを作成し、AudioSourceやAudioClipを設定後それ単体では音が出ることを確認しました。
②GameManagerにSound Managerを設定し、例えば下記を追加して画面上を左クリックしたとき音がでることを確認しました。
[SerializeField] SoundManager soundManager; public void PlayRevealBombSound() { soundManager.PlayRevealBombSound(); } void Update() { if (Input.GetMouseButtonDown(0)) //左クリック { PlayRevealBombSound(); } }
③タイルの状態で鳴らすSEを分岐させるため、TileInputHandler に GameManager を設定するようにし、タイルの状態によって鳴らす音を変えることを試みるとエラーになり音がでません。
[SerializeField] GameManager gameManager; //Normal click 左クリックが0.5秒以内ならタイルを開く if (elapsed < 0.5f) { // Play reveal tile sound or reveal bomb sound if (tile.CompareTag(Bomb.Tag)) { gameManager.PlayRevealBombSound(); } else { gameManager.PlayRevealTileSound(); } MessageSystem.Send<ITileClickListener>(listener => { listener.OnTileClick(tile); }); }
追加した class SoundManager のコード
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class SoundManager : MonoBehaviour { [SerializeField] private AudioSource source; [SerializeField] private AudioClip revealTileSound; //音源データ1 [SerializeField] private AudioClip flagTileSound; //音源データ2 [SerializeField] private AudioClip revealBombSound; //音源データ3 [SerializeField] [Range(0f, 1f)] private float soundVolume = 0.5f; public void PlayRevealTileSound() { source.PlayOneShot(revealTileSound, soundVolume); } public void PlayFlagTileSound() { source.PlayOneShot(flagTileSound, soundVolume); } public void PlayRevealBombSound() { source.PlayOneShot(revealBombSound, soundVolume); } }
発生しているエラーメッセージ
Can not play a disabled audio source UnityEngine.AudioSource:PlayOneShot (UnityEngine.AudioClip,single) SoundManager:PlayRevealBombSound () (at Assets/Ilumisoft/Minesweeper/Scripts/SoundManager.cs:36) Ilumisoft.Minesweeper.GameManager:PlayRevealBombSound () (at Assets/Ilumisoft/Minesweeper/Scripts/GameManager.cs:201) Ilumisoft.Minesweeper.TileInputHandler:OnPointerUp (UnityEngine.EventSystems.PointerEventData) (at Assets/Ilumisoft/Minesweeper/Scripts/Tile/TileInputHandler.cs:81) UnityEngine.EventSystems.EventSystem:Update ()
試したこと
出力されたエラーで検索し、原因となりそうな下記を試しました。
-
明示的にAwake()メソッド内で audioSource.enabled = true; としてみる。
-
SoundManagerクラス内で、AudioSourceが有効であるかどうかを確認する条件分岐を追加する。
[SerializeField] private AudioSource source; public void PlayRevealTileSound() { if (source.enabled) { source.PlayOneShot(revealTileSound, soundVolume); } else { Debug.LogError("AudioSource is disabled in SoundManager."); } }
-
Sound Managerを使用せず、GameManagerにAudioSource, Clipを設定した場合。違うエラーメッセージ(※)が出力されました。下記条件分岐を用いてPlayOneShotの引数がnullでないことを確認しても、同じエラー(※)です。
if (revealTileClip != null) { audioSource.PlayOneShot(revealTileClip, soundVolume); }
※GameManagerで効果音を鳴らす処理としたときのエラーメッセージ
ArgumentNullException: Value cannot be null. Parameter name: source UnityEngine.AudioSource.PlayOneShot (UnityEngine.AudioClip clip, System.Single volumeScale) (at <bdec5cc4d87f4049ad39114441fe4d1e>:0) Ilumisoft.Minesweeper.GameManager.PlayRevealBombSound () (at Assets/Ilumisoft/Minesweeper/Scripts/GameManager.cs:221)
自分の考察
上記の試したことから、audio sourceが有効である場合にPlayOneShotを実行するよう条件分岐したにも関わらず、a disabled audio source と出力されていることがわかりました。
そのため、私のしらない制約か仕様があると考えています。
例えば、Tile はゲーム開始後に生成された prefab のためそこで参照するようにした Game Manager は現在実行されているものと異なるものとなりそれが悪さをしているなどです。
情報が不足している、そもそも実装の方針から間違えているなどありましたら、教えていただければ有難いです。
お願いいたします。
補足情報(FW/ツールのバージョンなど)
Unity 2021.3.15f1
2023/5/8 追記
原因はわかっていませんが、下記のようにして実現したいことは達成しました。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class SoundManager : MonoBehaviour { //--シングルトン始まり-- public static SoundManager instance; private void Awake() { if (instance == null) { instance = this; DontDestroyOnLoad(this.gameObject); } else { Destroy(this.gameObject); } } //--シングルトン終わり-- [SerializeField] private AudioSource source; [SerializeField] private AudioClip revealTileSound; //音源データ1 [SerializeField] private AudioClip flagTileSound; //音源データ2 [SerializeField] private AudioClip revealBombSound; //音源データ3 [SerializeField] [Range(0f, 1f)] private float soundVolume = 0.3f; public void PlayRevealTileSound() { source.PlayOneShot(revealTileSound, soundVolume); } public void PlayFlagTileSound() { source.PlayOneShot(flagTileSound, soundVolume); } public void PlayRevealBombSound() { source.PlayOneShot(revealBombSound, soundVolume); } }

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/05/08 04:06
2023/05/10 10:05 編集