Unity 声音管理

  1. 自己去下一个Dotween 的插件。
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
using System;
using DG.Tweening;
public class SoundMaster : MonoBehaviour
{
    public const string                     POOL_KEY = "SoundMasterTemplate";
    private static SoundMaster              instance;

    public static SoundMaster               Ins { get { return instance; } }

    public SoundData[]                      sounds;
    public ObjectSoundData[]                objects;


    private void Awake()
    {
        if (instance != null && instance != this)
        {
            Destroy(this);
            return;
        }
        instance = this;
    }

    private void OnDestroy()
    {
        if (instance == this)
            instance = null;
    }

    //没用
    private void Start()
    {
        var numSoundNameDuplicates = sounds.Select(_ => _.key).Concat(objects.Select(_ => _.key)).GroupBy(_ => _).Where(_ => _.Count() > 1);
        if (numSoundNameDuplicates.Count() > 0)
        {
            var keys = numSoundNameDuplicates.Select(_ => _.Key).ToArray();
            throw new System.InvalidOperationException("duplicated key exists, make sure the keys are unique. duplicated key(s): " + string.Join(", ", keys));
        }
    }


    public void PlaySoundTo(string key, AudioSource aud, float delay = -1, bool recursive = false)
    {
        SoundData sd = null;
        foreach (var s in sounds)
        {
            if (s.key == key)
            {
                sd = s;
                break;
            }
        }

        if (sd == null)
        {
            Debug.Log("audio with key: " + key + " not found.");
            return;
        }

        var d = delay != -1 ? delay : sd.delay;

        if (sd.mode == AudioPlayMode.InstanceIgnore)
        {
            if (aud.clip != sd.audio)
            {
                aud.Stop();
                aud.clip = sd.audio;
                PlayAudio(aud, d, recursive);
            }
            else if (!aud.isPlaying)
            {
                PlayAudio(aud, d, recursive);
            }
        }
        else
        {
            if (aud.isPlaying)
                aud.Stop();
            aud.clip = sd.audio;
            PlayAudio(aud, d, recursive);
        }
    }



    public void PlaySound(string key, float delay = -1, bool recursive = false)
    {

        SoundData sd = null;
        foreach (var s in sounds)
        {
            if (s.key == key)
            {
                sd = s;
                break;
            }
        }

        if (sd == null)
        {
            Debug.Log("audio key not found: " + key);
            return;
        }

        var d = delay != -1 ? delay : sd.delay;

        var playNewSound = false;

        if (sd.mode != AudioPlayMode.Multiple)
        {
            var playingObj = GetPlayingSoundObject(sd.key);
            if (playingObj != null)
            {
                if (sd.mode == AudioPlayMode.InstanceRestart)
                {
                    var aud = playingObj.GetComponent<AudioSource>();
                    aud.Stop();
                    PlayAudio(aud, d, recursive);
                }
            }
            else
            {
                playNewSound = true;
            }
        }
        else
        {
            playNewSound = true;
        }

        if (playNewSound)
        {
            var obj = new GameObject();
            //var obj = KORPool.Ins.Get(POOL_KEY);
            //obj.SetActive(true);
            obj.name = sd.key;
            obj.transform.SetParent(transform);
            var ac = obj.AddComponent<AudioControl>();
            var aud = obj.AddComponent<AudioSource>();
            aud.loop = false;
            aud.playOnAwake = false;
            aud.clip = sd.audio;
            PlayAudio(aud, d, recursive);
        }
    }
    /// <summary>
    /// 加快后的声音
    /// </summary>
    /// <param name="key"></param>
    /// <param name="delay"></param>
    /// <param name="pich"></param>
    public void PlayPichSound(string key,float pich)
    {
        SoundData sd = null;
        foreach (var s in sounds)
        {
            if (s.key == key)
            {
                sd = s;
                break;
            }
        }

        if (sd == null)
        {
            Debug.Log("audio with key: " + key + " not found.");
            return;
        }

        //var d = delay != -1 ? delay : sd.delay;

        var playNewSound = false;

        if (sd.mode != AudioPlayMode.Multiple)
        {
            var playingObj = GetPlayingSoundObject(sd.key);
            if (playingObj != null)
            {
                if (sd.mode == AudioPlayMode.InstanceRestart)
                {
                    var aud = playingObj.GetComponent<AudioSource>();
                    aud.Stop();
                    aud.pitch = pich;
                    PlayAudio(aud, sd.delay);
                }
            }
            else
            {
                playNewSound = true;
            }
        }
        else
        {
            playNewSound = true;
        }

        if (playNewSound)
        {
            var obj = new GameObject();
            //var obj = KORPool.Ins.Get(POOL_KEY);
            //obj.SetActive(true);
            obj.name = sd.key;
            obj.transform.SetParent(transform);
            var ac = obj.AddComponent<AudioControl>();
            var aud = obj.AddComponent<AudioSource>();
            aud.loop = false;
            aud.playOnAwake = false;
            aud.clip = sd.audio;
            aud.pitch = pich;
            PlayAudio(aud, sd.delay);
        }
    }

    public float PlayObjectSound(string key, float delay = -1, float volume = 1)
    {
        ObjectSoundData sd = null;
        foreach (var s in objects)
        {
            if (s.key == key)
            {
                sd = s;
                break;
            }
        }

        if (sd == null)
        {
            Debug.Log("audio with key: " + key + " not found.");
            return 0;
        }

        var d = delay != -1 ? delay : sd.delay;

        var aud = sd.target;

        if(sd.mode == AudioPlayMode.InstanceIgnore)
        {
            if (!aud.isPlaying)
                PlayAudio(aud, d, volume:volume);
        }
        else
        {
            aud.Stop();
            PlayAudio(aud, d, volume: volume);
        }

        return aud.clip.length;
    }
    /// <summary>
    /// 停止语音
    /// </summary>
    /// <param name="key"></param>
    public void StopObjectSound(string key)
    {
        foreach (var o in objects)
        {
            if (o.key == key)
            {
                o.target.GetComponent<AudioSource>().Stop();
                break;
            }
        }
    }
    public void StopSound(string key, bool stopAllWithSameKey = true)
    {
        var len = transform.childCount;
        while (len-- > 0)
        {
            var child = transform.GetChild(len);
            if (child.name == key)
            {
                child.SetParent(null);
                Destroy(child.gameObject);
                if (stopAllWithSameKey)
                    len = transform.childCount;
                else
                    break;
            }
        }
    }

    public void StopAllObjSound()
    {
        foreach (var sound in objects)
        {
            if (sound.target.isPlaying)
                sound.target.Stop();
        }
    }

    public void StopAllObjSoundExcept(string keyList)
    {
        foreach (var sound in objects)
        {
            if (sound.target.isPlaying && !keyList.Contains(sound.key))
                sound.target.Stop();
        }
    }

    public void StopSceneSound()
    {
        AudioSource tempAudioSource = null;
        for (int i = 0; i < transform.childCount; i++)
        {
            tempAudioSource = transform.GetChild(i).GetComponent<AudioSource>();
            if (tempAudioSource != null && tempAudioSource.isPlaying)
                tempAudioSource.Stop();

        }
    }

    public void StopSceneSound(string noStopkey)
    {
        AudioSource tempAudioSource = null;
        for (int i = 0; i < transform.childCount; i++)
        {
            tempAudioSource = transform.GetChild(i).GetComponent<AudioSource>();
            if (tempAudioSource != null && tempAudioSource.isPlaying)
            {
                if (!tempAudioSource.clip.name.Equals(noStopkey))
                {
                    tempAudioSource.Stop();
                }
            }
        }
    }
    public void StopSound(string key, float fadeTime)
    {
        var len = transform.childCount;
        while (len-- > 0)
        {
            var child = transform.GetChild(len);
            if (child.name == key)
            {
                child.SetParent(null);
                child.GetComponent<AudioSource>().DOFade(0, fadeTime).OnComplete(
                    delegate {
                        Destroy(child.gameObject);
                    } 
                    );
                break;

            }
        }
    }


    /// <summary>
    /// 获取语音时长
    /// </summary>
    public float GetObjectSoundLength(string key)
    {
        var sd = GetObjectSound(key);
        if (sd == null)
            return 0;
        var aud = sd.target.GetComponent<AudioSource>();
        if (aud != null && aud.clip != null)
            return aud.clip.length;
        return 0;
    }
    public ObjectSoundData GetObjectSound(string key)
    {
        ObjectSoundData sd = null;
        foreach (var s in objects)
        {
            if (s.key == key)
            {
                sd = s;
                break;
            }
        }
        return sd;
    }
    //private GameObject CreateTemplate()
    //{
    //    var obj = new GameObject("template");
    //    var ac = obj.AddComponent<AudioControl>();
    //    ac.key = POOL_KEY;
    //    var aud = obj.AddComponent<AudioSource>();
    //    aud.loop = false;
    //    aud.playOnAwake = false;
    //    var sp = obj.AddComponent<SimplePoolable>();
    //    obj.transform.SetParent(transform);
    //    return obj;
    //}

    private GameObject GetPlayingSoundObject(string key)
    {
        var len = transform.childCount;
        while (len-- > 0)
        {
            var child = transform.GetChild(len);
            if (child.name == key)
                return child.gameObject;
        }

        return null;
    }
    // 正常播放  
    private void PlayAudio(AudioSource aud, float delay, bool recursive = false, float volume = 1)
    {
        aud.loop = recursive;
        aud.volume = volume;
        if (delay != 0)
            aud.PlayDelayed(delay);
        else
            aud.Play();

    }
}

[System.Serializable]
public class SoundData
{
    public string key;
    public AudioClip audio;
    public AudioPlayMode mode;
    public float delay;
}

[System.Serializable]
public class ObjectSoundData
{
    public string key;
    public AudioSource target;
    public AudioPlayMode mode;
    public float delay;
}

public enum AudioPlayMode
{
    Multiple, //a sound can play multiple time independently.
    InstanceIgnore, //if already playing the sound, then ignore current operation.
    InstanceRestart //if already playing the sound, then restart from the beginning.
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值