シーンが重くなってくると、オーディオソースで再生するBGMや効果音が途切れたり、時間がたってから急に再開したりと不具合が増えました。
原因は、同じオブジェクトに複数のオーディオソースをつけていることのようです。オーディオソースを一つずつ付けるようにすると解消しました。
オーディオソースを一つ付けるだけのゲームオブジェクトをいくつか用意することになりましたが、状況によって必要なオーディオソースの数は変わります。
そこで、スクリプトでプレイ中にオーディオソースを簡単に増やせるようにしました。それには、新規の空のゲームオブジェクトにオーディオソースを追加するだけです。
作ったオーディオソースをリストに追加しておいて、インデックスを指定して再生や停止、オーディオソースオブジェクトの削除などをできるようにすると便利です。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioSourceTest : MonoBehaviour
{
static AudioSourceTest instance;
public static AudioSourceTest GetInstance()
{
return instance;
}
private void Awake()
{
if (instance != null) Destroy(gameObject);
else instance = this;
}
// オーディオクリップの配列
[SerializeField] AudioClip[] audioClips;
// オーディオソースのリスト
List<AudioSource> audioSources = new List<AudioSource>();
// オーディオソースを追加
public AudioSource AddAudioSource()
{
// 新しいゲームオブジェクト
GameObject obj = new GameObject();
// オーディオソースを追加
AudioSource a = obj.AddComponent<AudioSource>();
// オーディオソースの設定
a.playOnAwake = false;
a.loop = false;
a.volume = 1f;
// リストに追加
audioSources.Add(a);
return a;
}
public void AddAudioSource(AudioSource a)
{
audioSources.Add(a);
}
// 再生
public void PlayAudio(int audioSourceIndex, int clipIndex, float volumeScale = 1f)
{
// インデックスが範囲内のとき
if (audioSources.Count > audioSourceIndex && audioClips.Length > clipIndex)
{
// オーディオソースとクリップを指定して再生
audioSources[audioSourceIndex].PlayOneShot(audioClips[clipIndex], volumeScale);
}
}
// 停止
public void StopAudio()
{
foreach(var a in audioSources)
{
a.Stop();
}
}
// オーディオソースを削除
public void DeleteAudioSource(int index)
{
// インデックスが範囲内のとき
if (audioSources.Count > index)
{
// オーディオソースオブジェクトを削除
Destroy(audioSources[index].gameObject);
// リストから削除
audioSources.RemoveAt(index);
}
}
// Start is called before the first frame update
void Start()
{
}
}
さらに、オーディオクリップもこのスクリプトにまとめておきました。
これで上の動画のように簡単にオーディオソースを増やせました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestScript2 : MonoBehaviour
{
int n;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
// 左クリック
if(Input.GetMouseButtonDown(0))
{
// オーディオソースを追加
AudioSourceTest.GetInstance().AddAudioSource();
// ランダムで再生
AudioSourceTest.GetInstance().PlayAudio(n, Random.Range(0,4));
n++;
}
// 右クリック
else if(Input.GetMouseButtonDown(1))
{
// オーディオソースを削除
AudioSourceTest.GetInstance().DeleteAudioSource(3);
n--;
}
}
}