• 【转】Unity3d的单例及场景间的数据传递


      http://blog.csdn.net/zy19940906/article/details/47724387

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

    [csharp] view plain copy
     
    1. // 摘要:   
    2.         //     Create a new scene.  
    3.         [WrapperlessIcall]  
    4.         public static void NewScene();  

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

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

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

    [csharp] view plain copy
     
    1. using UnityEngine;  
    2. using System.Collections;  
    3. //用以存放数据测试用的结构体  
    4. public struct Tollgate_Date  
    5. {  
    6.   public  int index;  
    7.   public   int playerhealth;  
    8. }  
    9.   
    10. public class MyInterface/* : MonoBehaviour*/  
    11. {  
    12.     private  static MyInterface myinterface = null;  
    13.     public Tollgate_Date[] date = new Tollgate_Date[10];  
    14.       
    15.     // Use this for initialization  
    16.     void Start () {  
    17.       
    18.     }  
    19.    public  static MyInterface getInstance()  
    20.     {  
    21.         if(myinterface==null)  
    22.         {  
    23.             myinterface=new MyInterface();  
    24.             myinterface.init();  
    25.   
    26.         }  
    27.         return myinterface;  
    28.     }  
    29.     public void init()   
    30.     {  
    31.           
    32.         for (int i = 0; i < date.Length;i++ )  
    33.         {  
    34.            date[i].index = 1;  
    35.            date[i].playerhealth = 1;  
    36.         }  
    37.          
    38.     }  
    39.     // Update is called once per frame  
    40.     void Update ()   
    41.     {  
    42.       
    43.     }  
    44. }  

    这个方法,就不能再继承基类MonoBehaviour了,继承之后它默认需要挂在在一个对象身上,所以入过不给对象,那么将赋值不了,myinterface一直为空。这样只需要在第一个场景任意一个object的脚本中初始化下就行了:MyInterface.getInstance();

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

    [csharp] view plain copy
     
    1. </pre><pre name="code" class="csharp">using UnityEngine;  
    2. using System.Collections;  
    3.   
    4. public class MyDate : MonoBehaviour {  
    5.       
    6.     private static MyDate mydate = null;  
    7.     public Tollgate_Date[] tollgatedate = new Tollgate_Date[10];  
    8.     public static GameObject obj;  
    9.     // Use this for initialization  
    10.     void Start () {  
    11.       
    12.     }  
    13.   
    14.     public static MyDate getInstance()  
    15.     {  
    16.         if(mydate==null)  
    17.         {  
    18.   
    19.             obj = new GameObject("MyDate");//创建一个带名字的对象  
    20.             mydate = obj.AddComponent(typeof(MyDate)) as MyDate;  
    21.             mydate.init();  
    22.             DontDestroyOnLoad(obj);  
    23.         }  
    24.         return mydate;  
    25.     }  
    26.     void init()  
    27.     {  
    28.         for (int i = 0; i < tollgatedate.Length; i++)  
    29.         {  
    30.             tollgatedate[i].index = 1;  
    31.             tollgatedate[i].playerhealth = 1;  
    32.         }  
    33.     }  
    34.     // Update is called once per frame  
    35.     void Update () {  
    36.       
    37.     }  
    38. }  
    [csharp] view plain copy
     
    1.   
    
    

    使用方法同方法一,仅仅在脚本中创建一个对象,而这个对象因为DontDestroyOnLoad函数将一直不会被释放,同时再次执行时也因为非空而保证不会再创建

    其中

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

    方法三:对象方法

    [csharp] view plain copy
     
    1. using UnityEngine;  
    2. using System.Collections;  
    3.   
    4. public class TestInstance : MonoBehaviour   
    5. {  
    6.     private static TestInstance testinsatnce = null;  
    7.     public Tollgate_Date[] tollgatedate = new Tollgate_Date[10];  
    8.     // Use this for initialization  
    9.     void Start ()   
    10.     {  
    11.     }  
    12.     void Awake()  
    13.     {  
    14.         if (testinsatnce == null)  
    15.         {  
    16.             testinsatnce = this;  
    17.             testinsatnce.init();  
    18.             //  
    19.             DontDestroyOnLoad(gameObject);    
    20.   
    21.         }  
    22.         else  
    23.         {  
    24.             Destroy(gameObject);  
    25.         }  
    26.     }  
    27.     public static TestInstance getInstance()  
    28.     {  
    29.         return testinsatnce;  
    30.   
    31.     }  
    32.     void init()  
    33.     {  
    34.         for (int i = 0; i < tollgatedate.Length; i++)  
    35.         {  
    36.             tollgatedate[i].index = 1;  
    37.             tollgatedate[i].playerhealth = 1;  
    38.         }  
    39.     }  
    40.     // Update is called once per frame  
    41.     void Update () {  
    42.       
    43.     }  
    44. }  

    这个方法与第二个方法最大区别就是它是在场景中建立一个GameObject,把脚本挂载上去,而不是通过手动创建关联实现,在这里该对象在别处使用时,通过getinstance来取得当前的单例对象。

  • 相关阅读:
    jQuery事件委托
    jQuery-事件面试题
    jQuery事件处理
    文档—CUD
    jQuery练习
    jQuery-筛选
    5. Longest Palindromic Substring
    340. Longest Substring with At Most K Distinct Characters
    159. Longest Substring with At Most Two Distinct Characters
    438. Find All Anagrams in a String
  • 原文地址:https://www.cnblogs.com/mimime/p/6798957.html
Copyright © 2020-2023  润新知