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

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

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

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

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

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

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

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

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

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

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

其中

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

方法三:对象方法

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

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

【转】Unity3d的单例及场景间的数据传递的更多相关文章

  1. WinForm登陆:窗体间的数据传递

    1. 登陆逻辑 FrmMain 为主窗体(启动窗体) FrmLogin 为登陆窗体 在“主窗体”中使用ShowDialog()方法显示“登陆窗体”,并通过“登陆窗体”的DialogResult告知“主 ...

  2. C#不同窗体间通信,数据传递

    在一个项目中,很多时候都需要在窗体间进行数据传递和通信,最觉见的是父子窗体之间的数据传递,比如登录ID,各个窗体都需要知道.有很多文章都写了这方面的问题,提出很多优秀的方法,鄙人不才,搜了一些资料之后 ...

  3. iOS:控制器间的数据传递

    在iOS开发中遇到的控制器间的数据传递主要有两种情况:顺传递与逆传递.顺传递是指数据的传递方向和控制器的跳转方向相同(如图1):逆传递是指数据的传递方向和控制器的跳转方向相反(如图2).这里分别介绍这 ...

  4. 封装MySQL的单例,连接数据库并对数据进行增删改查操作

    单例: 一个类只能有一个对象 应用场景:多次请求数据库只需要一个连接对象. 实现:三私一公 1.私有的静态属性用来保存对象的单例2.私有的构造方法用来阻止在类的外部实例化3.私有的__clone阻止在 ...

  5. hive、sqoop、MySQL间的数据传递

    hdfs到MySQL csv/txt文件到hdfs MySQL到hdfs  hive与hdfs的映射: drop table if exists emp;create table emp ( id i ...

  6. React Native移动开发实战-3-实现页面间的数据传递

    React Native使用props来实现页面间数据传递和通信.在React Native中,有两种方式可以存储和传递数据:props(属性)以及state(状态),其中: props通常是在父组件 ...

  7. fragment间的数据传递

    今天我将要讲的是fragment间的数据是如何进行传递的.这里我将举个简单的例子. 首先要有个MainActivity,它托管了MainFragment,而MainFragment又托管了DatePi ...

  8. vue组件间的数据传递

    父组件向子组件传递数据 在 Vue 中,可以使用 props 向子组件传递数据.   App.vue HelloWorld.vue 在子组件部分: 如果需要从父组件获取 logo 的值,就需要使用 p ...

  9. Liferay7 BPM门户开发之40: Form表单的Action到Render的数据传递

    在Form提交后的变量,很多情况是要展现在jsp页面中,这时Action到Render的变量传递就非常有用. 例如,您在数据库中添加了学生的详细信息. 为了实现这一需求,先创建Form表单(学生的细节 ...

随机推荐

  1. Codeforces Round #327 590B Chip 'n Dale Rescue Rangers(等效转换,二分)

    t和可到达具有单调性,二分就不多说了.下面说下O(1)的做法,实际上是等效转换,因为答案一定存在,如果在t0之前,那么分解一下 直接按照只有v计算就可以了.反过来如果计算的结果大于t0,那么表示答案在 ...

  2. go语言,第三方包相对路径导入包引起的问题及解决方案(goquery)

    对go语言而言,跟踪init很显然包有且仅有一次被导入的可能. 但是重复引用了goquery包,后编译出现问题 项目涉及相关目录 ├── main.go└── parse    └── parse.g ...

  3. 关于SIGSEGV错误及处理方法

    http://blog.csdn.net/brace/article/details/1102422 今天编程遇到了SIGSEGV错误,比较困惑,所以找了些资料,总结一下: (1)官方说法是: SIG ...

  4. 51nod——1086、1257背包问题V2(多重背包二进制拆分转01) V3(分数规划+二分贪心)

    V3其实和dp关系不大,思想挂标题上了,丑陋的代码不想放了.

  5. 1072: [SCOI2007]排列perm

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3000  Solved: 1875[Submit][Status][Discuss] Descript ...

  6. 项目10.2-企业级自动化运维工具---puppet详解

    1.认识puppet 1.1 引入 puppet是什么,咱们先不用专业的名词解释它,咱们先描述一些工作场景,看明白这些工作场景,自然会知道puppet是什么. (1)场景一: 管理员想要在100台服务 ...

  7. eclipse中使用git上传项目

    eclipse中使用git上传项目 先需要上传到本地仓库 先找到此选项打钩 再如下 再添加的属性则可以自动填充邮箱和密码 之后 右键选择import 点击找到git 选中 下一步  如果没有找到git ...

  8. 动态规划:HDU1789-Doing Homework again

    Doing Homework again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  9. (WPF&Silverlight)可空,null

    可空类型即引用类型 不可空类型即值类型 可空,即可 = null; 注意点:在不可null类型后加?就可以为null int? i = null; int?的范围大于int(可null的大于不可为nu ...

  10. MySQL之索引(四)

    压缩索引 MyISAM使用前缀压缩来减少索引的大小,从而让更多的索引可以放入内存中,这在某些情况下能极大地提高性能.默认只压缩字符串,但通过参数设置也可以对整数做压缩. MyISAM压缩每个索引块的方 ...