Unity3D中的序列化测试

Unity3D中序列化字段常使用[SerializeField],序列化类常采用[System.Serializable],非序列化采用[System.NonSerialized]。

序列化类使用时发现一些区别。测试如下:

(1)

将脚本第一次拖拽到场景中后,运行程序。发现,对类进行序列化后,id,name会保持在代码中写的字段值。

如果我们退出运行,对检视面板的值进行修改,再运行,如下图所示。那么会始终运行检视面板中修改的值!

如果我们退出运行,对代码中的值进行修改,再运行,如下图所示。那么发现print的值还是运行检视面板中的值!如下图所示:

由此可见,序列化类后,显示的数值由检视面板的值确定。脚本中的数值只是在第一次拖拽脚本到游戏对象时有用。

套用C#书上的一句话:序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。

如果不想序列化某个类的字段,有两种方式:第一个就是可以用System.NonSerialized。增加了这个属性的字段不会在检视面板中显示。如下:

第二个方式就是将字段的访问修饰符设置为private或protected即可,如下所示,由于字段为私有或保护,只能在类内或派生的类中访问。这里采用属性getname获取name的值,并print。

一开始我把public ClassToSerialize classSerialize = new ClassToSerialize();的new部分放在Start()中,这时,不管有没有[Serializable],数值都会以类中写入的初始值决定。原因就是:Start()在字段赋予初始值之后运行的。如下所示:

没有运行时,修改id数值:

运行后:

 1 using UnityEngine;
 2 using System.Collections;
 3 using System;
 4
 5 public class test : MonoBehaviour {
 6     public ClassToSerialize classSerialize;// = new ClassToSerialize()
 7     void Start () {
 8         classSerialize = new ClassToSerialize();//这里实例化
 9         print(classSerialize.id + classSerialize.getname);
10     }
11 }
12
13 [Serializable]
14 public class ClassToSerialize
15 {
16     public int id = 120;
17    // [NonSerialized]
18     protected string name = "tongtong1989";
19     public string getname
20         {
21         get { return name; }
22         }
23 }

当然,您也可以不在Start()中实例化,因为已经Serializable了,如下所示:

不过,您不可以把[Serializable]也注释掉,那样的话,类就不能序列化,默认初始化为null,调用字段会提示空引用异常!如下:

时间: 2024-10-12 22:53:53

Unity3D中的序列化测试的相关文章

c# 与 Unity3d 中的序列化

圣典中对于Unity3D的序列化介绍很容易和C#的序列化介绍搞混,做个笔记,方便以后查找. 很多资料算是拾人牙慧. 一.Serializable 序列化 Inherits from Attribute The Serializable attribute lets you embed a class with sub properties in the inspector. Serializable(序列化)属性让你植入一个类用替代内容在Inspector(检视面板) You can use t

Unity3D中xml序列化出错的问题

非继承自MonoBehaviour的类,里面包含Animation,Transform成员,成员以属性形式存在.然后序列化报错 目前没有比较好的解决方法,可以换成函数 不太理解自带的xml序列化为什么没有过滤属性.那么这类问题基本上都是这样造成的

Unity3D中事件函数的运行顺序

Unity3D中脚本的生命周期是依照预先定义好的事件函数的运行流程来演化的,详细流程例如以下: Editor模式下Reset: 当脚本第一次被挂到GameObject上或用户点击Resetbutton时,Reset被调用初始化脚本属性,最经常使用于在Inspector视图中呈现好的默认值. 载入第一个场景First Scene Load: 场景启动时会对场景中的每一个对象运行一遍例如以下事件函数: Awake:游戏启动之前初始化不论什么变量和游戏状态,仅在脚本生命周期中调用一次.不能做协程,St

(转)Unity3d中的碰撞检测

很多时候,当我们的主角与其他GameObject发生碰撞时, 我们需要做一些特殊的事情,比如:子弹击中敌人,敌人就得执行一系列的动作.这时,我们就需要检测到碰撞现象,即碰撞检测.这一篇,我来具体谈谈自己所了解的碰撞检测,希望高手不佞赐教. 首先,我们得明确一点:即产生碰撞信息所需要的条件.事实上,在unity3d中,能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器.这两种方式的应用非常广泛.为了完整的了解这两种方式,我们必须理解以下概念:    (一)碰撞器是一群组件,它包含了

【转】Unity3D中脚本的执行顺序和编译顺序

支持原文,原文请戳: Unity3D中脚本的执行顺序和编译顺序 在Unity中可以同时创建很多脚本,并且可以分别绑定到不同的游戏对象上,它们各自都在自己的生命周期中运行.与脚本有关的也就是编译和执行啦,本文就来研究一下Unity中脚本的编译和执行顺序的问题. 事件函数的执行顺序 先说一下执行顺序吧. 官方给出的脚本中事件函数的执行顺序如下图:  我们可以做一个小实验来测试一下: 在Hierarchy视图中创建三个游戏对象,在Project视图中创建三条脚本,如下图所示,然后按照顺序将脚本绑定到对

【吐血推荐】简要分析unity3d中剪不断理还乱的yield

在学习unity3d的时候很容易看到下面这个例子: 1 void Start () { 2 StartCoroutine(Destroy()); 3 } 4 5 IEnumerator Destroy(){ 6 yield return WaitForSeconds(3.0f); 7 Destroy(gameObject); 8 } 这个函数干的事情很简单:调用StartCoroutine函数开启协程,yield等待一段时间后,销毁这个对象:由于是协程在等待,所以不影响主线程操作.一般来说,看到

【转】简要分析unity3d中剪不断理还乱的yield

在学习unity3d的时候很容易看到下面这个例子: 1 void Start () { 2 StartCoroutine(Destroy()); 3 } 4 5 IEnumerator Destroy(){ 6 yield return WaitForSeconds(3.0f); 7 Destroy(gameObject); 8 } 这个函数干的事情很简单:调用StartCoroutine函数开启协程,yield等待一段时间后,销毁这个对象:由于是协程在等待,所以不影响主线程操作.一般来说,看到

unity3d中的Quaternion.LookRotation

android开发范例中的第二个粒子,是摇杆操作游戏,模式类似于“迷你高尔”,僵尸包围类型的设计游戏. 其中让我注意到这个函数的使用非常特别:Quaternion.LookRotation. 游戏针对两个平台做了输入配置. 在pc平台上控制人物移动用正常的上下左右按键控制,然而人物的旋转就变成了鼠标位置. 正常情况我们希望东西能够根据指定目标方向移动其实用lookat这个函数就可以了.但这个地方用的方法原比lookat来的更加省事儿. 看看他是怎么获得这个角度的: 1 2 3 4 5 6 7 8

Unity3D中关于场景销毁时事件调用顺序的一点记录

先说一下我遇到的问题,我弄了一个对象池管理多个对象,对象池绑定在一个GameObject上,每个对象在OnBecameInvisible时会进行回收(即移出屏幕就回收),但是当场景切换或停止运行程序时场景中如果还有待回收的对象,就会报错,报错显示的信息为,我的对象池GameObject已经被销毁了云云,因为回收的对象我会把他们作为绑定了对象池的GameObject的子级来方便管理. 所以唯一的可能就是脚本方法调用顺序不可控,即不同GameObject的OnBecameInvisible在其它Ga