Unity中如何修改布尔值并在按钮点击后永久生效实现关卡解锁
问题原因
- 你当前定义的布尔变量是挂载在场景对象上的脚本成员变量,场景切换时原场景的对象会被自动销毁,变量值自然会丢失
- 你在
Start()方法中每次加载场景都会强制把所有关卡解锁状态重置为false,就算变量不销毁也会被覆盖为初始值 - 没有做本地持久化存储,就算解决了跨场景保留的问题,重启游戏后进度也会全部丢失
解决方案
方案1:使用PlayerPrefs实现永久存储(推荐,完全符合永久保存的需求)
Unity内置的PlayerPrefs工具可以把数据存在本地磁盘,卸载游戏前数据都不会丢失,修改后的代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class MainButtons : MonoBehaviour { private bool level2Ready; private bool level3Ready; private bool level4Ready; private bool level5Ready; void Start() { // 场景加载时从本地读取已保存的解锁状态,无存档时默认返回false level2Ready = PlayerPrefs.GetInt("level2Ready", 0) == 1; level3Ready = PlayerPrefs.GetInt("level3Ready", 0) == 1; level4Ready = PlayerPrefs.GetInt("level4Ready", 0) == 1; level5Ready = PlayerPrefs.GetInt("level5Ready", 0) == 1; } public void Level1Map() { // 原代码用!取反会导致重复点击反复切换解锁状态,直接设为true更符合关卡解锁逻辑 level2Ready = true; // PlayerPrefs没有bool类型,约定用1代表true、0代表false存储 PlayerPrefs.SetInt("level2Ready", level2Ready ? 1 : 0); PlayerPrefs.Save(); // 立即写入本地,避免意外退出丢失进度 SceneManager.LoadScene(0); } public void Level2Map() { if (level2Ready == true) { level3Ready = true; PlayerPrefs.SetInt("level3Ready", level3Ready ? 1 : 0); PlayerPrefs.Save(); SceneManager.LoadScene(4); } } }
调试时如果需要清空测试进度,可以调用
PlayerPrefs.DeleteKey("level2Ready")删除单条存档,或调用PlayerPrefs.DeleteAll()清空所有存档。
方案2:跨场景保留对象(仅支持跨场景不丢失,重启游戏进度会清空)
如果不需要永久存储,只需要切换场景时变量不丢失,可以给脚本挂载的对象添加过场不销毁标记:
- 在脚本中新增
Awake方法,添加不销毁标记:
void Awake() { DontDestroyOnLoad(gameObject); }
- 删除
Start方法中给所有levelReady变量赋值false的代码,避免重复加载场景时覆盖已经解锁的状态
注意:该方案需要保证整个游戏运行周期内只有一个该脚本的挂载对象,否则会出现多个重复对象导致状态错乱。
内容的提问来源于stack exchange,提问作者Aarav chandrasekar
相关产品推荐
相关产品推荐

