MRが楽しい

MRやVRについて学習したことを書き残す

MRTKでボタン押下時にボタンを無効化した場合もSingletonパターンを使って音を鳴らす

本日は MRTK の小ネタ枠です。
MRTKでボタン押下時にボタンを無効化した場合もSingletonパターンを使って音を鳴らす方法を試したので記事に残します。

MRTKでボタン押下時にボタンを無効化する場合

MRTK のボタンでボタン押下時にボタンを無効化するようなイベントを発生させた場合、AudioSource もボタンオブジェクトに含まれているため、音が鳴りません。

今回は Singleton パターンを使ってシーンで共有するAudioSourceを参照することでボタンを無効化する場合も音が鳴るようにしました。

サンプルスクリプト

以下の AudioSource にアクセスするための Singleton パターンのクラスとボタン側からのアクセス用のサンプルスクリプトを作成しました。
・SingletonBase.cs

using UnityEngine;
/// <summary>
/// Awakeで設定されるSingletonのベースクラス
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonBase<T> : MonoBehaviour where T : SingletonBase<T> 
{
    private static T p_Instance;

    public static T Instance
    {
        get
        {
            if (p_Instance == null)
            {
                T[] objects = FindObjectsOfType<T>();
                if (objects.Length == 1)
                {
                    p_Instance = objects[0];
                }
                else if (objects.Length > 1)
                {
                    Debug.LogError($"Expected exactly 1 {typeof(T).ToString()} but found {objects.Length}");
                }
            }
            return p_Instance;
        }
    }

    protected virtual void OnDestroy()
    {
        p_Instance = null;
    }
}

・SceneAudioSourceSingleton.cs

using UnityEngine;
/// <summary>
/// AudioSourceにアクセスするためのSingletonクラス
/// </summary>
public class SceneAudioSourceSingleton : SingletonBase<SceneAudioSourceSingleton>
{
    [SerializeField]
    private AudioSource p_AudioSource;

    /// <summary>
    /// オーディオクリップの再生
    /// </summary>
    /// <param name="a_AudioClip"></param>
    public void PlayOneShot(AudioClip a_AudioClip)
    {
        p_AudioSource.PlayOneShot(a_AudioClip);
    }
}

・SceneAudioSourceAccess.cs

using UnityEngine;
/// <summary>
/// ボタン側のアクセス用クラス
/// </summary>
public class SceneAudioSourceAccess : MonoBehaviour
{
    /// <summary>
    /// オーディオクリップの再生
    /// </summary>
    public void PlayOneShot(AudioClip a_AudioClip)
    {
        // シーン内のSingletonクラスにアクセスしてクリップを再生する
        SceneAudioSourceSingleton.Instance.PlayOneShot(a_AudioClip);
    }
}

シーン内に適当なゲームオブジェクトを作成し、AudioSource とそれを参照する Singleton クラスを設定します。

ボタン側は新たにプレハブを作成し、AudioSource の再生イベントでアクセス用クラスを介して Singleton クラスにアクセスするようにしました。

・変更前の再生イベント

・変更後の再生イベント

動作確認

シーンを再生して動作を確認します。

ボタンを押下してボタンが無効化されてもボタン外の AudioSource を利用するため、押下時のオーディオが再生されました。