Unity 3d 保存高分错误

Posted

技术标签:

【中文标题】Unity 3d 保存高分错误【英文标题】:Unity 3d Saving high score bug 【发布时间】:2021-04-09 12:14:44 【问题描述】:

我创建了一个简单的游戏,玩家在每个关卡中收集积分,一旦关卡完成,它将显示总高分。我最近学会了如何使用玩家偏好来保存,并且我能够存储玩家在每个特定关卡中的高分。

这是玩家完成关卡时的图片:

这是它的代码:

 void Update()


    int tScore = PlayerPrefs.GetInt(SceneManager.GetActiveScene().name, 0);//it is adding the points with the highscore again for some reason 
    scoreDisplay.text = "TOTAL POINTS: "+ PlayerController.count.ToString();//display score 
    timeDisplay.text = "TIME LEFT: " + FindObjectOfType<TimeController>().timeText.text;//display remainder time 
    scorePoints = PlayerController.count;
    if (FindObjectOfType<TimeController>().minutes != 0)
    
        timePoints = (FindObjectOfType<TimeController>().sec + 60)/2;
    
    else
    
        timePoints = FindObjectOfType<TimeController>().sec/2;
    
    highScore = timePoints * scorePoints;
    highScores.text = "HIGH SCORE: " + highScore;

    if (tScore <= highScore)
    
        PlayerPrefs.SetInt(SceneManager.GetActiveScene().name, highScore);
    


我正在保存整个场景,以便保存特定级别的高分。我要做的第一件事是使用“GetInt”作为 tScore 获取玩家之前从同一级别获得的先前高分,或者如果没有,则默认为零。然后简单地通过取 scorePoints(我从代码中的另一个类“PlayerController.count”获得)并将其乘以您可以在上面的代码中看到的剩余时间来计算高分。然后我将 highScore 与同一级别的前一个 highscore (tScore) 进行比较,如果它更高,它将覆盖为该级别的新 highScore。

这段代码大部分时间都可以工作,但由于某种原因,有时,已经计算出的那个场景的 highScore 会再次加上分数(以上图为例,最高分是 368,但是当我使用GetInt,它再次添​​加分数,意思是(368 + 16 = 384)成为高分(覆盖之前的高分)这是错误的。有人能告诉我这是什么问题吗?

【问题讨论】:

Update() 在每一帧中被调用(一遍又一遍地做同样的事情)。您只想在加载场景时执行此操作,因此将其移至 Start()。 我做不到,如果我做,它根本不计算,如果只是显示所有内容为零(意味着总分:0,剩余时间:00:00,高分:0) 这个“关卡完成脚本”是在游戏对象上与“游戏”一起说的,还是这个脚本本身加载到场景中?我猜它是和游戏一起的,然后我们必须确保它在游戏完成之前没有被调用/启动。例如,一旦完成,您就可以从主游戏循环中调用此脚本。 脚本在画布中,玩家必须与 endtrigger 发生碰撞,该触发器将调用 gamecontrol,然后调用此脚本,激活面板 我同意@AndersBjerin 的观点,你可能应该想办法在 lvl 完成后触发一次代码。但除此之外,这行可能是错误的highScores.text = "HIGH SCORE: " + highScore;,因为highScore 可能低于tScore,在这种情况下,我猜你想打印tScore,因为它包含更高的值。 【参考方案1】:

好的,我会尽力给出答案。请注意,我可能误解了您想要的内容。无论如何,我会创建一个简单的 MonoBehaviour,例如“ShowScore.cs”,它可以放置在场景中的任何位置(所以为什么不在画布上)。

using UnityEngine;

public class ShowScore : MonoBehaviour

    public UI.Text scoreDisplay;
    public UI.Text timeDisplay;
    public UI.Text highScores;
  
    public void GameOver()
    
        string sceneName = SceneManager.GetActiveScene().name;
        int currentHighScore = PlayerPrefs.GetInt(sceneName, 0);
        TimeController timeController = FindObjectOfType<TimeController>();
    
        int scorePoints = PlayerController.count;
        int seconds = timeController.sec + timeController.minutes * 60;
        Debug.Log("timeController.sec: " + timeController.sec.ToString());
        Debug.Log("timeController.timeText.text: " + timeController.timeText.text);
        int timePoints = (int)(seconds/2f);
        int score = timePoints * scorePoints;

        scoreDisplay.text = "TOTAL POINTS: "+ scorePoints.ToString();
        timeDisplay.text = "TIME LEFT: " + seconds.ToString(); 
    
        if (score > currentHighScore)
        
            PlayerPrefs.SetInt(sceneName, score);
            highScores.text = "HIGH SCORE: " + score.ToString();
        
        else
        
            highScores.text = "SCORE: " + score.ToString() + " (the HIGH SCORE is " + currentHighScore.ToString() + ")";
        
    

一旦触发结束触发器,我将调用函数 GameOver()。祝你好运!

【讨论】:

我已经尝试过你的代码(它比我的更简洁哈哈),它似乎正在工作。您之前看到我的问题是它正在工作,但有时已经计算出的高分会再次加上分数。您的代码似乎与我的不同(除了整洁之外),我没有使用统一更新函数,而是调用了一个创建的函数。所以我想知道问题是否出在 update() 函数本身 只要 PlayerController.count 和 timeController.sec 是稳定的,你每帧都更新显示应该没关系......所以这是一个好问题。我的直觉告诉我,这可能是一个舍入错误。我应该像“/2f”一样在“/2”之后添加一个f,或者在前面放一个(float),并在计算时使用float。在手机上,所以我看到整个代码有点问题 - 试试看:)。 我没有使用浮点数,因为我希望高分是一个整数。同样当我尝试它时,PlayerPrefs.SetInt() 有一个错误,它说它无法从 float 转换为 int 高分使用int是完全可以的,我认为用户不喜欢十进制数...但是,一旦您进行除法或使用浮点数,您可能会遇到四舍五入关闭“错误”(从某种意义上说,它不是真正的错误,它可能只是“看起来”很奇怪 - 特别是如果我们显示四舍五入但使用小数计算的值), timeController.sec 是否返回浮点数或整数,是吗与 timeController.timeText.text 字符串一样吗?我将更新我的答案并添加一些有用的调试语句。 非常感谢大家的回复,真的帮了我哈哈。至于四舍五入的“错误”,是的,有一些问题。 timeController.sec 返回一个 int。它是相同但不同的格式(即timeController.sec = 18,timeController.timeText.text = 0:18),而如果它超过1分钟(即timeController.sec = 18,timeController.timeText.text = 1:18 )

以上是关于Unity 3d 保存高分错误的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D日常开发Unity3D中使用数据类保存数据,持久保存数据数据存放在跨场景调用数据类

Unity3D日常开发Unity3D中使用数据类保存数据,持久保存数据数据存放在跨场景调用数据类

(Unity3D) 保存/加载玩家库存

Unity 3D 之Playerprefs

Unity3D中,如何把图像文件保存为数组并通过输入键盘信息调用?

三句话搞定Unity3d内新建Txt并保存数据