Unity作为一个脚本语言,我们可以很方便的直接把脚本挂在object上运行。这样的做法对于一些小游戏来说是非常的方便的,不用我们自己再用代码去主动的实例化对象,Unity自动帮我们实例化好了。但如果是对于大型项目来说就很麻烦了,因为大型项目每个模块都会有一定的关联性,也会有一定的解耦,过度的把脚本挂在Object上会使得脚本非常的难统一去管理。
在unity游戏项目中,为了更好的管理我们的游戏脚本,我们需要一个单例模式类作为游戏的初始启动点。通过APP Singleton类初始化游戏的配置参数,下载资源,加载场景等。话不多说,单例类贴上
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace Joey
{
/// <summary>
/// 单线程下的简单单例模式
/// </summary>
public class SimpleSingleton
{
private static SimpleSingleton instance;
public static SimpleSingleton Instance
{
get
{
if (instance == null)
{
instance = new SimpleSingleton();
}
return instance;
}
}
public SimpleSingleton(){ }
}
/// <summary>
/// 多线程下的单例模式
/// </summary>
public class ThreadSingleton
{
private static ThreadSingleton instance;
//定义一个标识确保线程同步
private static readonly object locker=new object();
//构造函数为Private防止外部实例化
private ThreadSingleton()
{
}
//当第一个线程运行过来会对locker添加锁
//这里先判断instance是否为null,防止线程加锁后再去判断的话会进行额外的开销
//当第二个线程过来的时候,会检测加锁状态,该线程就会挂起等待第一个线程解锁
//lock语句完成后会对线程解锁
public static ThreadSingleton GetInstance()
{
if (instance==null)
{
lock(locker)
{
if (instance==null)
{
instance=new ThreadSingleton();
}
}
}
return instance;
}
}
/// <summary>
/// 继承于MonoBehavior下的单例模式
/// 运用到泛型,是因为如果我们不用泛型的话,那么我们游戏中的每个单例脚本都要这样去写,这就很麻烦了。有了泛型之后就可以直接运用
/// 看下面的实例类
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonMono<T>:MonoBehaviour where T:Component
{
private static T instance;
public static T Instace
{
get
{
if(instance==null)
{
instance = FindObjectOfType(typeof(T)) as T;
if(instance==null)
{
GameObject obj = new GameObject();
obj.hideFlags = HideFlags.HideAndDontSave;
instance=obj.AddComponent<T>();
}
}
return instance;
}
}
void Awake()
{
DontDestroyOnLoad(this);
if(instance==null)
{
instance = this as T;
}
}
}
public class SingletonTest:SingletonMono<SingletonTest>
{
public SingletonTest()
{
}
public void Log()
{
Debug.Log("SingletonMono Test");
}
}
public class Test
{
public Test()
{
SingletonTest.Instace.Log();
//Manger.Instance
}
}
}
在Unity项目中经常用到的是带继承MonoBehavior的单例,但可能有时候我们并需要继承MonoBehavior类的管理类又该如何去使用单例呢。这个有位大神给我们了很好的代码。
大神链接:http://liangxiegame.com/unity-you-xi-kuang-jia-da-jian-er-dan-li-de-mo-ban/
主要代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
/// <summary>
/// 1.泛型
/// 2.反射
/// 3.抽象类
/// 4.命名空间
/// </summary>
namespace QFramework {
public abstract class QSingleton<T> where T : QSingleton<T>
{
protected static T instance = null;
protected QSingleton()
{
}
public static T Instance()
{
if (instance == null)
{
// 先获取所有非public的构造方法
ConstructorInfo[] ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
// 从ctors中获取无参的构造方法
ConstructorInfo ctor = Array.Find(ctors, c => c.GetParameters().Length == 0);
if (ctor == null)
throw new Exception("Non-public ctor() not found!");
// 调用构造方法
instance = ctor.Invoke(null) as T;
}
return instance;
}
}
}
// 1.需要继承QSingleton。
// 2.需要实现非public的构造方法。
public class XXXManager : QSingleton<XXXManager> {
private XXXManager() {
// to do ...
}
}
public static void main(string[] args)
{
XXXManager.Instance().xxxyyyzzz();
}
还有对于这些单例类 我们又该如何去管理呢,在此贴上另一个大神的链接
链接:http://blog.csdn.net/ycl295644/article/details/49487361
对于单例模式Unity3D官方也有示例代码:http://wiki.unity3d.com/index.php/Singleton
相信这些只是应该能够帮助大家对于Unity3D单例模式的用法有个足够的了解