单例模式基类
类不继承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();
资源加载管理器
五种方法文章来源:https://uudwc.com/A/W1XM0
- 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);
文章来源地址https://uudwc.com/A/W1XM0