这就是我目前为小型RPG设置Sound Manager的方法,我只是想知道这是不是很好的做法。
我想要的是让我的两个方法(PlayBGMusic和PlaySound)成为“公共静态”,所以我不必在几乎所有其他需要的脚本中使用标记和脚本来抓取GameObject发出声音。如果我确实将它们设为“公共静态”,那么我必须使我的变量相同,这样就不会在检查器中放置任何东西。
public class Sound_Manager : MonoBehaviour {
// Allow the user to decide if music should be on or off.
public bool backgroundMusicOn;
// Allow the user to decide if sound should be on or off.
public bool soundOn;
// The music volume.
[Range(0,1)]
public float musicVolume;
// The sound volume.
[Range(0,1)]
public float soundVolume;
// The Background music to be used for any manipulations.
private AudioSource _bgMusic;
// Play a background song.
public void PlayBGMusic(AudioSource music){
...
}
// Mute Current Background Song.
public void MuteUnMuteBGMusic(){
....
}
// Play a sound.
public void PlaySound(AudioClip sfx, Vector3 location){
...
}
}
这是处理这样的事情的正确方法还是有另一种方式可以更简单?
答案 0 :(得分:2)
我认为你不能在一个GameObject中播放BGmusic和声音,因为每个音频都必须播放单个audion源,这是我的AudioManager代码。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class AudioManager : MonoBehaviour
{
public AudioClip[] audioSources;
public GameObject audioPrefabSource;
public Dictionary<string,AudioClip> audioClips;
static GameObject audioPrefab;
static GameObject instance;
static AudioSource musicPlayer;
public static AudioManager audioManager;
Dictionary<string,Audio> aliveSounds;
AudioListener al;
void Awake ()
{
audioManager = this;
al = GetComponent<AudioListener> ();
audioClips = new Dictionary<string, AudioClip> ();
foreach (AudioClip a in audioSources) {
audioClips.Add (a.name, a);
}
instance = this.gameObject;
audioPrefab = audioPrefabSource;
musicPlayer = audio;
aliveSounds = new Dictionary<string, Audio> ();
//DontDestroyOnLoad(gameObject);
}
void Update ()
{
if (!GameSetting.hasMusic) {
musicPlayer.Pause ();
} else {
if (!musicPlayer.isPlaying) {
musicPlayer.Play ();
}
}
if (!GameSetting.hasSound && aliveSounds.Count > 0) {
foreach (Audio a in aliveSounds.Values) {
a.StopSound ();
}
aliveSounds.Clear ();
}
if (!al.enabled) {
al.enabled = true;
}
}
public static void PlaySoundOnce (string name)
{
if (!GameSetting.hasSound) {
return;
}
if (!audioManager.audioClips.ContainsKey (name)) {
return;
}
GameObject go = GameObject.Instantiate (audioPrefab) as GameObject;
go.transform.parent = instance.transform;
Audio a = go.GetComponent<Audio> ();
a.PlaySoundOnce (audioManager.audioClips [name]);
}
public static void PlayMusic (string name)
{
if (!GameSetting.hasMusic) {
return;
}
if (musicPlayer.clip == null || musicPlayer.clip.name != name) {
// musicPlayer.clip = audioManager.audioClips [name];
musicPlayer.clip = Resources.Load ("Audio/" + name, typeof(AudioClip)) as AudioClip;
musicPlayer.Stop ();
musicPlayer.loop = true;
musicPlayer.Play ();
} else {
musicPlayer.loop = true;
musicPlayer.Play ();
}
}
}
还有另一个音频类,它必须用于audioprefab。
using UnityEngine;
using System.Collections;
public class Audio : MonoBehaviour
{
public void PlaySoundOnce (AudioClip audioClip)
{
StartCoroutine (PlaySoundCoroutine (audioClip));
}
IEnumerator PlaySoundCoroutine (AudioClip audioClip)
{
audio.PlayOneShot (audioClip);
yield return new WaitForSeconds (audioClip.length);
Destroy (gameObject);
}
public void PlaySoundLoop (AudioClip audioClip)
{
audio.clip = audioClip;
audio.loop = true;
audio.Play ();
}
public void StopSound ()
{
audio.Stop ();
Destroy (gameObject);
}
}
像这样,我忽略了音频的位置,我使用了2D声音。
答案 1 :(得分:1)
我建议将声音管理器转换为单例类。通过这种方式,您可以在检查器中拥有所有属性,并使用单例对象全局访问所有属性,甚至在不需要时完全销毁游戏对象。