音频/面板资源管理器_Audio&PanelManager

本文介绍了基于Unity和C#的自定义音频和面板资源管理器,采用面向对象思想,实现独立操作,降低组件间耦合度,适用于个人项目改进。

本文为参考大佬的代码,进行自定义修改,更适合自己使用,有待完善,仅供参考交流


====>>>>>>Unity_C# "面向对象"思想,独立操作,拒绝藕合

public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
    private static T instance;

    public static T Instance
    {
        //只读单例
        get
        {
            if (instance == null) 
            {
                //创建新Obj 命名和类名一样,并添加对应管理脚本,省去挂载过程
                GameObject obj = new GameObject(typeof(T).Name);
                instance = obj.AddComponent<T>();
            }
            return instance;
        }
    }

    protected virtual void Awake()
    {
        instance = this as T;
    }
}
//泛型单例类,通用,此处不是重点
public class Singleton<T> where T : new()
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new T();
            }
            return instance;
        }
    }
}
//资源加载工具
public class ResourcesTool : Singleton<ResourcesTool>
{
    public T ResourcesLoad<T>(object objName) where T : Object
    {
        string objFilePath = string.Empty;
		//根据枚举获取对应资源路径
        switch (objName.GetType().Name)
        {
            case "Audio_BGMusic":
                objFilePath = "Audios/BGMusic/" + objName.ToString();
                break;
            case "Audio_UI":
                objFilePath = "Audios/UI/" + objName.ToString();
                break;
            case "Panel_Person":
                objFilePath = "Panels/Person/" + objName.ToString();
                break;
            default:
                break;
        }
        //Debug.Log("objFilePath:" + objFilePath);
        //根据路径加载资源
        return LoadObj<T>(objFilePath);
    }

    private static readonly Dictionary<string, object> objDic = new Dictionary<string, object>();

    /// <summary>
    /// 动态加载资源
    /// </summary>
    public T LoadObj<T>(string path) where T: Object
    {
        if (!objDic.TryGetValue(path, out object obj))
        {
            obj = Resources.Load<T>(path);
            objDic.Add(path, obj);
        }
        return obj as T;
    }
}
public class EnumResources
{
    public enum Audio_BGMusic
    {
        None,
        FamilyBg,
    }
    public enum Audio_UI
    {
        None,
        ExitAudio,
        BtnClick,
    }
    public enum Panel_Default
    {
        None,
        EnterPanel,
        ExitPanel,
    }
}
//音频管理类
public class AudioController : MonoSingleton<AudioController>
{
    public AudioSource Aud_BGMusic { get; set; }
    public AudioSource Aud_Effect { get; set; }
    public AudioSource Aud_UI { get; set; }

    private Coroutine curCoroutine = null;

    protected override void Awake()
    {
        base.Awake();

        //Debug.Log("测试名字:"+gameObject);
		//Aud_Effect可做平常语音提示,也可和Aud_UI合并一个AudioSource,根据个人需要自行修改
        Aud_Effect = gameObject.AddComponent<AudioSource>();
        Aud_Effect.loop = false;
        Aud_Effect.playOnAwake = false;

        Aud_UI = gameObject.AddComponent<AudioSource>();
        Aud_UI.loop = false;
        Aud_UI.playOnAwake = false;

        Aud_BGMusic = gameObject.AddComponent<AudioSource>();
        Aud_BGMusic.loop = false;
        Aud_BGMusic.playOnAwake = false;        
    }

    public void PlayBGMusic(object bgMusic, bool isRestart = false, bool isLoop = false, float volume = 1.0f)
    {
        PlayAudioClip(Aud_BGMusic, bgMusic, null, isRestart, isLoop);
    }

    public void PlayEffect(object objName, UnityAction CallBack = null, bool isRestart = false)
    {
        PlayAudioClip(Aud_Effect, objName, CallBack, isRestart, false);
    }    

    public void PlayUI(object audioUI, float volume = 1.0f)
    {
        PlayUIObj(Aud_UI, audioUI, volume);
    }

    public void StopAudio(AudioSource audioSrc)
    {
        audioSrc.Stop();
    }

    private void PlayAudioClip(AudioSource audioSrc, object objName, UnityAction CallBack = null, bool isRestart = false, bool isLoop = false, float volume = 1.0f)
    {
        if (isLoop)
            audioSrc.loop = true;
        else
            audioSrc.loop = false;

        string currentClipName = string.Empty;
        if (audioSrc.clip != null)
            currentClipName = audioSrc.clip.name;

        AudioClip clip = ResourcesTool.Instance.ResourcesLoad<AudioClip>(objName);
        if (clip != null)
        {   //判断是否同一个音频要重新播放
            if (currentClipName == clip.name && !isRestart)
                return;

            audioSrc.clip = clip;
            audioSrc.volume = volume;
            audioSrc.Play();
            if (CallBack != null)
            {
                if (curCoroutine != null)
                {
                    StopCoroutine(curCoroutine);
                    curCoroutine = null;
                }
                curCoroutine = StartCoroutine(IeDelay(clip.length, CallBack));
            }
        }
        else
        {
            Debug.Log("Audio is Null");
        }
    }
    private IEnumerator IeDelay(float time, UnityAction CallBack)
    {
        yield return new WaitForSeconds(time);
        CallBack?.Invoke();
    }

    private void PlayUIObj(AudioSource audioSrc, object objName, float volume = 1.0f)
    {
        AudioClip clip = ResourcesTool.Instance.ResourcesLoad<AudioClip>(objName);

        if (clip == null)
        {
            Debug.Log("Audio is null");
            return;
        }           

        audioSrc.PlayOneShot(clip, volume);
    }

    //再有特殊分类冲突,直接调用可播放:AudioSources.PlayClipAtPoint(ResourcesTool.Instance.ResourcesLoad<AudioClip>(objName));
    //PlayCkipAtPoint 适合播放3D音效,每次播放创建一AudioSource,播放完即释放掉
}
//需要动态创建面板时(尤其是相似面板)
public class PanelController : MonoSingleton<PanelController>
{
    public Transform CurPanel { get; set; }

    private string lastPanelName;

    public void CreatePanel(object objName, Transform parent, string title = null, bool isRestart = false)
    {
        CreatePanelObj(objName, parent, title, isRestart);
    }

    private void CreatePanelObj(object objName, Transform parent, string title = null, bool isRestart = false)
    {
        Transform panel = ResourcesTool.Instance.ResourcesLoad<Transform>(objName);

        if (panel != null)
        {   
            //判断是否同一个面板要重新创建
            if (lastPanelName == panel.name && !isRestart)
                return;
            else
                lastPanelName = panel.name;

            //面板实例化
            CurPanel = Instantiate(panel);            

            //面板位置设置
            CurPanel.SetParent(parent);
            CurPanel.localPosition = Vector3.zero;
            CurPanel.localEulerAngles = Vector3.zero;
            CurPanel.localScale = Vector3.one;

            if (CurPanel.GetComponent<RectTransform>() != null)
            {
                CurPanel.GetComponent<RectTransform>().sizeDelta = Vector2.zero;
            }

            if (CurPanel.Find("Title") != null)
            {
                CurPanel.Find("Title").GetComponent<Text>().text = title;
            }
        }
        else
        {
            Debug.Log("Panel is Null");
        }
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值