单例模式基类
类不继承mono的单例基类
/// <summary>
/// 单例基类
/// </summary>
//泛型解决,给他一个约束要么是这个类本身要么是它的子类
public class SingleBase<T>where T : SingleBase<T>
{protected SingleBase() { }//线程锁。当多线程访问时,同一时刻仅允许一个线程访问。private static object locker=new object();//volatile关键字修饰字段是当多个线程都对他进行修改时,确保这个字段在任何时刻呈现都是最新的值private volatile static T _instance;public static T Instance{get{//双重保证对象的唯一性if (_instance == null){lock (locker){if (_instance == null){//使用反射调用无参构造方法创建对象,就是new一个对象的意思_instance = Activator.CreateInstance(typeof(T), true) as T;}}}return _instance;}}
}
继承单例基类就不用再写了
public class PlayerModel:SingleBase<PlayerModel>
{private PlayerModel() { }public int money=1000;public int diamond = 888;public void Show(){Debug.Log(money);Debug.Log(diamond);}
}
PlayerModel.Instance.Show();
类继承mono的单例基类
/// <summary>
/// 继承monobehaviour的单例基类,前面是继承,where后面是泛型约束,要么是本身,要么是继承monobehaviour
/// </summary>
public class SingleMonoBase<T> : MonoBehaviour where T : MonoBehaviour
{protected SingleMonoBase() { }//声明一个isExisted属性用来表示单例对象是否存在,用来记录单例对象是否存在,用于防止在OnDestroy方法中访问单例对象报错。public static bool isExisted { get; private set; } = false;private static T _instance;public static T Instance{get{if (_instance == null){_instance=FindObjectOfType<T>();if (_instance == null){//通过反射获取T类型的名字,typeof(T)就是获取T类型的信息,创建游戏对象挂载脚本GameObject go = new GameObject(typeof(T).Name);_instance = go.AddComponent<T>();DontDestroyOnLoad(go);isExisted = true;}}return _instance;}}//在子类中也可能有OnDestroy用protected修饰可以访问了,子类可能重写这个方法还要写关键字virtual成为虚方法让子类重写他protected virtual void OnDestroy(){isExisted=false;}
}
public class YaoUIManager : SingleMonoBase<YaoUIManager>
{private YaoUIManager() { }public void yao(){Debug.Log("yaoyao");}
}}
YaoUIManager.Instance.yao();
资源加载管理器
五种方法
- inspector窗口拖拽,Instantiate(go);
- resources.Load方法、Resources.LoadAsync方法、Resources.LoadAll方法来加载资源。Resources文件夹只能存储2G左右的资源,要谨慎使用,不支持热更新。
- AssetBundle.LoadFormXXX方法来加载资源。
- Addressables(可寻址资源系统),理解为高级的AssetBundle,资源管理由unity内部自动完成。目前还在发展中,可能有bug。
- AssetDatabase.LoadAssetAtPath方法来加载资源,仅限于编辑器模式,主要用于再编辑器模式下用代码改变本地文件。
using System.Resources;using UnityEngine.Events;/// <summary>
/// 封装resourcesManager的异步加载
/// </summary>
public class ResourcesManager : SingleMonoBase<ResourcesManager>
{/// <summary>/// 同步加载Resources文件夹中指定类型的资源/// 如果有多个相同类型,且相同路径的资源,则只会返回找到的第一个资源。/// </summary>/// <typeparam name="T">要加载的资源的类型</typeparam>/// <param name="path">资源的路径</param>/// <returns></returns>public T Load<T>(string path)where T:Object{return Resources.Load<T>(path);}public T[] LoadAll<T>(string path) where T : Object{return Resources.LoadAll<T>(path);}/// <summary>/// 异步加载Resources文件夹中指定类型的资源/// 如果有多个相同类型,且相同路径的资源,则只会加载找到的第一个资源。/// </summary>/// <typeparam name="T">加载的资源的类型</typeparam>/// <param name="path">要加载的资源的路径</param>/// <param name="callback">资源加载完毕后要执行的逻辑</param>public void LoadAsync<T>(string path,UnityAction<T> callback=null)where T : Object{StartCoroutine(LoadAsyncCoroutine(path,callback));}IEnumerator LoadAsyncCoroutine<T>(string path,UnityAction <T> callback=null) where T : Object{ResourceRequest resourceRequest= Resources.LoadAsync<T>(path);//开始加载资源yield return resourceRequest;//等待资源加载完毕callback?.Invoke(resourceRequest.asset as T);}public void UnloadUnusedAssets(UnityAction callback=null){MonoManager.Instance.StartCorotine(UnloadUnusedAssetCoroutine(callback));}IEnumerator UnloadUnusedAssetCoroutine(UnityAction callback=null){AsyncOperation asyncOperation = Resources.UnloadUnusedAssets();//开始卸载资源while (asyncOperation.progress < 1){yield return null;}//资源卸载完毕后执行的逻辑callback?.Invoke();}
}
GameObject go = ResourcesManager.Instance.Load<GameObject>("Prefabs/Cube");GameObject[] gos = ResourcesManager.Instance.LoadAll<GameObject>("Prefabs");
音频管理器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 音频管理器
/// </summary>
public class AudioManager : SingleMonoBase<AudioManager>
{//各个声道的AudioSource组件AudioSource bgmAudiosource;AudioSource bgsAudiosource;AudioSource voiceAudiosource;//各个声道的游戏对象GameObject bgmController;GameObject soundController;GameObject bgsController;GameObject msController;GameObject voiceController;private void Awake(){//背景音乐控制bgmController = CreatController("BGMController");bgmAudiosource = bgmController.GetComponent<AudioSource>();bgmAudiosource.playOnAwake = false;bgmAudiosource.loop = true;//音效控制soundController = CreatController("SoundController");bgsAudiosource = bgmController.GetComponent<AudioSource>();bgsAudiosource.loop=true;msController = CreatController("MSController");//声音控制voiceController = CreatController("VoiceController");voiceAudiosource=voiceController.GetComponent<AudioSource>();voiceAudiosource.playOnAwake=false;voiceAudiosource.loop = false;}//创建控制器GameObject CreatController(string name){GameObject go=new GameObject(name);go.transform.SetParent(transform);return go;}
}
AudioManager.Instance.PlayBGM(BGM_1);
AudioManager.Instance.PauseBGM(BGM_1);
AudioManager.Instance..UnPauseBGM(BGM_1);
AudioManager.Instance.StopBGM(BGM_1);AudioManager.Instance.PlaySound(Sound_1,new Vector3(1,2,3));
AudioManager.Instance.PauseSound(Sound_1,GameObject.Find("Gold"));
AudioManager.Instance..UnPauseSound(BGM_1);
AudioManager.Instance.StopSound(BGM_1);