【问题标题】:Insert player name with new high score插入具有新高分的玩家姓名
【发布时间】:2020-11-16 17:23:49
【问题描述】:

我正在创建一个带有评分系统的游戏,但目前玩家的名字不包括在他们的高分中。这个想法是玩家可以在游戏结束屏幕出现并获得新的高分后添加他们的名字。

最初系统只会保存一个高分,但现在保存了 5 个高分,这些高分将在其他地方的表格中调用,我也希望在该表格中显示玩家姓名。

我对 C# 不太熟悉,所以不知道如何合并这种用户输入,所以我很高兴听到可用的选项。

这是我的评分系统代码:

public class ScoreManager : MonoBehaviour
{
public Text scoreText;
public Text hiScoreText;
public Text gameOverScoreText;

public float scoreCount;
public float hiScoreCount;

public float distance;

public float pointsPerSecond;

public bool scoreIncreasing;

//create array for last 5 high scores
float[] highScores = new float[5];

//create list for scores
public List<float> ScoreHistory;


// Start is called before the first frame update
void Start()
{
    //if there is a high score, the game will register it, otherwise it will be 0 - this is for one score
    /*if (PlayerPrefs.HasKey("HighScore"))
    {
        hiScoreCount = PlayerPrefs.GetFloat("HighScore");
    }*/

    //obtain last 5 scores
    ScoreHistory = LoadScoresFromPlayerPrefs(5);

    // Set the current high score to be the highest score in the player history - if there is no high score saved, high score will be 0
    if (ScoreHistory.Count > 0)
    {
        hiScoreCount = ScoreHistory[0];
    }
    else
    {
        hiScoreCount = 0;
    }

}

// Update is called once per frame
void Update()
{
    if (scoreIncreasing)
    {
        //adding points every frame/update => but shows decimals
        scoreCount += pointsPerSecond * Time.deltaTime;
        //scoreCount += Vector3.Distance(transform.position, camera.position);
      
    }

    if(scoreCount > hiScoreCount)
    {
        hiScoreCount = scoreCount;           

        //saves value called high score and the hiScoreCount value - not used if saving more than one score
        //PlayerPrefs.SetFloat("HighScore", hiScoreCount);
    }

    //adding text to score
    //Mathf.Round rounds scoreCount and hiScoreCount to nearest whole
    scoreText.text = "Score: " + Mathf.Round(scoreCount);

    hiScoreText.text = "High Score: " + Mathf.Round(hiScoreCount);

    gameOverScoreText.text = "Your Score: " + Mathf.Round(scoreCount);

}

//function which needs a number value to take in - can be used more than once
public void AddScore(int pointsToAdd)
{
    //adding points to score
    scoreCount += pointsToAdd;

}

// Save the current score to the list of scores, and then write them to the player prefs
public void SaveCurrentScore()
{
    ScoreHistory.Add(scoreCount);
    //put scores in order
    ScoreHistory.Sort();

    
    for (int i = 0; i< ScoreHistory.Count; i++)
    {

        //key is the name of the value being stored
        var key = "High Score " + i;

        //value is what is being stored (i.e. the high scores) => ScoreHistory is being used as each score is being saved
        var value = ScoreHistory[i];

        //high scores are being saved using PlayerPrefs
        PlayerPrefs.SetFloat(key, value);
      
    }
    
}

// Loads the scores from the player prefs and returns them in a list of floats
private List<float> LoadScoresFromPlayerPrefs(int maximumNumberOfScoresToLoad)
{
    //no visibility modifiers - this is a local variable
    List<float> LoadScores = new List<float>();

    //loop will run once per score
    for (int i = 0; i < maximumNumberOfScoresToLoad; i++)
    {

        //key is the name of the value being stored
        var key = "High Scores " + i;

        //will return value of the key if there is one, otherwise will return default value of 0.0
        //PlayerPrefs.GetFloat(key);

        var score = PlayerPrefs.GetFloat(key);
        LoadScores.Add(score);
    }

    return LoadScores;
 }
}

【问题讨论】:

  • 您需要一个播放器类,这样您就可以将每个播放器分开。播放器类需要名称和分数列表。然后你需要一个 List 并将所有玩家添加到列表中。

标签: c# unity3d user-input


【解决方案1】:

如果你想让用户输入一个名字,你要么必须使用

  1. Unity 的 UI 系统(例如 input field)或
  2. 自己编写代码(例如,完成后观察Input.inputString),我只建议您有类似旧街机的东西,只允许 3 个字符。

在这两种情况下,您都需要能够通过可检测的提交(例如返回键或专用 UI​​ 按钮)检测用户输入的结束。之后,您可以将其与相应的点一起存储。

要将点和名称绑定在一起,只需添加一个包含两者的结构

public struct ScoreData {
    public float Score { get; set; }
    public string Name { get; set; }
}

并将其用于您的ScoreHistory

public List<ScoreData> ScoreHistory;
private string playerName; // store the name input by player here
...
public void SaveCurrentScore()
{
    ScoreHistory.Add(new ScoreData { Score = scoreCount, Name = playerName });
    //put scores in order
    ScoreHistory = ScoreHistory.OrderBy(s => s.Score).ToList();


    for (int i = 0; i < ScoreHistory.Count; i++)
    {

        //key is the name of the value being stored
        var scoreKey = "High Score " + i;
        var nameKey = "High Score Playername " + i;

        //value is what is being stored (i.e. the high scores) => ScoreHistory is being used as each score is being saved
        var value = ScoreHistory[i];

        //high scores are being saved using PlayerPrefs
        PlayerPrefs.SetFloat(scoreKey, value.Score);
        PlayerPrefs.SetString(nameKey, value.Name);

    }

}

【讨论】:

  • 为什么不使用 PlayerPrefs.SetString(...) 将它们添加到 PlayerPrefs 中,就像使用乐谱一样?
  • 好的,所以我现在有一些东西,只有当玩家通过输入他们的名字提交他们的分数时才能保存分数。但是,新名称会替换分数表上的旧名称。有没有办法防止以前的数据被覆盖,还是我必须提交不同的分数和名称?
  • 既然你只想保存前5个分数,为什么覆盖以前的数据会打扰你?
  • 不是那个,困扰我的是被覆盖的播放器的名字。假设玩家一提交分数,然后玩家二在同一设备上玩游戏并提交分数;即使玩家一提交了自己的名字和分数,玩家二的名字也会覆盖他们的名字,看起来好像他们也达到了玩家一的分数。这就是我想要避免的。
  • 您想为每个玩家存储 5 个分数(以便每个玩家都可以跟踪自己的技能提升情况)吗?或者你想存储一个包含 5 个分数的列表,其中有 5 个不同玩家达到这些分数的可能性(以便当前玩家将他的技能与其他玩家的技能进行比较)?
猜你喜欢
  • 2017-06-07
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
相关资源
最近更新 更多