您的位置:首页 > 移动开发 > Unity3D

Unity组件的基类单例模式

2016-04-09 13:56 330 查看

0. 背景

单例模式非常常见,在各种语言上都能见到,用处也十分广泛,前一篇文章有讲到python的两种单例模式。当然Unity中组件的单例模式用途也很广,例如游戏中各种
Manager
, 使用
StartCoroutine
,
GetComponent
等方法的单例,本文简要讲述一下Unity中对于组件的单例模式如何构建。

1. 相同之处

首先既然是单例模式,也就符合单例的一些既定规则:

- 构造参数为私有;

- 存在
static
的实例变量名
instance


- 存在
static
的方法-
Instance
or
GetInstance
,以获取
instance
,若第一次获取
instance
则需要
new
一个实例。

2. 不同之处

- 既然是
Unity
的组件
Component
,在
new
组件实例时: 先需要
new GameObject
, 然后
new Component
, 并把新建的组件实例挂载到
GameObject


- 当然这个新建的
GameObject
不能持久化到
Unity Editor
,也就是
xxxx.unity
上不能将这个
GameObejct
保存进去;

- 作为一个单例的基类其实需要使用到泛型。

3. Singleton

Post Code是最好的解释行为。

首先声明命名空间:

using UnityEngine; // Unity相关API
using System.Collections;
using System;


其次声明单例类和其
static
的实例变量名
instance


// 泛型T,继承自MonoBehaviour, 保证了此单例是组件的基类
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
protected static T instance;
...
}


然后实现
static
的方法-
Instance
or
GetInstance


/**
Returns the instance of this singleton.
*/
public static T Instance //使用c#的get,set Property的写法
{
get
{

if(instance == null){ //第一次调用Singleton<T>.Instance时instance==null
if(instantiated)
return null;
instance = (T) FindObjectOfType(typeof(T)); // 寻找object,找到后转为Component

if (instance == null){ //如果没有找到
GameObject go = new GameObject();//新建GameObject
go.name = typeof(T).ToString();
instance = go.AddComponent<T>();//把T挂载到go上,
instantiated = true; //初始化成功
}
}

//Destroy instance if the singleton persists into the editor
if (Application.isEditor && !Application.isPlaying){ //持久化之前消除该GameObject
Destroy(instance);
instance = null;
}

return instance;
}
}


4. Program

使用Singleton请看如下代码:

//新建一个HttpRequest单例
class HttpRequest : Singleton<HttpRequest>
{

// Get请求
public WWW GET(string url)
{
WWW www = new WWW (url);
StartCoroutine (WaitForRequest (www)); // 由于是继承自MonoBehaviour,所以可以调用协程函数StartCoroutine
while (!www.isDone) {}
return www;
}

// Post请求
public WWW POST(string url, Dictionary<string,string> post)
{
WWWForm form = new WWWForm();
foreach(KeyValuePair<String,String> post_arg in post)
{
form.AddField(post_arg.Key, post_arg.Value);//添加表单字段数据
}
WWW www = new WWW(url, form);

StartCoroutine(WaitForRequest(www));
while (!www.isDone) {}
return www;
}

//枚举器,yield关键字作用
private IEnumerator WaitForRequest(WWW www)
{
yield return www;

// check for errors
if (www.error == null)
{
Debug.Log("WWW Ok!: " + www.text);
} else {
Debug.Log("WWW Error: "+ www.error);
}
}
}


5. 总结

上述单例介绍简单易用,欢迎大家指正交流。cs脚本文件,请移步csdz的gitbub下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: