创建声音管理器

时间:2015-08-11 22:25:36

标签: c# unity3d

这就是我目前为小型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){
...
}
}

这是处理这样的事情的正确方法还是有另一种方式可以更简单?

2 个答案:

答案 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声音。

enter image description here

答案 1 :(得分:1)

我建议将声音管理器转换为单例类。通过这种方式,您可以在检查器中拥有所有属性,并使用单例对象全局访问所有属性,甚至在不需要时完全销毁游戏对象。