草庐IT

【Unity】场景切换保留数据的解决方案

br0sy 2023-07-28 原文

PlayerPrefs 类

简介

        PlayerPrefs类是 Unity 给我们提供的内置的数据存储类,是以键值对的形式存储数据的(具体可以去Unity官网的文档中看:UnityEngine.PlayerPrefs - Unity 脚本 API),这里存储的数据是独立于游戏的,因此可以实现场景切换的数据保留。这里我的理解是,在场景切换的时候,我们的内存条会读取下一个场景,抛弃当前场景,因此所有变量会重置,比如人物的血条,当场景切换时,人物被重新加载,是无法保留血条数据的,所以我们不能将数据存在内存中,而是要把数据存到硬盘中,下面的静态函数就是做到了这一点,读取也是从硬盘中读取到内存中。(理解可能有误,欢迎批评指正)

常用的一些静态函数

使用实例

场景:我们假设这样一个熟悉的例子——角色血条(假设角色血量最高为100)。在这里,要求是在切换场景时,下一场景的初始血量要和上一场景的最后血量相等,简单来说,就是血量这个数据在场景之间可以传递。那么我们就用上面 Unity 给我们提供的 API 来写一下代码。

直接使用:如果你对这个场景的实现已经有了一定的想法,那么就直接用上面的静态方法就可以,我也将这个例子中最核心的代码写在下方。

// 存入数据(第一个参数 Blood 是你自己取的,主要目的就是标识数据,方便提取;第二个参数是在这个场景中的变量blood)
// 这里因为血量是 Int 型,所以用SetInt,如果是其他类型就要调用不同的函数哦!这样我们就将内存中的数据成功存入了硬盘中!
PlayerPrefs.SetInt("Blood",blood);
// 读取数据(上面存的这个标识,就可以拿到下面来读取数据了,我们就将硬盘中的数据成功拿到了内存中!)
blood = PlayerPrefs.GetInt("Blood");

--------------------------------------------------------分割线-------------------------------------------------------

浅浅分析一下:如果你对这个例子还没有什么思路,那我们就来简单分析一下这个场景。

1、什么时候需要保存血量?

答:当切换场景时需要保存血量,或者当我们保存退出一个游戏时。(当然保存退出不止要保存血量,还有各种角色的各种信息,所以这里我们只写第一种情况——切换场景保存血量)

2、什么时候需要读取血量?

答:当场景切换时,或者当游戏加载时需要读取血量,并且我们要将血量显示到 UI 上。

好的,那么我们就来写脚本吧。

首先是我们的角色脚本 PlayerMove:

private int blood; // 血量暂存变量
private Text Blood; // UI Text变量,用来显示信息到界面上
​
// Start 函数在每次场景切换时都会重新执行一次,那么场景切换后血量就会重新读取一次
void Start() {
    // 拿到 Unity 中的 BloodText(我这里只是一种方法,方法是很多的)
    Blood = GameObject.FindGameObjectWithTag("BloodText").GetComponent<Text>();
    // 进入游戏实例化对象后读取
    blood = PlayerPrefs.GetInt("Blood");
    // 显示到UI上
    Blood.text = blood.ToString();
}
​
// 接下去我们就可以根据角色的动作对 blood 进行各种操作了

现在产生了一个问题:我们刚上来就使用了 PlayerPrefs.GetInt("Blood") ,但是如果从来没有执行过 PlayerPrefs.SetInt("Blood"); 怎么办呢?这里我提供一个解决方案。

首先作为一个游戏,会有一个主菜单,主菜单上有个按钮,<开始新游戏>,那么我们就可以给这个开始新游戏的按钮的脚本上加上Set的代码,来进行游戏的血条初始化。代码如下:

// 按钮上挂载的方法
public void StartNewGame() {
    // 载入时初始化 Blood
    PlayerPrefs.SetInt("Blood", 100);
    // 加载场景
    SceneManager.LoadScene("Scene0");
}

好的解决了这个问题,那么接下去就是最后一步,场景切换时保存当前血量了。

场景切换的讲究

场景切换这边,其实也有点讲究,比如我们设计的是一个闯关类游戏,那么我们的场景就是线性的,就是一关接着一关,没有选择的余地;如果我们设计的是一个探索类游戏,那么一个场景可以根据选择的不同,跳转至多个场景,甚至可以回跳场景。那么可想而知,第二种情况会比第一种情况复杂很多,那么在这里我就讲一下两种情况的实现思路,并着重写一下第一种情况下场景切换保存血量的代码,如果同时也想要看第二种情况下保存数据,可以参考我的另一篇博客:【Unity】一个场景跳转到多个场景的解决方案

线性场景下的血量保存:

思路:由于场景的切换是线性的,所以我们无需考虑场景的名称等,只需要编排好场景的顺序(也就是索引),每次遇到门的时候,我们就跳转到下一个索引场景即可。那么这串代码,我们就可以写入角色 PlayerMove 的脚本中。

PlayerMove:

// 在上面PlayerMove代码的下面写
// 下面这个函数就是 当角色碰到门时,就保存血量,并加载下一个场景
private void OnTriggerEnter2D(Collider collision) {
    if(collision.tag == "Door") {
        // 获取当前场景的对象
        Scene scene = SceneManager.GetActiveScene();
        // 保存血量
        PlayerPrefs.SetInt("Blood", blood);
        // 加载下一个场景( 本场景的索引+1 就是下一个场景)
        SceneManager.LoadScene(scene.buildIndex + 1);
    }
}

非线性场景下的血量保存:

思路:如果场景切换是非线性的,那么我们就要去使用场景的名称来进行精准的切换了,因此把代码写在 角色的身上是不现实的,那将会造成角色身上代码的堆积,因此我们需要将代码挂载到门的上面,从而实现不同的门,使用不同代码,加载进不同的场景,具体的实现代码可以参考我上面给出的文章。

有关【Unity】场景切换保留数据的解决方案的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby-on-rails - Ruby on Rails with Haml - 如何从 erb 切换 - 2

    我正在从erb文件切换到HAML。我将hamlgem添加到我的系统中。我创建了app/views/layouts/application.html.haml文件。我应该只删除application.html.erb文件吗?此外,仍然有/public/index.html文件被呈现为默认页面。我想创建自己的默认index.html.haml页面。我应该把它放在哪里以及如何使系统呈现该文件而不是默认索引文件?谢谢! 最佳答案 是的,您可以删除任何已转换为HAML的View的ERB版本。至于你的另一个问题,删除public/index/h

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  5. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  8. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  9. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  10. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

随机推荐