• 【Unity】单例模式及游戏声音管理类应用


    【Unity】单例模式及游戏声音管理类应用

    描述

    在日常游戏项目开发中,单例模式是一种常用的设计模式,它允许在应用程序的生命周期中只创建一个对象实例,并提供对该实例的全局访问点。通过使用单例模式,可以提高代码的可维护性和可重用性。

    单例写法

    通过创建一个泛型Singleton类,可以让全局功能类继承,从而使全局功能类都具备单例特性。这样做可以避免在全局功能类之间书写重复的代码,让代码更加精简和易于维护。

    • 错误写法,this类型无法转化为泛型
      在这里插入图片描述
    • 正确写法,让泛型T继承MonoBehaviour
      在这里插入图片描述

    Singleton类继承MonoBehaviour,而且 泛型T 也继承MonoBehaviour,故[this]才能转换为泛型类[T]。

    代码如下:

    using UnityEngine;
    
    public abstract class Singleton<T> : MonoBehaviour
        where T : MonoBehaviour
    {
        private static T instance;
        public static T Instance { get { return instance; } }
        
        protected virtual void Awake()
        {
            instance = this as T;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    声音管理类

    继承Singleton类,使得声音管理类成为单例,提高代码的可维护性和重用性。

    代码如下:

    using UnityEngine;
    
    public class SoundManager : Singleton<SoundManager> {
    
        public string resourcesDir = "sound";
        private AudioSource musicAu;
        private AudioSource soundAu;
    
        protected override void Awake()
        {
            base.Awake();
            DontDestroyOnLoad(this);
            
            musicAu = gameObject.AddComponent<AudioSource>();
            musicAu.loop = true;
            musicAu.playOnAwake = false;
    
            soundAu = gameObject.AddComponent<AudioSource>();
        }
    
        /// 
        /// 播放音乐
        /// 
        /// 名字
        public void PlayMusic(string clipName)
        {
            string name;
            if(musicAu.name == null)
            {
                name = "";
            }
            else
            {
                name = musicAu.name;
            }
            if(name != clipName)
            {
                string path = resourcesDir + "/" + clipName;
                AudioClip clip = Resources.Load<AudioClip>(path);
                if(clip != null)
                {
                    musicAu.clip = clip;
                    musicAu.Play();
                }
            }
        }
    
        /// 
        /// 暂停播放音乐
        /// 
        public void StopMusic()
        {
            if(musicAu.clip != null)
            {
                musicAu.Stop();
            }
        }
    
        /// 
        /// 播放声音
        /// 
        /// 名字
        public void PlaySound(string clipName)
        {
            string path = resourcesDir + "/" + clipName;
            AudioClip clip = Resources.Load<AudioClip>(path);
            if(clip != null)
            {
                soundAu.PlayOneShot(clip);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    在项目根目录创建Resources文件夹,并在该文件夹中再创建sound文件夹,用来存放播放的声音。
    在其他脚本,直接通过单例播放该名称的背景音乐/特效声音。

    代码如下:

    //播放背景音乐-BackgroundMusic
    SoundManager.Instance.PlayMusic("BackgroundMusic");
    //播放特效声音-ClickButton
    SoundManager.Instance.PlaySound("ClickButton");
    
    • 1
    • 2
    • 3
    • 4

    因为作者精力有限,文章中难免出现一些错漏,敬请广大专家和网友批评、指正。

  • 相关阅读:
    JavaScript基础知识-JS数据类型
    RabbitMQ(五)交换机
    强引用、软引用、弱引用、虚引用的区别
    【Docker】搭建一键更新容器工具 - OneKey
    2022.8.22-8.28 AI行业周刊(第112期):个人定位发展
    Centos7 编写开机监测gdm服务退出的脚本
    FPGA-HDMI-彩条显示实验(ZYBO Z7)
    Nacos源码分析专题(五)-Nacos小结
    通过git bash激活虚拟环境遇到的问题
    Docker使用nodejs镜像构建express服务
  • 原文地址:https://blog.csdn.net/qq_46051312/article/details/134483037