Unity组件的基类单例模式

来源:互联网 发布:淘宝卖家怎么查访客 编辑:程序博客网 时间:2024/05/20 18:04

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相关APIusing 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下载。

1 0
原创粉丝点击