粉丝83获赞174
![[游戏开发]Unity基础 Unity 资料储存与载入,存读档大解析 #编程 #编程入门 #计算机 #游戏开发 #游戏梦想家计划](https://p3-pc-sign.douyinpic.com/image-cut-tos-priv/ad3710fe14ed9f2b3cfc82878283d6b1~tplv-dy-resize-origshort-autoq-75:330.jpeg?lk3s=138a59ce&x-expires=2079954000&x-signature=PqkbeR4XsuaUm%2BBOyls1Hf7NMmc%3D&from=327834062&s=PackSourceEnum_AWEME_DETAIL&se=false&sc=cover&biz_tag=pcweb_cover&l=202512012116367F4FA2C19541E1F47B5F)
哈喽,大家好,欢迎来到阿空的游戏部,我是阿空,那么这一次要介绍的是 unit 的存档与独档。 好,那么在介绍存档与独档之前呢,我们要先来介绍一下资料的形式以及储存的方式, 那我们可以储存资料的形式有非常多种,第一种是直接储存数值,就是把我的等级,或者把我的攻击力,防御力依序储存在我们的档案里面。 那第二种的话,就是透过序列化的方式,那我们可以把我们的资料序列化成 binary 的形式,或是变成是叉 m l 的格式,或是序列化成 jason 的格式,那当然 我们也可以自定义我们想要的格式,然后那么序列化就是只说呢,我们可以把一个物件变成是一串资料,那么接着是储存的方式,最常看到的当然就是使用 preppress 的方式去做储存。那第二种就是透过外部档案, 那接着呢当然是通过连线的方式去做储存,也就是把我们的数值还有资料储存在 sever 端。 那么准备好了资料,然后我们也决定了要储存在哪边,那中间呢,我们就可以加上加密, 通过加密呢,我们就可以提升我们资料的安全性,减少被修改的可能性。然后那么接着我们来介绍直接储存数值,像是我们有两个变数, 他们分别是阿空,然后等级是一,那直接储存,当然就是把名字跟等级,然后一序存下来,那我们可以去规划自己的储存顺序以及他的样式,然后依次去读取跟写入。 好,那么接着呢,我们要来介绍序列化,什么是序列化呢?就是我们可以把我们所需要的资料变成是一个物件,或者是把物件当做是一个资料,那像这个范例,我们就是把名字跟等级包装在 一个叫做 player data 的资料上面,那么序列化就是把这个物件变成是一串文字的资料。那我们在使用序列化的时候,必须要注意,我们的物件上面必须要写上 see reliable 才能 能够去使用,而且并不是所有的资料都能够被序列化保存下来。那么准备好了物件之后呢,我们就可以决定我们要序列化成什么样的格式,那像是 binary, 那我们把物件序列化成 binary, 就会得到这样子的一个数列。好,那因为它是二进位的格式,所以打开来就会是一个乱码的形式,那么使用 binary 形式的序列化 优点就是他不容易被篡改,那缺点就是他不容易被维护,因为他是属于二进制的档案。那么接着是叉按 l, 那就会像是上面这样子,他就会是一行一行条列下来的一个格式,那他的优点就 就是比较容易去维护,那么缺点就是它的体积会比较大,因为它还多了一些叙述的资料。好,那么接着是 dressen, 那么序列化成绝省,就会得到这样子的一个格式,那绝省的优点就是它的体积比较小,使用起来也是最方便的一种。 那我们序列化成这些文字之后呢,我们就必须要反序列化,就是 descent 来,那么透过反序列化呢,我们就可以把这些文字变成是我们原来的物件, 也就是把这些文字再转换回去我们一开始所使用的这个物件。好,那么接着我们来谈一下储存的方式。那么第一种是 player price, 那么 player price 是什么意思呢?它就是 player preference, 也就是玩家的偏号设定好,那么他所资源的资料形态呢?有以下几种,那一个是 i n t, 就是整数,一个是 float, 就是浮点数,那么一个是 stream, 就是自创。 那么我们来看一下这个 prayer proof 会储存在哪里吧。好,那么我们到 unit 的网站上面就可以查到 prayer proof 的一些资讯。好,那么既然它是 preference, 就代表说它也是可以去做修改的,所以说在储存的时候呢,我们最好还是做一些加密的动作 好,那么在下面呢,我们就可以看到很多的资讯,就是在各个平台上面,他所储存的位置都是不一样的,那么在 windows 呢,是透过注册表来去储存 我们的数值,那各位有兴趣可以看一下里面的路径,那么接着我们就实际的来试试看 prior price 的功能吧。那我这边已经先做好了一个小型的储存脚本, 就是设定了一个文字,那这个文字是用来显示我们的资料用的,然后我们创建了一个 player data, 然后在编辑器里面去做编辑,然后有两个功能,一个是储存,一个是载入 好,然后底下是我们的物件资料。好,那我们就开始吧。那如果我们要使用 player pref 去做储存的话呢,我们就直接打上 player pref, 点 set integer 就可以去储存它的 数值,那当然我们也可以储存自串好,那么需要两个参数,那一个是 key, 一个是 value, 也就是一个 key 会对应到一个 value, 那我们就可以给他一个名称,像是 name, 那 value 的话就可以给他数值,那我们要储存的是 data 的这个数值,那他的名称就是 name 好,那么透过这一行呢,我们就可以把我们的名称储存下来,那载入的话就是使用 player press 点 get dream, 然后我们可以拿 name, 就是把我们的这个 key 的数值给拿回来,那我们这边使用文字去做显示,那我们来看一下效果吧。 然后呢,当我们按下 s 的时候储存完成,然后按下 l 的时候,我们就可以成功的把阿空这个数值给拿回来,那当然这个 level 也是一样的,我们可以使用 i n t 去做存取。 好,那么这边我们就可以使用 player brief 点 set integer, 我们要储存的是 level, 然后使用 data 点 level 好,那么这边我们也可以把 data 的物件给换回来,就是 data 点 name 等于 play pref 点 get stream, 然后是 name, 那后面呢是 data 点 level 等于 player please 点 get integer, 然后 level 好,那透过这个方式我们就可以返回原本的物件,那假设我们把等级变到九十九, 然后当我储存,然后我们把等级改成一,然后当我载入的时候呢,就会发现等级变成了九十九,那这就是 player price 的使用方式。 好,那么接着我们要来介绍透过外部档案来去做存取,那么是使用 c sharp 的 file string 跟 file 的这个 原件呢,来做档案的创建跟读取。提到外部档案,当然就要提到我们的路径,那在我们的应用城市里面呢,有两个路径是比较常使用的,那一个是 application 点 data pat, 那第二个 路径是 application 点 presistent data pass, 那我们可以来看一下。好,那么回到 unity 的文件,那我们就可以看到这个 data pass, 那他们在不同的平台当然会有不同的路径, 但是这个路径呢,都是指向这个应用城市。好,那么第二个是 application 点 好,那么这个 persistent data pass 呢?在 windows 里面会存在 user, 然后 user name, 然后 apple data, 然后 local low, 然后这个公司名称,然后 app 的名称的这个资料夹底下,那它的用意就是说呢,当我如果把整个专案删掉的时候,它的资料还是会存在这个 地方,他不会去被覆盖或者是被删除,那这就是 presistent data pass 的一个好处。好,那么 company 呢?跟 applen 呢?可以在我们的 project satin 去做设定, 然后那我们就实际的来试试看吧,那我们先把这个 prayer price 先删掉。 好,那么首先呢,我们要使用 file stream 来去创建我们的档案,然后 f s 等于 new file stream, 那里面呢,我们要放置的是路径,所以我们就使用 application 点 data pass, 那这边我们先使用 data pass 来做一个测试,那当然我们也可以使用 presistent data pass。 好,那么后面 呢,我们要加上这个档案的位置,就是斜线,然后 saf 点 txt, 那这边我们使用的是文字档,方便我们去做浏览。那后面呢,我们要填上 file mode 点 preact, 因为我们要创建一个新的档案,那这样子我们就制作好了一个档案流。好,那么接着我们要有一个 stream writer 来去撰写我们的文字,然后那就是 s w 等于 new string writer, 那里面呢,我们要放置的是这个档案流,好,那么接着我们就可以使用这个 string writer 来去写一些文字,那就是用 s w 点 right line, 然后 我们要写上 data 点 name, 先写上我们的文字,然后呢我们再去写上我们的等级, 那写完之后呢,别忘记把它关上,就是 s w 点 pro, 然后 f s 点 pro, 然后呢我们先来看一下是不是能够正确的创建我们的档案,好呢?当我们按下开启,然后按下 s, 当储存完之后呢,我们来目录看一下, 我们就可以找到这个 saf 点 p x p 的档案,那打开来就会发现它是阿空,然后一那通过这个方式呢,我们就可以把文字储存到档案里面,那接着 是窄路的部分,那一样是需要一个 file stream, 那这边我们就是使用 open, 因为我们要把档案做开启的这个动作,那么接着我们需要有一个 stream reader, 然后它是这个 file string。 好,那我们就可以使用 s r 点 read line 去做读取的这个动作。那第一个呢是什么?第一个是我们的名字,所以就可以使用 data 点 name 等于 好,那第二个是我们的 level 等于好,那因为它读取出来呢是一个字串,所以我们要把它变成是一个整数,我们就可以使用 i n t 点 past, 然后去把它变成整数。好,那我们来看一下吧,那当我把这个物件呢变成是等级九十九,然后叫做阿空一二三, 那当我开启的时候,我就可以用读取去把我的文字读进来,然后修改成我们的物件,然后呢透过这个方式呢,我们就可以成功的把资料储存在文件里面,然后再从文件里面去取得资料。 好,那么接着我们要介绍的是透过连线储存的方式去储存资料,因为储存在本地的资料很容易受到修改,所以我们就把资料储存在四伏器端, 来提升我们资料的安全性。但是呢,城市还是在玩家的手上,这意味着他还是不安全的,因为 玩家可能去修改里面的城市逻辑,然后导致这个游戏发送错误的资讯到事故器端,所以眼镜到后面呢,我们会把一些敏感的城市逻辑放在事故器上面去做执行, 玩家端的部分我们也会适时的做验证,这样子才能提升整个资料的安全性。好,那么接着呢,我们要来介绍如何透过序列化的方式来去做档案的存取,那这边我们要先来介绍的是 finally。 好,那么首先我们需要有一个 binary formator, 那么我们要引用的就是 system 点 run time, 点 civilization, 点 formator, 然后这边是用 binary 的方式去做饮用。 好,那接着我们还需要有一个文件流,那这边我们使用的是 file 点 open 啊,因为我们不需要一个一个去做撰写,所以我们使用 file 点 open 就可以了,那里面要加的是地址, 然后它的方式 file mod, 点 create。 那么在 binary 的文件里面呢,我们可以自己去修改里面的这个副档名,像是 sav 啊,或是 d a t 都可以啊,或者是你想要取自己的副档名也可以。 好,那接着呢,我们要来使用这个 binary formatter, 然后点 serialize, 那里面呢我们要放置的是 stream, 那这边我们就可以使用 stream 把这个文件流呢给接起来,那我们把 dream 给放进去,那接着呢?我后面要放的是物件,那物件就是 data。 好,那么透过这个方式,他就会直接写到这个文件流里面,那就用 s 点 close, 这样就可以完成我们的剧烈化物件。那在读取的部分呢,我们一样是需要一个 binary formator, 然后一个 dream, 那这边一样改成 open。 好,那这边我们就可以使用 data 等于 b f 点 the serialize, 我们要反序列化,那反序列化里面放的就是文字流,就是 s, 那因为它读取出来之后呢,它没有被定义它的形态,所以这边呢,我们就要强制转型,就是 player data, 那这样子我们就可以把文件里面的资料流呢,变成是我们的 player data 的物件,然后再传回去给原本的这个 data, 那我们来看一下是不是可以正常的读取吧。好,那这边我们先使用阿空,然后等级九十九,那当我们按 s 的时候呢,输出完成,那这边我们把它改成一,然后变成是空,然后再进行游戏,那当我们读取的 之后,就会发现他变成阿空,然后等级是九十九,我们就成功的把资料写进我们的 finally 文件里面了。那我们就来看一下档案啊,就会发现有一个 saf 点 epp 的这个档案, 那我们把它开起来,就会发现他长得就跟我们介绍的是一样的,就会是二进制的档案。 好,那么这样子我们就完成了透过搬运序列化去存取资料的功能了。好,那么接着呢,我们要来介绍的是透过 timel 的方式去做序列化,那首先我们需要引用 system 点 timel, 点 civilization, 那其实大部分的东西都是一样的,那我们把这边变成是叉 m l, 然后 see realize 等于 new c realize, 那这边呢?我们就改成使用 time l 去做序列化,然后那么里面要放置的是 type, 也就是我们物件的形态,所以这边我们就使用 data 点 get type 去拿取 data 的 type。 好,那这边我们可以改成 timel, 方便我们去做观看。 好,那么下面一样,我们把这个 binary formatter 呢改成我们的 timel c realizer, 那么文件也是一样的,那这边改成 timel, 那最底下呢?一样我们使用叉 m l 点 desiri 来去做返去列化,然后把这个文件流串进来,然后返回我 我们的 data。 好,那我们来试一下吧。好,那我们把它变成阿空,然后等级是九十九,那当我们储存的时候 储存完成,那这边我们再做修改,把等级改成一,然后去做读取,那我们就会发现他的等级又变回九十九, 那现在来看一下我们的档案,那找到叉按钮就会长得像这样子, 那当然我们可以去修改里面的引扣顶,因为现在我们会发现这边是问号,问号,但是读取来说他是正常的,那么在名字的部分的话,假设我把阿空变成是空白的,那当我去读取的时候,数值也是可以正常的去做 拿取。好,那么这样子我们就成功的透过叉 m l 的方式去做数值的存取。 好,那么接下来呢,我们要来介绍第三种,也是最好用的一种,就是使用 jason 的方式去做序列化,那我们先把上面的给删掉。 好,那要怎么做呢?我们就使用 jason utility, 然后点 two jason, 那里面就是放我们的物件,就是 data, 这样子我们就完成了,有没有非常的快速呢?好,那透过这个方式,我们会得到一个字串,那我们就印出来看一下吧。 好,那当我们按下 s 的时候呢,它就会是后面这一串的数值,那读 去也是一样的,然后那么这边呢,我们就可以使用这个 player price, 或者是透过 seashot 的文件去储存我们的这一串数列,那我们就使用 player price 吧, set string, 然后去储存里面的字,那我们要给他一个 key, 就是 jason data, 这样子我们就可以存到我们的 preference 里面了, 那后面呢,我们就可以把它反去列化,就是使用 data 等于,然后 player press, 点 get dream, 我们把这个 jason data 给拿出来,然后呢,我们要写上这个 jason 有题的题,然后点 from jason, 就是从 绝省去做读取,然后我们的形态是 playo data, 那后面呢,我们要接的是这个字串,也就是我们把字串拿出来,然后传进去,让他去做返回,返回出来的就是我们原本的物件。哦,是绝省 data, 那我们来看一下吧。好,那么现在我是阿空九十九,等那当我去做执行的时候,我就会把这些资料存进去我们的自创腿托软鼠里面。 好,那当我们按下读取的时候,就会发现阿空跟九十九就跑回来了,那这也是最常用的一个方式,那如果你要比较安全的形式的话呢,那我们也可以直接在这边去加上一些像是 a, e, s 啊,或是其他 的对称式加密,然后把我们加密后的这个资料存进去 player proof 或者是使用嗯 seeshop 的档案进行存取,那就可以得到一个比较安全的资料存档。 好,那么一次介绍了这么多种方式去做档案存取,那就看各位喜欢使用哪一种的资料格式,然后使用哪一种方式去做存取。 好,那么我们这一次关于存档跟独档的介绍就到这里结束啦,感谢各位的收看。我是阿空,我们下次见喽,拜拜。

大家好,今天给大家讲的内容是如何持久化重储数据,通过 unitate。 什么是斋神?斋神他是一种轻量的资料的交换的一种格式,他最大的特点的话就是建字对,这也就导致他便于阅读和处理, 这是我们常见的一个阶层的一个格式。当当前前面的话是 k, 然后通过中间的封号去做处理,然后后边的跟着他的外流数据。 当我们再去处理数据的时候的话,节省的话是用的中括号去做表示的数据和数据之间的,它是通过逗号去做隔开的。需要注意的点的话是由内体中的自带的节省。在处理数据的时候必须 去做序列化。接下来的话我们回到代码里边去做一下,做一下处理。在用的题里边的话,我们创建一个脚本 叫做 unit 再生,创建一个空物体,由内体再生,把脚本去拖动到空物底上,提上双击内容后,我们开始去做内容的处理,然后依旧是我们把我们的书放进来不可,然后书包含的信息有 id, name, author 刚才提到了他必须去做序列化。 处理完成之后的话,接下来的话我们去定义一本书, 完成之后的话,我们把这一本书的内容去转化成一个节省的格式。 如果要去做这件事情的话,我们要用到 unity 里边的一个就节省的一个工具吐节省。接下来的话我们去输出这个内容。第八个点, oh no, 节省。第二兔节省就是把它转化为节省,转化谁 book? 接下来的话我们去运行一下右内腿看一下效果。 因为当前没有重储数据,所以的话是就是只有整数会有一个, 所以我去给他加入一些内容。书名叫母猪的产后护理, 作者是兰陵小小生。好,接下来我们有先看一下效果, 下边的话,你可以看到他把当前我们定义的内容转化成了一个节省的格式。 那么接下来我如果我要处理多个数据的时候, united jason 这边的话,不能够直接去做处理,需要去定一个类,然后去把你要处理的数据通过历史的或者数据的形式去把它包装起来, 然后当前内容的话也需要去做序列化,然后 我这里边要放多本书,通过历史的和数组的结构都可以,然后去把我的 book 放进来。呃, book bookcomp 完成之后的话,我们基于新定义的这个类,然后 做一个处理,完成之后的话,接下来我们再对这个内容去做输出,如果你直接去定义一个历史的话,他是不能够去把内容去做输出的。会有这样的一个问题, 就是当前我用的这个方式,如果有更好的方式的话,你们可以给我留言。好,回到应该题里边的话,然后我们去填入数据,然后去测试一下。 好,接下来我们启动用心看一下效果,这次的话我们把数据内容的话就是就是一个列表性质的内容去做了一个输出。 好,回到当前我们已经就是掌握了基础的使用。接下来的话我们把我们的内容去重储到本地, 然后第一步的话依旧是先处理我们的文件,棉质 处理完成之后的话,我们处理下文件的路径 依旧是把它放到我们的 streamer sex 里边 处理的文件的格式为结实,下步的话我们去教育一下该路,呃,该文件夹是否存在,如果不存在做什么?通过 io 里边的 director 去创建一个文件夹, 创建完成之后的话,接下来的话我们处理我们的数据内容。 string 好,把我们的 books 去转化为 jason, 转化完成之后的话,接下来的话我们就需要把我们的数据去重出起来,用力提 jason 这边的话是不能够直接去重储数据的,所以的话我们通过 io 里边儿的 fill they're right on text 去把内容写入该函数的话,前面是放入文件的路径,后边的话是放入要重组的数据。好,接下来的话我们启动用心看一下效果, 完成之后的话我们刷新一下,刷新完成之后的话得到一个节省。文件好,当前的话我们就可以把我们的数据内容 去通过油内贴里边的再生去重储,为这重储成一个再生的一个结构。刚才的话需要注意点的话就是 就是在重储单数据结果的时候可以直接去做重储,但是必须去做序列化。下个的话就是我们去做了一个重储的一个数组,数组的话需要定一个新类,去把他们 去格格,呃,去那个格在一起,你要说需要定义一个新的类,然后成历史的或者数组的形式, 其实归根到底的话就是我们要对我们的内容去必须去做一个就是序列化。好了,今天的内容就到这了。

大家好,今天给大家讲的内容是如何持久化重组数据通过 csv。 什么是 csv? 它是一种就是逗号分割字,就是把数据通过逗号去做分割。接下来的话我们去看一下, 然后先创建一个文件 test, 创建完成之后的话,我通过逗号去放入一些数据,然后逗号的话使用英文的逗号,其中的话我留几个空档。 数据放完之后的话,接下来的话我们去修改一下这个文件的后缀,修改为 csv, 接下来 的话它会自动识别,去通过能打开 excel 的软件去打开它。接下来的话你会发现数据是分别放在不同的格子里边的,那么以此基于此的话,我们得到了一个结论,就是普通的制服串重储数据是通过逗号以及换行去做处理的, 接下来的话我们就进入代码环节,也就意味着我们在去做做制服处理的时候的话, 让他去在数据和数据之间通过逗号去做隔开每一行数据和每一行数据的话,我们通过反邪恶嗯去让他做换行。接下来的话我们创建工程,创建空物体,创建脚本 csv manager, 双击打开脚本之后进入编辑整个文件的重储的话,我们通过 io 去做处理,所以需要隐约秘密空间 sexycommetrio。 隐约完成之后的话,我们去定义一个 fu 内蒙,我们文件的名字类型为支付串。接下来的话我们依旧是把我们经常看的书去放进去,先定一个类叫做不可,然后书的构成的话有 id name, author。 完成之后的话我们要拿一个利斯特去做管理,为了方便去看到的话,我们需要做训练化处理,接下来的话我们定一个利斯特,然后去对我们的书籍进行管理。 完成之后的话,我们第一步处理文件路径,因为我们在放文件的时候的话,需要放到一个区门塞斯文件夹里, 里面摔的话我们去下一步要去较验路径是呃文件夹是否存在 往下跳, 如果不存在的话我们就创建文件夹, 然后下一步的话我们去重储,重储内容 好,接下来的话我们一步步的去做,实现吹 feel pass。 接下来的话我们去教验一下师傅存在,教验的话通过 通过 directory 去看该文件夹是否包含, 如果他是处于不包含状态的,那我们就创建该文件夹, 创建完成之后的话就确保该文件夹是存在的,那么接下来的话我们去做重储,重储的时候的话,我们用 stream right 去做处理, 然后接下来的话把文件的路径给到他。文件路径改完之后的话,接下来的话我们就可以去写入内容。第一个我们去写入标题, 然后写入的话有 red 和 red light 的,一个是换行,一个是不换行。接下来的话我们用一个换行去做处理,分别里边放入 id, 嗯,然后需要通过逗号去把它们间隔开。 标题有了之后的话,接下来的话我们开始去便利我们的 list belly 每个数据,之后的话,接下来的话我们依旧通过写入标题的方式去写入他。 数据和数据,直接通过逗号去做隔开, 然后里边分别放上 book 的 id name。 完成之后的话,我们最终的话把我们的数据去 这边的话是处理写入数据,写入完成之后的话,我们要把数据的内容去推流到 推送到刘文件中, 推送完成之后的话我们要对这个文件进行关闭, 好,关闭完成之后的话,接下来的话我们去测试一下,然后依旧是我们常看的几本书, 文件的名字叫做 test csv, 然后最近常看的两本书,然后编号幺幺如何养花, 然后作者是作者是。嗯,想想作者是谁了,作者是 作者,作者怎么想不起来了?作者,嗯。兰陵笑笑声, 然后下边的话是水火,然后作者是石男。好,接下来的话我们重储下场景, 接下来的话我们启动一下,看一下效果,启动完成之后的话下边没有报错,然后我们去刷新一下, 刷新完成之后的话他创建了文件夹,同时创建了该文件。接下来的话这边内容的话有些问题,然后并没有去重储进去。接下来的话我们去找一下问题点, 问题的话就是在于刚才提到了一个 read 和 readline 呢?因为它的数据的一行和另外一行的处理的话 是通过换行去需要去做换行,就数据的间隔是通过逗号数据的,换行是通过那个回车反前感恩。 read 和 ready 的话区别就在于他们差了一个。 呃。换好。接下来的话回到这边我们去看一下,这边的话数据已经做了重储了,因为他的字符编码格式的问题,所以的话出现了显示不正确的问题,如果出现该问题的话,接下来的话我处理一下, 找到他,然后接下来我们去修改一下支付编码,可以通过计时本去打开,打开之后的话,然后我们去另充为一下, 另出围之后的话用 utf 杠八去确保这个重储的是没有问题的。接下来的话我们双击打开再看一眼,嗯,那也就是当前这个软 软件再去做解码的时候的话,方式不对,我们换一个软件去打开测试一下。好,当前的话可以看到我们所重储的内容的话是完全没有问题的。 好的,今天的内容就到这了,谢谢大家一见善良。


大家好,我是 michael。 这个视频我们要为我们的背包系统创建我们的物品的数据库了。听到数据库是不是有点头大呢?不过你放心,你知道 michael 一定会讲一些比较简单容易明白的这些小的技巧,所以不卖关子了。这就是我们标题所写的 scriptable objects。 所以什么是 scriptable object 呢?它是跟 mono behavior 一样,是属于一个特殊的类,这个类跟 mono behavior 有一点不一样。如果我们在 api 的手册里查看 scriptable object, 你会发现它写了,它不需要挂载在任何的 game object 上,也就是它不像 mono behavior, 它需要一个物体才可以使用这个代码,所以它可以直接存在我的文件夹当中,而且它可以用来 存储我的数据。看到了吗?存储我的数据,所以它里面也包含一些简单的方法,比如说他也有 destroy in stancy, 包括 uneviable on disable week 这些方法,所以小伙伴们可以看一下这个手册。另外, scriptable object 通常会跟我们的 creatics menu 在一起配合来工作,那听起来有点复杂,我们来简单 举个例子,比如说在我的 project 窗口当中,在空白的位置,按鼠标右键,我们会弹出一个菜单,这个菜单就是我们的 ss menu。 我们可以通过 scriptable object 在里面创建属于一个我自己的分类的菜单来创建一个文件。那创建文件和创建 mono 比黑文的代码有什么不同呢?比如说我创建一个 material, 它是一个素材球, 这个材质球我会改变里边的属性。那么不管我的代码如何来运行,甚至我的游戏启动或者关闭,这些东西都不会消失,而且这个会以一个文件的形式存储在我的项目的文件夹当 当中,所以它是一个文件,用来存储一些数据。另外 monon behavior 需要挂载在一个物品上,比如说我们挂载在我们的 player 上,然后我可以更改里边一些变量的数据,这个数据我是可以通过代码的运行来进行更改,比如说这个速度,比如说碰到什么东西了,我这速度更改了, 但是只要我的游戏一暂停或者停止再进去的时候,他会按照我先前代码中设置的速度,依然不会被改变, 这就是我们没有办法去保存我原有的数据,或者保存我更改的数据。 scripto object 就可以很好的解决这个问题了。话说了这么多,我们一起动手来做一下,你就能明白它有什么奇妙的用处了,这 是一个非常好用的功能,所以我们在我们的 inventory 的文件夹当中,右键新建一个文件夹,我们给它起名叫做 script, 为了用于区分我们, 我给他起名叫做 inventory script, 跟我们的背包系统有关的代码在里边。我们在右键新创建一个 c shop 的脚本,我给他起名叫做 item, 我先创建跟我的物品有关的, 那我希望这个 item 的这个代码用来存储我物品的所有的属性信息,比如说他的名字,他的图片,他有多少个,然后他的一些 information, 所以我们一起来看看如何用 scriptable object 来写这个代码。我们双击打开扣子, 然后在这里我要将 mono behavior 改掉,我不要使用 mono behavior, 我要使用 scriptable object。 使用了 scripto object 之后,我们就不要用这个 start 和 update 的这两个方法了。那么接下来我希望在我的右键的菜单当中来创建属于我的这个 item 的这个选项。所以每 自我选择可以创建一个新的物品,里边能包含一些属性,所以我们会在上面写上一个方法。 一个投文件的方法是 create ss menu, 然后它这里面我们要写上你新创建的这个菜单的文件名,文件夹的路径是什么。 还有每当我创建了那么新的那个文件叫什么名字,所以 file name 等于一个字符型的文件名。比如说你新创建一个东西,这个东西默认的名字是叫什么?我给他起名叫做 new item, 所以作为他的默认的名字逗号隔开后边接上 menu name, 也就是说我右键的菜单他是叫什么名字,所以我给写着等上等于 um inventory 一个斜杠,表示它的紫菜单叫做 new item。 好, 我们先保存这个代码来看看是什么样的效果。回到 unit 当中,我们在空白的位置按鼠标的右键,然后你会看见 create, 这个时候你会发现在最上边有了我们刚才新建的这个菜单了,就是 inventory, 然后里面有我们设新的项目,就叫做 new item, 然后我点击这个 new item, 他会为我创建一个新的叫做 new item 的默认名字。比如说我给他起名字叫做 sword 一把剑,然后你会发现他像一个文件一样在这里存着,我不需要把它挂载到任何的空物体上。接下来我们来给这个物品添加一些属性, 我们继续来写,我希望我这个物品有一些公开的变量,用来存储我不同的物品的属性。比如说,首先我最基础的要有一个物品 的名字,叫做 it name。 另外我希望他有这个物品特殊的图片,所以这里边我们用 sprite, 也就是他渲染的精灵来获得他的 图片,起名叫做 item image。 另外我需要储存我这项物品有几个,因为在背包当中,多个同类物品应该放在一起,所以我们要有一个整形的变量,叫做 item help, 你现在持有多少个?另外我需要 item 的 information, 它的一些描述同样也是字符型的。 好,写到这里以后,我们回到我们的 unity 当中,我们来看一看现在的我的这个 sword, 这把剑的属性就已 已经显示在我的 unny 的窗口当中了,可以看到我,他有名字,有图片,有他有几个,还有他的 information。 所以每一次我右键新创建一个物品,比如说我创建一双鞋, 他都会有这些默认的分类,所以我只要在里面添上这个是斜,然后我给他一个他的默认的图片,我们可以去到我们的 ss 当中,找到我的 free pixel gear。 这里边有一些物品的属性,我只要将他们拖拽过来就可以使用了。比如说我找到这个穗, 然后我添加 image, 可以在这里面找宝剑的话我们用这个,然后斜的话我们也可以用斜的那个, ok, 然后我可以添上一些 information, 他默认只有一个 information。 好,然后在这里面还要给大家介绍一个小的技, 有的时候我的音封面上会非常多,比如说以后我们获得一个很传奇类的物品,下边会有一些描述,甚至是一小段话,所以这个时候一行代码不够我来写,所以我要写多行的时候。这个时候我们在他前面加上一个中国号,里面写上这是一个 text area, 所以如果你搜索 tax area 的话,他后边也可以跟一些参数默认是多少行,所以我只想使用他的默认属性,我就直接保存回到 unny 当中,这个时候你会看到我的 information 这个部分里已经不是一行了,会变成一个文本框,在这里边我可以输入多行的内容来代表他的信息。另外我也可以创建一个布尔值, 因为我们的物品只有两个类型,要么他是一个药水,可以恢复我的生命,要不然他就是装备,是可以备装备上的,所以我给他写上一个 equipped。 好, 所以我用这个属性来确定他是否是一个可装备的。那如果是药水的话,我就不勾选,如果不是药水,我就将它勾选上,代表这是一件装备。所以同样我也将这个宝剑的内容写上。所以请大家留意这个 information 当中,我们也可以写用中文啊,他同样可以识别。 好的,那么我们要将这两个物品也单独保存,而不是存在这个 skips 里边,所以我们将它印起一个文件夹。在 inventory 的文件夹当中,我们新建一个 folder, 叫做 items, 专门用来存储我的这些物品,所以我们去到刚才的文件夹中,将他们两个拽过来。 好的,现在我有了 item 之后,接下来我要创建一个背包,我们另建一个 ctrl 的脚本,就叫做英文 turret, 这个是用来干嘛的?我同样要用 用一个 scriptable object 来创建一个背包的系统,我希望这个背包的系统是一个列表,他将我所有的物品都储存在这个列表当中,这样的话我们就可以每次创建不同的背包。举个例子,以后我们可能需要有玩家的背包, 还有铁匠铺的背包,药水商的背包,或者是你的身体的那个装备的页面显示的那个,也可以称作为一个背包。总之,所有用列表来储存物品的东西,我们都可以创建一个新的背包,所以我们来一起写一下, 同样不需要这些,那就像刚才说的一样,我们要将这个 inventory 变成一个列表,用来存储我的所有的物品。所以我们 public list 这个 list 里边文件的类型,数据的类型就是我们刚才创建的那个 lay, 就是 item, 这样的话能保 保证里边所有的物品都是 item 的 lay, 然后我给它起名叫做 item list, 等于 new list item。 好的,我同样希望他哦,别忘了这后背有小括号,我同样要将它保存在我的 menu 当中,所以同样这里我就快速写了 后边这个部分。请留意,如果我希望他跟刚才的 item 存储在同一个文件夹的目录,我可以直接将这段的名字复制过来, 然后在这里边把后边这个部分改掉,比如说后边就改成 new inventory。 好,我们保存回到 unique 当中。我们来看一下,我们在 inventory 的这个总的文件夹当中 来创建一个新的文件夹,用来起名叫做 new inventory。 里边按鼠标右键点击 create, 然后找到 inventory 的这个紫菜单。我们可以看到我们现在创建了两个菜单的选项,所以我们要创建一个新的背包。新的背包我给它起名就叫做 my back, 因为以后我们可能还会创建其他的刚才我说过的各种各样的背包,所以可以看到这个背包它是一个 list, 是一个列表。所以我希望做的一个效果就是当我的游戏角色碰到世界地图上的一个物品之后,它的 list 里边就加一, 然后这里边包含的项目,我就要将我刚才的这个 item 它属于哪一个类,我就将这个 item 放过来,这样我的背包里就多了这件物品了,所以这就是我创建背包系统的这个逻辑。那么接下来我们一起来动手实验一 下如何来实现这个效果。那我需要先在世界地图上产生一个物品,所以去到我们的素材文件夹当中随便拽一个,比如说刚才我们用了哪一个做的宝剑呢?所以我们将这个物品添加到我们的 helloak 窗口当中, 然后他就可以在我的地面上显示了,你也可以拖拽把它放到一个适当的位置上。接下来我要给他添加一些必要的组件,比如说他需要一个 collider, 我给他添加一个 box collider, ok, 大小没问题。然后我不希望他跟我的游戏角色产生碰撞,我希望他是 trigger, 所以我勾选这个 trigger。 另外我要给他写一个代码,这个脚本的代码希望是应用在所有的物品上,只要触碰判断是游戏角色碰撞了,那么他就会保存到我游戏角色的这个 bag 里面来,所以我们来一起来写一下这部分的内容。所以我去到英文策略 文件夹当中找到 inventory scripts, 在里面右键新建一个脚本,叫做 item on word 在世界地图上的物品。好,我们双击打开,我们来一起写一下这部分的内容。这部分我们就使用 mona behavior 了,接下来我们一起来看看怎么写。我先要获得这个物品的属性, 当我把这个脚本挂在的物品当中,我要知道这个物品是属于哪一个我们创建好的物品的数据,这是两个相当于数据库啊,你这个物品是属于哪个数据库?所以我要生成一个变量来告诉我的 unity 这个东西,它是一个鞋还是一个保健?所以我们要开始生成一个 public item, 就是刚才我们写好的一个类,我把它放大一点,起名叫做 this item 这 这个物品。然后我也要知道背包你的物品应该去到哪一个背包,所以我 public 英文 turret。 刚才我们写好的那个类, 给他起名叫做 player inventory 好,保存回到佣金当中。我们先来确定这两个变量的数据,所以刚才我们写好的这个 item on word, 他应该被放在每一个物品上,所以我们直接将这个 item on word 拖拽放到我的这把键上, 然后他这里需要你给他拖拽赋予两个值,一个是你这个物品的本来的属性是哪一个数据库,另外就是你的玩家的背包是哪一个背包,所以这刚好我们创建好了。第一个就是 item, 这是一把剑,我将这把剑的属性拖拽过来,然后另外 player 的背包是哪一个?我们找到我们的 new inventory 的这个文件夹,当中有一个 my bag, 所以我将 my bag 拖拽过来。最 所以接下来我要实现的代码的方法就是判断游戏玩家是否碰撞到这个物品,碰撞的话,将这把剑放到我的背包当中,我们一起来操作一下。所以刚才我们为这个物品添加了一个可来点,但是一个 on trigger, 所以我们用 on trigger enter to d。 然后接下来我们来写一下里边的内容,判断一下。如果另外一个物品 点 game object 它的 tag。 以前我们用 tag 等于,那这次我们用一个更好的方法叫做 compare tag, 匹配一下他的标签是什么?标签是 player。 这个标签的 player 是在我默认的这个项目当中,我已经给 player 添加好了,就是 type 是 player。 如果你还没选好,或者你用的资 自己的项目,请在这里选好它是 player, 或者填入你对应的那个 tag。 如果是这个 tag 的话怎么办呢?我们要判断要添加一个物品 i'd new item, 可是这个方法我们还没写呢,所以接下来我们来写这个方法。我们生成一个方法, 添加一个新物品。我们要先判断当前的这个物品是否已经在这个利斯特里了,如果在这个利斯特里,那么他加一。如果不在这个利斯特里,他要被添加到这个利斯特里。小伙伴们,还记得我们在 roby 的这个项目中怎么添加一个宝珠到我们的列表当中吗? 我们来判断。如果 player inventory 点 item list, 还记得吗? 刚才我们设置的这个列表的名字叫做 item list, 所以在 item list 当中是否包含 this item? 所以现在我的写法是,如果它里边包含,那么怎么办?有,一开始先用否定来判断, 如果这包包里没有这个物品,那么我要将这个物品添加进来。 this item。 okay, 那接下来我们还要写一个 else, 如果这东西已经在这里面了,我们怎么办呢?我们就要将当前物品的持有度增加一。 this item, there are item help。 还记得吗?我们设置了这个物品的属性,它是一个 scriptual object, 是我们刚才设置好的类。这个类里边有一个物品的持有数,所以我碰撞以后,如果判断它里边没有,那么我加入这个物品。如果已经有了,那么就将这个物品的持有数 加一。另外在上面的这个方法当中,当我碰撞了这物品之后,除了要添加这个物品之后,我也要将当前这个物品毁掉,所以要 destroy game of object。 好啦,我们回到 unity 当中,我们来试验一下。在试验的当中,请留意 my bag 里边要清零,这个物品是没有的。 另外我们留意,我们之前添加的是一把键,这个键的默认持有数是一,然后我们来试一试。我们点击 play, 然后我们要选中我们刚才 他创建的 my bag, 留意这里边的参数的变化。现在我控制游戏玩家,然后我触碰这把剑, 看到了吗?现在这把剑已经被添加到我的列表当中了,同时在画面中已经没有了,这样的话我就成功的将这把剑添加进来了。那我们再试试,看看剑的属性会不会有一些变化。 看,当我停止游戏的时候,我的背包系统数据并没有改变,这把剑仍然被添加进来的,这就实现了存储信息的这个功能了,所以小伙伴们可以发现用 scriptable object 可以存储很多信息,所以你的玩家的属性 h p m p 力量 总结各个方面的属性,甚至一个 boss 他的长的样子,图片是什么。所以用了 scripto object 的话,我相信所有的美术老师也会非常喜欢你,因为他们即便不会用代码, 他们也可以直接将他做好的图片拖拽放到这个位置,那么就可以改变你游戏里面的各种各样的素材了,是一个非常方便的工作。所以 scriptable object 真的是是一个非常棒的一个东西,希望小伙伴们赶紧用起来。好,那接下来我们来试验另外一个, 我还是这把剑,我现在背包里已经有了,而且这把剑的属性是你目前保有一个,那么接下来我在 play 运行一下,我在原有的基础之上,我再次碰撞这把剑,我们来看看这属性的变化。 看,这把剑现在已经有两个了,但是你的背包当中还是只有这一个物品,这一物品现在已经有两件了,这样的话我们就很好的实现了我的背包系统的后台的操作,所以我们创建了我们的数据库,然后也将这个数据库跟我的世界物品连接起来了。接下 下来最重要的一步就是将我的数据库里的东西在我的 slot 里边显示对应的图片,对应的数量,然后让我们的背包可以显示对应的这个物品。 好的,那么这个视频就到这了,小朋友们你们学会了吗?别忘了为我点个赞哦。那我们下个视频,再见吧,拜拜。

大家好,今天给大家讲的内容是如何持久化重储数据,通过艾欧 再去处理这个数据存储。之前的话我先说一个 younute 的一个 get 属性, application streaming or cs pass。 呃,为什么要说这个东西呢?接下来的话,因为我们要去重储文件,再去重储的时候的话,我们需要放到某一个路径下边,假设我们放到 young 里边的工程路径下面, 这个时候的话,在艾德特模式下的话是不会有任何问题的,但是如果是发布之后的话,有的人会把 而赛斯里边的资源去打打包,打到一个包里边,这个包是只读的,也就意味着你的文件是可以读取的,但是在去做修改的时候是不可以的,所以的话接下来的话我们就需要把 他放到一个地方,这个地方的话的这个文件是可以被修改的,可以读也可以去修改,所以的话接下来的话我们把它放到吹门 sis 里边。接下来的话,我们回到优内贴里边去操作下如何去放到吹门 sis 里边。 streaming our size pass, 这个他他是一个特殊文件夹,具体的话 uplocation 点 streamer size, 这个里边我们通过 fc 值二的话去定位一下,看一下他的描述,他说这个路径是 指的这个文件讲接下来的话,因为我记不住怎么去拼,或者有可能拼错,所以的话一般来说我会以这种方式去来复制。接下来的话回到 young 这里边,在 east 下边去创建一个文件讲,然后这个名字必须是这个。接下来的话,这个文件的好处的话是最终的话,我做完我整个操作 之后的话,接下来的话我再去发布,完成之后我们看一下效果。好,接下来创建完成之后,我们之后的文件都会去放到这个里边。 文杰在去做重储的时候的话,第一个的话我们通过 feel right on text 这个方式去去做重储。好,接下来的话我们会到脚本里边。第一的话我们创建一个脚本叫 save manager, 然后先念一个空物体 save manager, 创建完成之后的话,把这个脚本揪上去,然后双击打开脚本,接下来的话我们取 操作一下,在我们输入费用的时候,哎,报错了,怪怪的。因为从一开始就说了我们需要就是通过艾欧,所以的话我们引用一下艾欧的命名空间,艾欧的话是在 system 里边的,艾欧 好,完成之后的话,哎,变色了对不对?那么接下来的话我们去写入一个东西,刚才说了用的是 right or text, 写入的时候的话就要设计到两个东西,第一 pass, 第二内容好,接下来的话我们去写入一下, 我们定一个 street, 为了方便操作的话,我们给他一个 public street name, 然后 stream a few name 吧,因为这个很和里边的某一个冲突了。 few stream 等于 application there stream or death pass, 加上斜杠,加上 fu。 内蒙, 然后我们后缀的话用它来去做处理,然后使用了未负责的局部变量。 局部变了啊,脑残了。因为上面已经定义过了,所以下边的话不需要去做继续的生命,然后接下来的话我们重除起来。呃,这个费用内蒙的话其实指的是完整的整个路路径, 然后接下来的话我们希望放入什么东西?今天我变帅了,今天我又进步了。好,接下来的话我们用心看一下效果,然后 回到右内贴里边,然后给一个名字叫做,呃, test 吧, test。 好,接下来启动看一下效果。 运行完成之后的话,我们需要刷新一下,然后你可以很清楚的看到在 stromerces 别多了一个文件夹,然后双击下这个文件夹。哎,里边就有刚才我们写入的内容,如果说你需要放入 一次放入多个内容的话,就可以去看一下他有没有其他方法。哎,还有一个存在方法,然后我们看一下 f 十二,看看这个存在方法。呃,这个设计到一个编码格式 哎,有个 red online 呢, red 白白的,里边会有其他的一些洗肉的方式,你们可以接下来继续去做一个扩展。接下来的话我要说第二个操作, 通过 feel stream right, 然后这个是需要把放入的内容的话,就是制服串内容转化成 bat, 然后零的话是长度,然后具体的话放入多长的内容去,需要获取这个 bat 的一个长度,接下来我通过他来去做一个操作。 呃,当前这个文件路径我需要再复制一遍,因为就是名字,如果一字的话他可能会被去覆盖掉,所以的话上边的话我把它修改为零,下边的话修改为一。 好,接下来的话我们用另外一个方式去实现下,叫做 fail stream 里边。好,首先再去使用它的时候的话,我们先来一个 fail stream field string, 然后 f s 等于六一个,它里边的话,需要的属性的话,我们通过逗号看一下。呃,它里边的存在比较多,然后我们选一个比较 简单的一些,但是简单可能会反涵盖的一些问题会比较多, 哎,有一个费,哦,好,接下来的话第一个的话我们放入 pass, pass 的话用的是 fio。 好,第二个的话就是关于一个 field model, field model 的话就是对于这个文件你是如何,就是接下来做什么操作,比如说 chrita, 你创建一个新的,比如说是 crate, 创建 open 打开,哎,比如说这个 open one correct, 如果有的话就打 打开,如果没有的话就创建。接下来的话我们用这个模式完成之后的话,接下来我们要去写入什么样的内容?刚才提到了我们要把它转化成一个比比拜他的一个数组, 接下来的话再去做转化的时候,我们需要用到一个 recording, 就是代码的一个格式的一个处理,如果要用它的话,我们就接下来需要沿用一个命名空间 using system their text。 好,接下来的话我们用 recording, 然后制服的话,我们先用 utf 杠八,然后 get bite, 然后把我们需要的中文内容,然后 转化成那个拜他的一个素主,嗯,今天变帅了, 摔脸了,变帅了。好,因为最终的话他返回的是一个拜拜他的一个数组,所以接,呃,所以,所以接下来的话我们直接把他 fail right, 然后把这个内容去丢进去,当然他类似能够实现这些这个东西的方法很多,我们现在直接把它放进去,然后第二个的话就是它的长度 开始偏移,从零开始,然后具体多少个,所以这边的话我们还需要用一下他的乐事,像这种情况的话, 如果多次出现同一个东西使,要使用,使用同一个东西的话,我们就需要把它定义成一个变量, 这样的话会让我们的代码的溶溶余度变得比较低一些,就后续修改的话会比较方便再处理。 failstream, 睡么?这些东西的时候一定要记得最终再去处理,完成之后一定要做一个 clothes 操作,避免就是其他地方在去做使用的时候他还处于被修改状态,导致代码错误。好,接下来的话我们启动回到 youngelty 里边,然后启动看下效果, 然后运行完成之后。哎,这边有个错,然后我们看一下词怎么描述的。呃, fuel, 呃。这边的路径的话,我在做 处理的时候的话是有问题的,所以的话我先看一下这边路径的一个情况。 feels trim, 现在他已经变了这么长了,然后再去做变化的时候,所以会出现问题。那么接下来的话,我把第一个方法去 注册,那就是注视起来,为了方便测试的话,我想一下怎么去弄,哎,直接用一个注视吧,这是第一种方法。好,接下来的话我们看一下第二种方法, 然后 feelstream 刷新一下,刷新完成之后的话,然后我们看一下内容。好,今天,今天变帅, 这是一,今天我又进步了啊,对对,今天变帅。是是这个文档里面的内容。好,然后接下来的话我们再去说下一个东西, stream, right, 然后 right line, 然后里边放入重储的,重储的内容。好,回到代码里边,然后我们继续先把这个注视起来,然后通过斜斜杠心加新斜杠,然后去把内容注视起来, 路径的话我们让它变为二。好,接下来,呃,通过,接下来的话,我们通过 string right 这个,这个去处理东西。上一个的话是 fu, fu fustram。 好,接下来的话我们路径有了,通过 stream reader, 因为我们要去呃,通过 stream reader 去做呃 write, 去做处理 reader 的话,它是用来去做读起的, write 的话是去做写录,写录的,所以的话 stream write sw, 然后等于你有一个它里边的话需要构造函数,有一个 路径,然后有了路径之后的话,我们通过 stream right, 然后接下来的话,我们就可以通过这个,通过他 点里边去写入内容。有 read 和 ready 呢,这个其实很可受,那个比较类似 read 的话是不换好, ready 呢?是换好,我想夸夸自己, 夸一百遍,夸夸自己,为了区分的话夸一百遍,哎,你可以复制一百遍,也可以通过 for, 然后一百。好,接下来把这个去丢进去,让他去执行一百遍,加上爱。 完成之后的话,接下来我们要做一个 sw 点 克洛斯,同样的他也需要去做一个操作。接下来的话我们测试一下我们的内容, 好关闭右脑推,启动,启动完成之后刷新一下 什么。呃,这个没有改,把零 给覆盖了,所以的话我要把它变为二。呃,接,接下来先看一下这个零。好,这个的话就是刚才去把内容去重塑起来。从一开始我一直在聊的一个东西就是追梦,而塞斯这个东西,接下来我演示一下它的作用, 如果要演示他的话,我们就需要做发布,因为他的发布通过 field beyond setting, 然后添加要发布的场景内容,然后当前我是 pc 平台,所以的话点击贝尔的,然后先建一个贝尔的文件夹,然后选择文件 发布,完成之后的话他会给你打开,然后回到对特里边,当前 可以看到一个睡眠而 sex 的文件,这个里边的话就是我所放的这些内容。这个文件夹的内容是可被读写的,其他的内容的话可能会放到 resource 里边,或者其他的地方,比如说关卡信息会放放到雷我林 以及利沃林对应的资源里边。这个这这个东西它是一个 redo 类的,它是一个只读的,就是不可去被修改的,所以的话如果你去没有把东西放到区门赛室里边,也就只能读,写入信息的时候是有问题的。好,今天的内容就到这了,谢谢大家。 hey, kidona you see yes sir。



你要悄悄把家,然后惊艳所有人, nice。