MYMYゲーム制作室

アラ古希姉妹のゲーム制作日記

unity 2つのBGMを切り替えたい!

メインシーンで敵を全部やっつけたらゲームクリアとなる。

そこでシーンの景色も明るくなる設定にしてあり、音楽もそれと同時に明るい音楽に切り替えたいというのが、わたしたしの目論見。ゲームクリアの別のシーンを作ることもできたが、きつくんの森は、最後に森が毎回違う風に変化するところも肝となるところなので、シーンを遷移することなく、どうしても同じシーンの中でBGMを切り替えたい。

それで、試してみたのが、

  1. ヒエラルキーの中に空のオブジェクトを作り、BGMとする。
  2. 1にAddComponentでAudioSours(仮にa1と考える)を追加する。
  3. 1にAddComponentでもう一つAudioSours(仮にa2と考える)を追加する。
  4. スクリプトを新しく作り、BGMControllerと名前を付け、1のオブジェクトに貼り付ける。

この状態でBGMをスクリプトから切り替えたいわけ。

 

これでやって最初はうまく再生できた気がしたので、ビルドしてみたところ、a1のBGMは最初から鳴り続けて、ゲームクリアの瞬間にピタッと停止でOK。しかし、2個目のBGM(a2)が、ガーガーとひどい雑音がきこえるだけで音楽は聞こえない(; ・`д・´)

 

そこでスクリプトを書き替えて試すが、どうやっても2番目の音楽に切り替わってくれない。

 

どういうスクリプトを書いたのか、備忘録として残しておく。

 

スクリプトその1

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

public class BGMController2 : MonoBehaviour
{

    
    [SerializeField] private AudioSource a1;//AudioSource型の変数aを宣言
    [SerializeField] private AudioClip b1;//AudioClip型の変数bを宣言

    [SerializeField] private AudioSource a2;//AudioSource型の変数aを宣言
    [SerializeField] private AudioClip b2;//AudioClip型の変数bを宣言


    private GameObject enemyBox;

    // public AudioSource audioSource;// [SerializeField] でコントロールするのでこれは不要と思う。


    void Start()
    {
        a1.PlayOneShot(b1);
    }


    void Update()
    {
        enemyBox = GameObject.FindGameObjectsWithTag("Enemy");

        //Debug.Log("敵の数は" + enemyBox.Length);

        if (enemyBox.Length == 0)
        {
            a1.Stop();//ビルドしたとき、ゲームクリアの瞬間にa1は正しく停止した。
            a2.PlayOneShot(b2); //このスクリプトでビルドしたら、a2は雑音になってしまった。なぜ?

 

        }
    }
}

 

スクリプトその2

using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;

public class BGMController : MonoBehaviour
{

    
    [SerializeField] private AudioSource a1;//AudioSource型の変数a1を宣言
  
    [SerializeField] private AudioSource a2;//AudioSource型の変数a2を宣言
   
    //それぞれのAudioSoursの中のAudioClipはインスペクター内でアサインしてある。
   
    private GameObject enemyBox;

  


    void Start()
    {
        a1.Play();//1個目のBGM(a1)を再生する。
    }


    void Update()
    {
       
        enemyBox = GameObject.FindGameObjectsWithTag("Enemy");

        //Debug.Log("敵の数は" + enemyBox.Length);

        if (enemyBox.Length == 0)//BGMを切り替える条件。敵が全滅してゲームクリアしたとき。

        {
           //AudioSource型の変数aを再生 。audioClipはインスペクターの中にアサインしてあるので()の中は空欄。
            a1.Stop();//1個目のBGMは停止。再生するとa1のBGMは正しく停止した。
            a2.Play();//2個目のBGMを再生開始。これで再生すると、a2のBGMは鳴らなかった。なぜ?

        }
    }
}

 

スクリプトその3

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

public class BGMController1 : MonoBehaviour
{

    private GameObject enemyBox;
    AudioSource
sounds;
    //audioClipはそれぞれのインスペクター内のAudioSoursにアサインしておいた。

    // Use this for initialization
    void Start()
    {
        sounds = GetComponents<AudioSource>();
        sounds[0].Play();
    }

   


    void Update()
    {

        enemyBox = GameObject.FindGameObjectsWithTag("Enemy");

        //Debug.Log("敵の数は" + enemyBox.Length);

        if (enemyBox.Length == 0)//BGMを切り替えるための条件。ゲームクリアしたときに。
        {
            sounds[0].Stop();//再生したときゲームクリアの瞬間に正しく停止した。
            sounds[1].Play();//再生したときゲームクリアの瞬間に鳴らない。なぜ?

        }
    }
}

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

Play()、 PlayOneShot()、配列、[SerializeField]などいろいろ試したが、どれもうまくいかない。万事休す!

 

そこで苦肉の策を試してみる。BGMに2つのAudioSoursを持たせるのを諦める。

その代わりに、ゲームクリアの瞬間にSetActive==trueになるUIテキスト「GmaeClear」にAudioSoursコンポーネントを追加。これに2番目のBGMのaudioClipを貼り付ける。

こうしておけば、このテキストが表示されるまでは、2番目のBGMは鳴ることなく、テキストが表示されると同時に、PlayOnAwakeでなり始めるはず。

果たして、、、これは成功!ビルドしてみた後もちゃんと雑音ではなく音楽がクリアに聞こえるようになった。

そのスクリプトはこちら。👇これにはAudioのことは書いていないが、テキストにつけたAudioSoursにAudioClipがつけてあり、PlaytOnAwakeにチェックを入れてある。

UIテキストにつけたスクリプト

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

public class GameClearController : MonoBehaviour
{

    [SerializeField] GameObject gameClearText;

    private GameObject[] enemyBox;
    private void Start()
    {
        gameClearText.SetActive(false);
    }


    // Update is called once per frame
    void Update()
    {
        enemyBox = GameObject.FindGameObjectsWithTag("Enemy");

        Debug.Log("敵の数は" + enemyBox.Length);

        if (enemyBox.Length == 0)
        {
           

            //GameClearのテキストが表示される
            gameClearText.SetActive(true);
        }
    }
}

 

結果として2つのBGMを切り替えることができたわけだが、なぜBGMオブジェクトに着けたBGMをスクリプトで切り替えることがうまくできなかったのかは、謎として残った。原因は引き続き追究したい。

(こん)