Unity3d的单例及场景间的数据传递

来源:互联网 发布:晓军判卷软件 编辑:程序博客网 时间:2024/05/17 23:12

           单例是场景间切换时传递数据的最常见的方式之一,在unity中,很多方法被封装,有时候感觉不知道从何处看起,只能从官方文档上去根据功能找类了。个人感觉u3d可视化太过强烈,许多自定义的一些功能似乎让人无从下手,当然也可能是自己水平不够,不太熟悉。比如说场景间的数据传递,在cocos2dx时,我一般会在director里边创建一个单例Interface,用以游戏中的从数据库读取玩家信息,关卡信息,场景间的数据同步等;要么就是在场景间切换的时候直接用带参数的构造函数实现,在u3d就不用说了,场景一般是直接在界面上创建了,切换场景时也只是简单的一句 Application.LoadLevel(scene);,没法在另一个场景创建时传递数据,因为它的创建场景函数是这样的:

// 摘要:         //     Create a new scene.        [WrapperlessIcall]        public static void NewScene();

因而只好用单例去实现了:

            关于单例也很多种实现形式,参考了网上一些别人的方法,自己实践整理出三种较为便捷的方法,比较简单


方法一:纯c#单例,这个单例正常是不需要使用unity的接口和方法,当然,如果要读取文件用它的也是更方便

using UnityEngine;using System.Collections;//用以存放数据测试用的结构体public struct Tollgate_Date{  public  int index;  public   int playerhealth;}public class MyInterface/* : MonoBehaviour*/{    private  static MyInterface myinterface = null;    public Tollgate_Date[] date = new Tollgate_Date[10];    // Use this for initializationvoid Start () {}   public  static MyInterface getInstance()    {        if(myinterface==null)        {            myinterface=new MyInterface();            myinterface.init();        }        return myinterface;    }    public void init()     {                for (int i = 0; i < date.Length;i++ )        {           date[i].index = 1;           date[i].playerhealth = 1;        }           }// Update is called once per framevoid Update ()     {}}
这个方法,就不能再继承基类MonoBehaviour了,继承之后它默认需要挂在在一个对象身上,所以入过不给对象,那么将赋值不了,myinterface一直为空。这样只需要在第一个场景任意一个object的脚本中初始化下就行了:MyInterface.getInstance();




方法二:手动创建一个对象挂载

</pre><pre name="code" class="csharp">using UnityEngine;using System.Collections;public class MyDate : MonoBehaviour {        private static MyDate mydate = null;    public Tollgate_Date[] tollgatedate = new Tollgate_Date[10];    public static GameObject obj;// Use this for initializationvoid Start () {}    public static MyDate getInstance()    {        if(mydate==null)        {            obj = new GameObject("MyDate");//创建一个带名字的对象            mydate = obj.AddComponent(typeof(MyDate)) as MyDate;            mydate.init();            DontDestroyOnLoad(obj);        }        return mydate;    }    void init()    {        for (int i = 0; i < tollgatedate.Length; i++)        {            tollgatedate[i].index = 1;            tollgatedate[i].playerhealth = 1;        }    }// Update is called once per framevoid Update () {}}
 
使用方法同方法一,仅仅在脚本中创建一个对象,而这个对象因为DontDestroyOnLoad函数将一直不会被释放,同时再次执行时也因为非空而保证不会再创建

其中

mydate = obj.AddComponent(typeof(MyDate)) as MyDate;
</pre><pre name="code" class="csharp">通过底层可以看到意思是添加一个名称为className的组件到游戏物体,把这个单例对象和GameObject对象关联起来。

方法三:对象方法

using UnityEngine;using System.Collections;public class TestInstance : MonoBehaviour {    private static TestInstance testinsatnce = null;    public Tollgate_Date[] tollgatedate = new Tollgate_Date[10];// Use this for initializationvoid Start ()     {}    void Awake()    {        if (testinsatnce == null)        {            testinsatnce = this;            testinsatnce.init();            //            DontDestroyOnLoad(gameObject);          }        else        {            Destroy(gameObject);        }    }    public static TestInstance getInstance()    {        return testinsatnce;    }    void init()    {        for (int i = 0; i < tollgatedate.Length; i++)        {            tollgatedate[i].index = 1;            tollgatedate[i].playerhealth = 1;        }    }// Update is called once per framevoid Update () {}}
这个方法与第二个方法最大区别就是它是在场景中建立一个GameObject,把脚本挂载上去,而不是通过手动创建关联实现,在这里该对象在别处使用时,通过getinstance来取得当前的单例对象。



2 0
原创粉丝点击