[UNITY]画面遷移ボタンのボタン効果音を鳴らす

どうもえんちゃです。
ボタンの効果音を入れようとしたんですけど
画面遷移時に音が消えちゃうんですよね。なので、いろいろ試した内容を備忘録として書いていきます。
たぶんあるあるだと思うので失敗例も見ていただればと思います。

【失敗例1】音がならない

ボタンタップ時に呼ばれるクラス・メソッド

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

/// 
/// ボタン共通クラス
/// 
public class ButtonManager : MonoBehaviour
{
    public AudioSource audioSource;
    public AudioClip audioClip;

    //ボタンタップで呼ばれるメソッド
    public void TappedButton()
    {
        audioSource.PlayOneShot(audioClip);
        SceneManager.LoadScene("SceneA");
    }
}

ボタンタップで画面遷移をする前にPlayOneShotで音を鳴らそうとしています。

これで実行すると、、、、鳴りません。

原因は、音が鳴ろうとする直後に画面遷移が起こり、AudioSourceやAudioClipオブジェクトが破壊され、音が途切れるためです。

なのでAudioSource等オブジェクトを画面遷移後も保持できるように修正していきます。

【失敗例2】効果音が増殖する

オブジェクトを保持するには

 DontDestroyOnLoad([GameObject]);

を利用します。
まず、SE用のクラスとオブジェクトを用意

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SeManager : MonoBehaviour
{
    // Start is called before the first frame update
    private  AudioSource audioSourceSE;
    public  AudioClip se;

    private void Start()
    {
        audioSourceSE = this.GetComponent();
        DontDestroyOnLoad(this.gameObject);
    }

    public  void SettingPlaySE()
    {
        audioSourceSE.PlayOneShot(se);
    }
}

これをSE用オブジェクトにアタッチしていきます。

最後にボタンメソッドを修正し
SeManagerに先ほどのSE用オブジェクトをアタッチします。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

/// 
/// ボタン共通クラス
/// 
public class ButtonManager : MonoBehaviour
{
    public SeManager seManager;
    //ボタンタップで呼ばれるメソッド
    public void TappedButton()
    {
        seManager.SettingPlaySE();
        SceneManager.LoadScene("SceneA");
    }
}

これを実行します。

今度は、音は鳴るが、SE用オブジェクトが増殖していきます。
これは遷移時にSeManager.Start()がよばれ、新しくSE用オブジェクトが作成、保持される。ということが繰り返されるためです。

あとはこれを解決すればOKです。

【完成】ボタン効果音を鳴らす手順

こちらの記事を参考にしました。
【Unity】シングルトンを上手く活用しよう

新しく作られるときに、すでに存在するか、していないかを判別するように修正します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SeManager : MonoBehaviour
{
    // Start is called before the first frame update
    private AudioSource audioSourceSE;
    public AudioClip se;

    public static SeManager Instance
    {
        get; private set;
    }

    void Awake()
    {
        if (Instance != null)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }

    private void Start()
    {
        audioSourceSE = this.GetComponent();
    }

    public void SettingPlaySE()
    {
        audioSourceSE.PlayOneShot(se);
    }
}

これにより、SeManagerが無い(1回目)時、はDontDestroyOnLoadで自オブジェクトを保持し、
既にあるとき(2回目)には、Destroyし、自オブジェクトを破壊します。

最後にButtonManagerのSeManagerの呼び出し元を毎回既存のものを呼び出すように修正します。
今までのままだと2回目の時、破壊されたオブジェクトを見ているため、
「オブジェクトがないよ!」というエラーが出てしまいます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

/// 
/// ボタン共通クラス
/// 
public class ButtonManager : MonoBehaviour
{
    //ボタンタップで呼ばれるメソッド
    public void TappedButton()
    {
        SeManager seManager = SeManager.Instance;
        seManager.SettingPlaySE();
        SceneManager.LoadScene("SceneA");
    }
}

以上で画面遷移時、音が鳴るようになりました。

コメント

タイトルとURLをコピーしました