【转】Unity3d的单例及场景间的数据传递
http://blog.csdn.net/zy19940906/article/details/47724387
单例是场景间切换时传递数据的最常见的方式之一,在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 initialization
- void 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 frame
- void 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 initialization
- void 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 frame
- void 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 initialization
- void 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 frame
- void Update () {
- }
- }
这个方法与第二个方法最大区别就是它是在场景中建立一个GameObject,把脚本挂载上去,而不是通过手动创建关联实现,在这里该对象在别处使用时,通过getinstance来取得当前的单例对象。
【转】Unity3d的单例及场景间的数据传递的更多相关文章
- WinForm登陆:窗体间的数据传递
1. 登陆逻辑 FrmMain 为主窗体(启动窗体) FrmLogin 为登陆窗体 在“主窗体”中使用ShowDialog()方法显示“登陆窗体”,并通过“登陆窗体”的DialogResult告知“主 ...
- C#不同窗体间通信,数据传递
在一个项目中,很多时候都需要在窗体间进行数据传递和通信,最觉见的是父子窗体之间的数据传递,比如登录ID,各个窗体都需要知道.有很多文章都写了这方面的问题,提出很多优秀的方法,鄙人不才,搜了一些资料之后 ...
- iOS:控制器间的数据传递
在iOS开发中遇到的控制器间的数据传递主要有两种情况:顺传递与逆传递.顺传递是指数据的传递方向和控制器的跳转方向相同(如图1):逆传递是指数据的传递方向和控制器的跳转方向相反(如图2).这里分别介绍这 ...
- 封装MySQL的单例,连接数据库并对数据进行增删改查操作
单例: 一个类只能有一个对象 应用场景:多次请求数据库只需要一个连接对象. 实现:三私一公 1.私有的静态属性用来保存对象的单例2.私有的构造方法用来阻止在类的外部实例化3.私有的__clone阻止在 ...
- hive、sqoop、MySQL间的数据传递
hdfs到MySQL csv/txt文件到hdfs MySQL到hdfs hive与hdfs的映射: drop table if exists emp;create table emp ( id i ...
- React Native移动开发实战-3-实现页面间的数据传递
React Native使用props来实现页面间数据传递和通信.在React Native中,有两种方式可以存储和传递数据:props(属性)以及state(状态),其中: props通常是在父组件 ...
- fragment间的数据传递
今天我将要讲的是fragment间的数据是如何进行传递的.这里我将举个简单的例子. 首先要有个MainActivity,它托管了MainFragment,而MainFragment又托管了DatePi ...
- vue组件间的数据传递
父组件向子组件传递数据 在 Vue 中,可以使用 props 向子组件传递数据. App.vue HelloWorld.vue 在子组件部分: 如果需要从父组件获取 logo 的值,就需要使用 p ...
- Liferay7 BPM门户开发之40: Form表单的Action到Render的数据传递
在Form提交后的变量,很多情况是要展现在jsp页面中,这时Action到Render的变量传递就非常有用. 例如,您在数据库中添加了学生的详细信息. 为了实现这一需求,先创建Form表单(学生的细节 ...
随机推荐
- Intel&amd
- C++之RAII惯用法
http://blog.csdn.net/hunter8777/article/details/6327704 C++中的RAII全称是“Resource acquisition is initial ...
- 在PHP中读取二进制文件
很多时候,数据并不是用文本的方式保存的,这就需要将二进制数据读取出来,还原成我们需要的格式.PHP在二进制处理方面也提供了强大的支持. 任务 下面以读取并分析一个PNG图像的文件头为例,讲解如何使用P ...
- 输出流缓冲的意义 何时缓冲 Stdout Buffering
From : https://eklitzke.org/stdout-buffering 译者:李秋豪 大多数编程语言默认提供了i/o缓冲特性,因为这会使得输出更加有效率.这些缓冲功能大都是默默工作& ...
- 【luogu P3608 [USACO17JAN]Balanced Photo平衡的照片】 题解
题目链接:https://www.luogu.org/problemnew/show/P3608 乍一看很容易想到O(N^2)的暴力. 对于每个H[i]从i~i-1找L[i]再从i+1~n找R[i], ...
- es6之Object扩展及内部属性的总结
对象扩展: 1.Object.is(A,B) :比较两个值是否相等,取代===运算:只要值相等代表相等:其中NAN和NAN相等:+0和-0不相等: 2.Object.assign(target,sou ...
- Solr7部署报错:java.lang.NoSuchMethodError: javax.servlet.ServletInputStream.isFinished()Z
错误信息: Servlet.service() for servlet [default] in context with path [/solr] threw exception [Filter e ...
- 1269: [AHOI2006]文本编辑器editor
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5269 Solved: 2037[Submit][Status][Discuss] Descript ...
- JavaScript 资源大全中文版
我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-javascript 是 sorrycc 发起维护的 JS 资源列表,内容包括:包管理器.加 ...
- ecshop里提出来的js常用函数
目录 Utils.js jquery.listTable.js 使用例子: ecshop里提出来的js常用函数 Utils.js /* $Id : utils.js 5052 2007-02-03 1 ...