在开发中,想必用到的最多的就是单例模式了。那么今天就分享一下我经常在开发中用到的单例模式。
伪单例
using UnityEngine;
public class SingleScript : MonoBehaviour
{
public static SingleScript Instance;
private void Awake()
{
Instance = this;
}
}
不继承MonoBehaviour的单例
public class SingleScriptClass
{
public int game = 0;
private static SingleScriptClass _instance;
public static SingleScriptClass Instance()
{
if (null == _instance)
_instance = new SingleScriptClass();
return _instance;
}
}
你会发现这样写 每次新建类时都要手动写一遍 会很麻烦 有没有更简单的一劳永逸的方法呢?
当然了 我会在下面创建一个单例基类 这样每次创建的类需要使用单例模式时只需要继承该类就会具有单例模式的特点了
因为是使用了创建对象的方式 脚本其实可以不用挂载在场景物体中 (如果忘记挂载脚本)脚本在被调用时会自动创建一个物体给他挂载脚本
//创建脚本对象(立即执行Awake)
new GameObject(“Singleton of” + typeof(T).Name).AddComponent();
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Common
{
///<summary>
///脚本单例类
///</summary>
public class MonoSingleton<T> : MonoBehaviour where T:MonoSingleton<T>
{
//T 表示子类类型
private static T instance;
public static T Instance
{
get
{
if (instance==null)
{
//在场景中根据类型查找引用
instance = FindObjectOfType<T>();
//如果忘记挂载 T这个脚本了
if (instance==null)
{
//创建脚本对象(立即执行Awake)
new GameObject("Singleton of" + typeof(T).Name).AddComponent<T>();
}
else
{
//初始化
instance.Init();
}
}
return instance;
}
}
/// <summary>
/// 如果子类需要在Awake操作 重写这个方法
/// </summary>
public virtual void Init()
{
}
protected void Awake()
{
if (instance==null)
{
instance = this as T;
Init();
}
}
}
}
使用方法也很简单 只需要继承该类就好
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace CLK
{
public class Test: Common.MonoSingleton<Test>
{
public void DebugTest()
{
Debug.Log("我是Test class");
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Common;
using System;
namespace CLK
{
public class GameManager: MonoSingletonDontDestroy<GameManager>
{
//如果需要在awake方法中执行一些逻辑 可以重写Init方法
public override void Init()
{
base.Init();
//TODO:
}
private void Start()
{
Test.Instance.DebugTest();
}
}
}
运行结果
还有其他两种单例基类写法
一种是使用了unity的DontDestroyOnLoad方法 切换场景不会卸载物体
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Common
{
///<summary>
///脚本单例类
///</summary>
public class MonoSingletonDontDestroy<T> : MonoBehaviour where T: MonoSingletonDontDestroy<T>
{
//T 表示子类类型
private static T instance;
public static T Instance
{
get
{
if (instance==null)
{
//在场景中根据类型查找引用
instance = FindObjectOfType<T>();
//如果忘记挂载 T这个脚本了
if (instance==null)
{
//创建脚本对象(立即执行Awake)
new GameObject("Singleton of" + typeof(T).Name).AddComponent<T>();
}
else
{
//初始化
instance.Init();
}
}
return instance;
}
}
/// <summary>
/// 如果子类需要在Awake操作 重写这个方法
/// </summary>
public virtual void Init()
{
}
protected void Awake()
{
Debug.Log("初始化");
if (instance==null)
{
instance = this as T;
Init();
}
else
{
if (instance!=this )
{
Destroy(gameObject);
}
}
DontDestroyOnLoad(gameObject);
}
}
}
一种是不继承Monobehaviour的类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Common
{
public class Singleton<T> where T : new()
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
instance = new T();
}
return instance;
}
}
}
}