一.单例类模板
using UnityEngine;
/// <summary>
/// 通用Mono单例模板
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
private static T ms_instance;
public static T Instance
{
get
{
if (ms_instance == null)
{
ms_instance = Instantiate();
}
return ms_instance;
}
}
protected static T Instantiate()
{
if (ms_instance != null) return ms_instance;
// 在场景中查找T类型的Mono类
ms_instance = (T)FindObjectOfType(typeof(T));
if (FindObjectsOfType(typeof(T)).Length > 1)
{
return ms_instance;
}
if (ms_instance != null) return ms_instance;
// 创建GameObject实例
var singleton = new GameObject("[Singleton]" + typeof(T).Name);
DontDestroyOnLoad(singleton); // 设置GameObject不被销毁
if (singleton == null) return ms_instance;
// 添加Mono单例脚本
ms_instance = singleton.AddComponent<T>();
// 初始化单例
ms_instance.InitSingleton();
return ms_instance;
}
protected virtual void InitSingleton()
{
}
/// <summary>
/// 使用预制体实例化时创建单例
/// </summary>
protected virtual void Awake()
{
if (ms_instance == null)
{
ms_instance = this as T;
// 初始化单例
InitSingleton();
}
else
{
// 如果已经存在实例,则需要销毁当前的GameObject
GameObject.Destroy(this.gameObject);
}
}
protected virtual void OnApplicationQuit()
{
ms_instance = null;
// 销毁GameObject
GameObject.Destroy(this.gameObject);
}
}
MonoSingletonExample:
public class UITWQChoiceQuestion : MonoSingleton<UITWQChoiceQuestion>
{
protected override void Awake()//重写Awake
{
base.Awake();//被重写的Awake 也执行,不添加base 则只执行重写的Awake
BtnCommit.onClick.AddListener(() => { OnBtnCommit(); });
}
}
二.对象池的简单使用:
对象池的管理:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolManage : MonoSingleton<PoolManage>
{
//开辟一块 对象池
List<GameObject> objectPools = new List<GameObject>();
protected override void Awake()
{
base.Awake();
}
/// <summary>
/// 从对象池中获取
/// </summary>
/// <param name="obj"></param>
public void GetObj(GameObject obj)
{
//判断池中是否有可用资源
if (objectPools.Count == 0) //没有则重新生成
{
GameObject go = Instantiate(obj, Vector3.zero, Quaternion.identity) as GameObject;
//并添加到池中
objectPools.Add(go);
}
else
{
//从对象池中取
GameObject go = objectPools[0];
go.SetActive(true);
objectPools.Remove(go);
}
}
/// <summary>
/// 放到对象池中
/// </summary>
/// <param name="obj"></param>
public void SetObj(GameObject obj)
{
objectPools.Add(obj);
obj.SetActive(false);
}
}
//在想要用到的地方直接调用:
PoolManage.Instance.GetObj(GameObject);//从对象池中拿取,没有则创建并存取对象池
Example :
public GameObject BullerPre;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
PoolManage.Instance.GetObj(BullerPre);
}
}
Example :
挂载在子弹预制的类 用来回收子弹
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
//在创建一个脚本挂在子弹预设物上,用来回收子弹
public float Speed = 7f;
void Update()
{
//让子弹向前移动
transform.Translate(Vector3.forward * Time.deltaTime * Speed);
StartCoroutine(DesBullet(3f));
}
//回收子弹,用完 放回对象池
private IEnumerator DesBullet(float v)
{
yield return new WaitForSeconds(v);
PoolManage.Instance.SetObj(gameObject);
this.transform.position = Vector3.zero;
}
}