You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity2D游戏三星评分系统:关卡选界面星级显示及最高星级保留求助

这问题我之前做2D关卡游戏的三星评分系统时也踩过坑,核心就是两个关键点没做好:一是没给每个关卡分配独立的存储键,导致数据互相覆盖;二是没做星级高低的判断,随便就更新数据。我给你拆解下具体的实现思路和代码示例,都是实际项目里用过的方案:

解决思路与实现步骤

1. 给每个关卡设置独立的PlayerPrefs存储键

你之前数据被覆盖的根本原因,应该是用了同一个通用键(比如"StarCount")存储所有关卡的星级,导致新关卡的数据直接覆盖旧关卡的。解决办法很简单:给每个关卡的星级分配唯一的存储键,比如采用"LevelStar_关卡编号"的命名规则(比如关卡1对应"LevelStar_1",关卡2对应"LevelStar_2"),这样每个关卡的数据就完全独立,不会互相干扰了。

2. 关卡完成后的星级更新逻辑

当玩家完成关卡、计算出新星级后,先读取该关卡已记录的旧星级,只有当新星级高于旧星级时,才更新PlayerPrefs的数据。这样就能保证高星级不会被低星级覆盖,符合你想要的“只保留最高星级”的需求。

代码示例(Unity C#)

// 假设这是关卡完成后的处理函数,currentLevel是当前关卡编号,newStar是本次获得的星级(1-3)
public void OnLevelCompleted(int currentLevel, int newStar)
{
    // 先校验星级的合法性,避免非法值存入
    if (newStar < 1 || newStar > 3)
    {
        Debug.LogError("星级值必须在1-3之间,请检查计算逻辑");
        return;
    }

    // 拼接当前关卡的存储键
    string starStorageKey = $"LevelStar_{currentLevel}";
    // 读取已有的星级,默认值0表示从未完成过该关卡
    int oldStar = PlayerPrefs.GetInt(starStorageKey, 0);

    // 仅当新星级更高时,才更新存储数据
    if (newStar > oldStar)
    {
        PlayerPrefs.SetInt(starStorageKey, newStar);
        PlayerPrefs.Save(); // 强制写入磁盘,避免意外退出导致数据丢失
        Debug.Log($"关卡{currentLevel}星级更新为{newStar}星");
    }
    else
    {
        Debug.Log($"本次获得{newStar}星,不高于已记录的{oldStar}星,无需更新");
    }
}

3. 关卡选择界面的星级展示逻辑

在关卡选择界面初始化时,遍历所有已解锁的关卡,读取对应键的星级数据,然后根据星级数显示对应的点亮星星(比如3星就点亮3颗,1星就点亮1颗)。

代码示例(Unity C#)

// 关卡选择界面的初始化函数
public void InitLevelSelectUI()
{
    // 假设你的游戏总共有15个关卡,可根据实际数量调整
    int totalLevels = 15;

    for (int level = 1; level <= totalLevels; level++)
    {
        // 找到对应关卡的UI按钮(假设按钮命名为"LevelBtn_1"、"LevelBtn_2"等)
        GameObject levelButton = GameObject.Find($"LevelBtn_{level}");
        if (levelButton == null) continue;

        // 获取按钮下的星星Image组件(假设每个按钮有3个星星子物体)
        Image[] starImages = levelButton.GetComponentsInChildren<Image>();
        if (starImages.Length != 3)
        {
            Debug.LogWarning($"关卡{level}的按钮星星数量不对,请检查UI结构");
            continue;
        }

        // 读取该关卡的星级数据
        string starStorageKey = $"LevelStar_{level}";
        int starCount = PlayerPrefs.GetInt(starStorageKey, 0);

        // 根据星级设置星星的显示状态(点亮用黄色,未点亮用灰色)
        for (int i = 0; i < 3; i++)
        {
            // i从0开始,第0个是第一颗星,所以i < starCount时点亮
            starImages[i].color = i < starCount ? Color.yellow : Color.gray;
            // 也可以用enabled属性控制显示:starImages[i].enabled = i < starCount;
        }
    }
}

额外注意事项

  • 关卡解锁逻辑:如果你的游戏有“必须完成前一关才能解锁下一关”的规则,可以在InitLevelSelectUI函数里同时处理关卡的解锁状态(比如未解锁的按钮置灰、不可点击)。
  • 数据重置:如果需要单独重置所有关卡的星级(而不是清除所有PlayerPrefs数据),可以写一个遍历函数,删除所有以"LevelStar_"开头的键。
  • 跨平台兼容性:PlayerPrefs在不同平台的存储位置不同,但Unity已经做了封装,直接调用即可,无需额外处理。

内容的提问来源于stack exchange,提问作者Jibril

火山引擎 最新活动