UI的制作
首先,我们建一个新的场景把他命名为Scoring,在Scoring场景导入积分面板资源25.3(资源下载放在置顶了) 并设置渲染摄像机,在游戏结束时我们将切换到这个场景。
配置好将看到如下界面,资源来自bili up阿严Dev
其次,制作button按钮即返回主菜单功能,只需在Scoring UI ——Scoring Screen——Right Panel——Button Container内创建一个button就行了。
最后,将Scoring Screen里的Canvas取消掉。并将资源26.0里的New High Score Screen导入到Scoring UI下,并添加两个button,一个代表提交,一个代表取消。同理对New High Score Screen的Canvas属性进行取消。
我们将得到如下场景配置
如下效果,这里俺自由发挥了下。。。。
脚本的编写
对Scoring UI添加c#脚本书写以下代码,并一对一的将SerializeField导入。脚本主要功能,如果玩家破了纪录,仅展示New High Score Screen ——Canvas,玩家选择输入名字后点击提交后将取消New High Score Screen ——Canvas,激活Scoring Screen——Canvas的同时更新排行耪,如没有破纪录,直接激活Scoring Screen——Canvas。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoringUIController : MonoBehaviour
{
[Header("== SCOREING SCREEN")]
[SerializeField] Canvas scoringScreenCanvas;
[SerializeField] Text playerScoreText;
[SerializeField] Button buttonMainMenu;
[SerializeField] Transform highScoreboardContainer;
// Start is called before the first frame update
[Header("== HIGH SCORE SCREEN==")]
[SerializeField] Canvas newHighScoreScreenCanvas;
[SerializeField] Button buttonCancel;
[SerializeField] Button buttonSubmit;
[SerializeField] InputField playerNameInputField;
void Start()
{
Cursor.visible = true;//显示鼠标光标
Cursor.lockState = CursorLockMode.None;
if (ScoreManager.Instance.HasNewHighScore)
{
ShowNewHighScoreScreen();
}
else
{
ShowScreenCanvas();
}
buttonMainMenu.onClick.AddListener(OnButtonMainMenuCliked);
buttonSubmit.onClick.AddListener(OnbuttonSubmitClicked);
buttonCancel.onClick.AddListener(HideNewHighScoreScreen);
}
private void ShowNewHighScoreScreen()
{
newHighScoreScreenCanvas.enabled = true;
buttonCancel.Select();
}
// Update is called once per frame
void Update()
{
}
private void ShowScreenCanvas()
{
scoringScreenCanvas.enabled = true;
//显示玩家得分,如果没有个属性自己想办法添加,这里本文是float属性的
playerScoreText.text = DeliverManager.Instance.GetPointSum().ToString();
buttonMainMenu.Select();
//更新高分排行榜
UpdateHighScoreLeaderboard();
}
//返回主菜单函数,点击设置Scoring的Canvas为空并返回主菜单没有主菜单自己做一个空白的也行,或许没有这个功能也行自己想办法
private void OnButtonMainMenuCliked()
{
scoringScreenCanvas.enabled = false;
//单纯的切换场景的封装,没有的话我放在备注代买里了
Loader.Load(Loader.Scene.MainMenuScene);
}
private void HideNewHighScoreScreen()
{
newHighScoreScreenCanvas.enabled = false;
ScoreManager.Instance.SavePlayerScoreData();
ShowScreenCanvas();
}
//更新排行榜
private void UpdateHighScoreLeaderboard()
{
var playerScoredList = ScoreManager.Instance.LoadPlayerScoreData().list;
for (int i = 0;i< highScoreboardContainer.childCount;i++)
{
var child = highScoreboardContainer.GetChild(i);
child.Find("Rank").GetComponent<Text>().text = (i+1).ToString();
child.Find("Score").GetComponent<Text>().text = playerScoredList[i].score.ToString();
child.Find("Name").GetComponent<Text>().text = playerScoredList[i].playerName;
}
}
private void OnbuttonSubmitClicked()
{
if (!string.IsNullOrEmpty(playerNameInputField.text))
{
ScoreManager.Instance.SetPlayerName(playerNameInputField.text);
}
HideNewHighScoreScreen();
}
}
分数的存取JSON格式、排序
首先,作为读取文件我们先编写一个SaveSystem类代码如下:
using System.IO;
using UnityEngine;
//删除文件,保存文件,读取文件
public static class SaveSystem
{
public static void Save(string saveFileName, object data)
{
var json = JsonUtility.ToJson(data);
var path = Path.Combine(Application.persistentDataPath, saveFileName);
try
{
File.WriteAllText(path, json);
#if UNITY_EDITOR
Debug.Log($"Successfully saved data to {path}.");
#endif
}
catch (System.Exception exception)
{
#if UNITY_EDITOR
Debug.LogError($"Failed to saved data to {path}. \n{exception}");
#endif
}
}
public static T Load<T>(string saveFileName)
{
var path = Path.Combine(Application.persistentDataPath, saveFileName);
try
{
var json = File.ReadAllText(path);
var data = JsonUtility.FromJson<T>(json);
return data;
}
catch (System.Exception exception)
{
#if UNITY_EDITOR
Debug.LogError($"Failed to load data from {path}. \n{exception}");
#endif
return default;
}
}
public static void DeleteSaveFile(string saveFileName)
{
var path = Path.Combine(Application.persistentDataPath, saveFileName);
try
{
File.Delete(path);
}
catch (System.Exception exception)
{
#if UNITY_EDITOR
Debug.LogError($"Failed to delete {path}. \n{exception}");
#endif
}
}
public static bool SaveFileExists(string saveFileName)
{
var path = Path.Combine(Application.persistentDataPath, saveFileName);
return File.Exists(path);
}
}
然后对于分数管理我们创建ScoreManager脚本,这个脚本是可持续单例模式,编写脚本如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
public class ScoreManager : PersistentSingleton<ScoreManager>
{
[System.Serializable]
public class PlayerScore
{
public float score;
public string playerName;
public PlayerScore(float score, string name)
{
this.score = score;
this.playerName = name;
}
}
[System.Serializable]
public class PlayerScoreData
{
public
List<PlayerScore> list = new List<PlayerScore>();
}
readonly string SaveFileName = "player_score.json";
private string playerName = "No Name";
//玩家得分是否创了记录,我这得分是 DeliverManager.Instance.GetPointSum()这儿对应要修改
public bool HasNewHighScore => DeliverManager.Instance.GetPointSum() > LoadPlayerScoreData().list[9].score;
/*public bool HasNewHighScore(float score)
{
return score > LoadPlayerScoreData().list[9].score;
}*/
public void SetPlayerName(string newName)
{
playerName = newName;
}
public PlayerScoreData LoadPlayerScoreData()
{
PlayerScoreData playerScoreData = new PlayerScoreData();
if (SaveSystem.SaveFileExists(SaveFileName))
{
playerScoreData = SaveSystem.Load<PlayerScoreData>(SaveFileName);
}
else
{
while(playerScoreData.list.Count < 10)
{
playerScoreData.list.Add(new PlayerScore(0, playerName));
}
SaveSystem.Save(SaveFileName, playerScoreData);
}
return playerScoreData;
}
public void SavePlayerScoreData()
{
PlayerScoreData playerScoreData = LoadPlayerScoreData();
//填入游戏总分数和玩家名字,名字默认NoName,如玩家有输入则修改
playerScoreData.list.Add(new PlayerScore(DeliverManager.Instance.GetPointSum(), playerName));
//这里排序算法可以尝试其他,如冒泡排序
playerScoreData.list.Sort((x, y) => y.score.CompareTo(x.score));
SaveSystem.Save(SaveFileName, playerScoreData);
}
}
备注脚本
只想运行Loader类的实现如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public static class Loader
{
//单纯切换场景枚举
public enum Scene
{
MainMenuScene,
GameScene,
LoadingScene,
Scoring
}
private static Scene targetScene;
public static void Load(Scene targetScene)
{
Loader.targetScene = targetScene;
SceneManager.LoadScene(Scene.LoadingScene.ToString());
}
public static void LoaderCallback()
{
SceneManager.LoadScene(targetScene.ToString());
}
}
标签:得分,void,System,玩家,Unity,score,path,using,public
From: https://blog.csdn.net/qq_54376778/article/details/139268077