前言
如果在外部想在不同的时间结点、不同的位置访问某类中的成员且想要保持访问时,成员地址唯一。
那么可以考虑将该类声明为静态类,但若是成员中包含公共的数据类型,此时便可以考虑将该类做成一个单例。
单例模式
由于类中的数据,必须在实例化后堆栈才会为其分配变量的值,以及引用类型的地址,通过地址在静态存储区中也可访问其值。
那么,脚本文件每初始化一次,不管数据相不相同,已经是两个对象了,那么需要读取或者更新的字段就有可能出错。
所以,要保证外界可访问自身
需要在给类一个静态的公共自身成员,作为访问的中间桥梁
private static T _instance;
public static T Instance => GetInstance();
要保证,单一对象
- 在第一次访问时,new()
- 如果已经实例化,使用之前实例化过的对象
private static T GetInstance()
{
if (_instance != null) return _instance;
_instance = new T();
_instance.Initialize();
return _instance;
}
public static void CreateSingleton()
{
GetInstance();
}
访问时:SingletonAClass.Instance.Function();
就可以访问到唯一的function方法了。
单例类
实际在开发中,会根据需求做成单例类的形式,使用不同的泛型约束,构造成不同的基类。
使用时,根据需求继承即可。
不继承Monobehavior的形式
在做一些公共数据库的时候,游戏频繁访问的一些实时数据,一般会把它做成单例,然后根据需求给数据一些 get set方法。文章来源:https://www.toymoban.com/news/detail-683417.html
/// <summary>
/// 通用单例。
/// </summary>
/// <typeparam name="T">泛型T。</typeparam>
public abstract class Singleton<T> where T : Singleton<T>, new()
{
private static T _instance;
public static T Instance => GetInstance();
private static T GetInstance()
{
if (_instance != null) return _instance;
_instance = new T();
_instance.Initialize();
return _instance;
}
public static void CreateSingleton()
{
GetInstance();
}
public static bool HasInstance()
{
return _instance != null;
}
public static void DestroySingleton()
{
_instance?.UnInitialize();
_instance = null;
}
protected abstract void Initialize();
protected abstract void UnInitialize();
}
继承自Monobehavior的形式
最常见的,流程管理、总控的XXManager、XXController的脚本,一般会频繁调用,没有必要每次都实例化一个新的对象,实际会做成单例。约束绑定继承自Monobehavior文章来源地址https://www.toymoban.com/news/detail-683417.html
/// <summary>
/// 具备Unity完整生命周期的单例。
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class UnitySingleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
var ins = FindObjectOfType<T>();
if (ins != null)
{
var obj = ins.gameObject;
obj.name = typeof(T).Name;
_instance = ins;
SingletonMgr.Retain(obj);
return Instance;
}
System.Type thisType = typeof(T);
string instName = thisType.Name;
GameObject go = SingletonMgr.GetGameObject(instName);
if (go == null)
{
go = GameObject.Find($"[{instName}]");
if (go == null)
{
go = new GameObject($"[{instName}]")
{
transform =
{
position = Vector3.zero
}
};
}
}
_instance = go.GetComponent<T>();
if (_instance == null)
{
_instance = go.AddComponent<T>();
}
if (_instance == null)
{
Log.Error($"Can't create UnitySingleton<{typeof(T)}>");
}
}
return _instance;
}
}
public static T Active()
{
return Instance;
}
public static bool IsValid => _instance != null;
private bool CheckInstance()
{
if (this == Instance)
{
return true;
}
GameObject.Destroy(gameObject);
return false;
}
protected virtual void OnLoad()
{
}
public virtual void Awake()
{
if (CheckInstance())
{
OnLoad();
}
#if UNITY_EDITOR
Log.Debug($"UnitySingleton Instance:{typeof(T).Name}");
#endif
GameObject tEngine = SingletonMgr.Root;
if (tEngine != null)
{
this.gameObject.transform.SetParent(tEngine.transform);
}
}
protected virtual void OnDestroy()
{
Release();
}
public static void Release()
{
if (_instance == null) return;
SingletonMgr.Release(_instance.gameObject);
_instance = null;
}
}
到了这里,关于浅谈单例模式在游戏开发中的应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!