You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity调用NextLevel时gemsCollected仅短暂增长,无法持久存储数值

解决Unity场景切换时宝石收集数值无法持久化的问题

你当前的代码存在两个核心问题,导致数值无法保留:

  1. 执行顺序错误:先调用NextLevel()加载新场景,会直接销毁当前场景的所有对象,后续的gemsCollected++根本没机会执行。
  2. 变量未做持久化处理:gemsCollected是普通实例变量,场景切换时脚本所在对象被销毁,变量值自然丢失。

下面提供三种不同场景下的解决方案:

方案1:静态变量(快速实现,适合小型项目)

静态变量属于类本身,不会随实例销毁而消失,只要游戏进程不结束就会保留值。修改代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class gemTaken : MonoBehaviour
{
    public GameObject gem1;
    public Transform playerNearCheck01;
    public float playerCheckRadius01;
    public LayerMask playerLayer;
    private bool takenByPlayer; 
    // 将变量改为静态类型
    public static int gemsCollected;

    void Update()  
    {   
        Debug.Log(gemsCollected);
        takenByPlayer = Physics2D.OverlapCircle(playerNearCheck01.position, playerCheckRadius01, playerLayer);

        if (takenByPlayer)
        {
            // 先执行加分,再加载场景
            gemsCollected ++;
            NextLevel(); 
        }
    }

    void NextLevel()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex +1 );
    }
}

其他场景要访问这个值时,直接用gemTaken.gemsCollected即可。但静态变量在游戏重启后会重置,若需要永久保存,参考方案3。

方案2:单例模式(规范全局状态管理,适合中大型项目)

创建一个全局状态管理对象,标记为DontDestroyOnLoad,确保场景切换时不被销毁:

  1. 新建GameManager脚本:
using UnityEngine;

public class GameManager : MonoBehaviour
{
    // 全局单例实例
    public static GameManager Instance;

    public int gemsCollected;

    void Awake()
    {
        // 保证全局只有一个GameManager实例
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}
  1. 修改原gemTaken脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class gemTaken : MonoBehaviour
{
    public GameObject gem1;
    public Transform playerNearCheck01;
    public float playerCheckRadius01;
    public LayerMask playerLayer;
    private bool takenByPlayer; 

    void Update()  
    {   
        Debug.Log(GameManager.Instance.gemsCollected);
        takenByPlayer = Physics2D.OverlapCircle(playerNearCheck01.position, playerCheckRadius01, playerLayer);

        if (takenByPlayer)
        {
            GameManager.Instance.gemsCollected ++;
            NextLevel(); 
        }
    }

    void NextLevel()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex +1 );
    }
}

这种方式可以集中管理所有全局状态(比如生命值、关卡进度等),代码结构更清晰。

方案3:PlayerPrefs(永久保存,重启游戏不丢失)

如果需要关闭游戏后再次打开仍保留收集的宝石数,用PlayerPrefs存储数据:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class gemTaken : MonoBehaviour
{
    public GameObject gem1;
    public Transform playerNearCheck01;
    public float playerCheckRadius01;
    public LayerMask playerLayer;
    private bool takenByPlayer; 
    private int gemsCollected;

    void Start()
    {
        // 游戏启动时读取本地保存的数值,默认值为0
        gemsCollected = PlayerPrefs.GetInt("GemsCollected", 0);
    }

    void Update()  
    {   
        Debug.Log(gemsCollected);
        takenByPlayer = Physics2D.OverlapCircle(playerNearCheck01.position, playerCheckRadius01, playerLayer);

        if (takenByPlayer)
        {
            gemsCollected ++;
            // 将数值保存到本地
            PlayerPrefs.SetInt("GemsCollected", gemsCollected);
            PlayerPrefs.Save();
            NextLevel(); 
        }
    }

    void NextLevel()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex +1 );
    }
}

注意:PlayerPrefs适合存储少量非敏感数据,若需要更安全的持久化,可以考虑用文件序列化或Unity官方的Save System。

内容的提问来源于stack exchange,提问作者Elver David Båshus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:05:41