首页 > 其他分享 >Unity玩家本地得分排名系统的制作

Unity玩家本地得分排名系统的制作

时间:2024-05-29 10:02:15浏览次数:25  
标签:得分 void System 玩家 Unity score path using public

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

相关文章

  • 软件构造思想在Unity项目中的实践举例(2)
    本文系笔者在学习软件构造课程期间所写,不保证通用性和正确性,仅供参考。目录前言Spec撰写与TestFirst防止表示泄漏重载与修饰结语一、前言详见上一期软件构造思想在Unity项目中的实践举例(1),这是一个早早就选好题但因为懒才拖到现在的系列。我将介绍我的一个正在工作中......
  • Unity屏幕分辨率适配方法
    Unity屏幕分辨率适配方法在Unity中实现屏幕分辨率适配,可以使用以下几种方法:1.使用CanvasScaler创建Canvas:在Unity编辑器中创建一个Canvas,它将自动添加一个CanvasScaler组件。设置CanvasScaler:选择Canvas对象,找到CanvasScaler组件,并设置其属性:UIScaleMode:选......
  • Unity性能优化——其他合集
     本节将详细介绍在收集性能分析数据之前不应使用的优化。可能的原因是这些优化在实现时非常耗费精力,在提高性能的同时可能会损害代码整洁性或可维护性,或者解决的可能仅仅是特定的范围内才存在的问题。多维数组与交错数组如该 StackOverflow文章所述,遍历交错数组通常比遍历多......
  • Unity 2022无法安装Entities 1.2.0 Package的解决方法
    会出现如下的错误提示:本质原因是国内版的Unity2022使用了自己的Package加速CDN:packages.unity.cn,而不是官方的packages.unity.com。而这个CDN更新了Entities的几个包到1.2.0,却没有将依赖的com.unity.collections更新到2.4.0。诡异的是CDN里却有2.4.1。所以解决方法就来了:直......
  • 完成一个猜数字游戏进入程序后提示用户输入 要猜的数字其他人输入时,提示数字大了,或者
    print("---------------欢迎来到猜数字游戏------------")print("游戏规则:每位玩家只能猜5次,5次猜错结束程序,显示正确的数字后,重新开始")count=0whilecount<=5:num=int(input("请输入你要猜测的数字:"))system_num=random.randint(1,100)ifnum>system_num:......
  • 使用 Unity Barracuda 和 Compute Shader,Yolov2 进行高效物体识别
    前言通过整合UnityBarracuda和TinyYOLOv2模型,开发者可以在Unity中实现高效的实时物体识别功能。这种技术不仅可以增强游戏和应用的交互性,还可以应用于虚拟现实(VR)和增强现实(AR)等创新项目中,为用户创造更加沉浸和动态的体验。TinyYOLOv2模型概述TinyYOLOv2是YOLO(You......
  • Unity A*寻路算法
    前言:为什么要使用A*寻路算法,不直接使用unity自带的Navigation组件呢?灵活性高:A*算法允许开发者根据具体游戏需求调整和优化算法实现,比如通过改变启发式函数来适应不同的地图和寻路条件。Unity的Navigation组件虽然强大,但在一些特殊场景或需要高度定制的路径计算中可能不够灵......
  • Unity (玩家通关胜利的障碍物效果)
    前沿当玩家进过密室逃脱的时候胜利的时候制作通关的物体 右键3Dobject --cube然后改名为GameEnding 然后取消材质的勾选 然后制作一个canvas 右键Ui-image   选中右边的那个 按住 Alt 选中右下角那给个然后平铺 在创建个图片一样的操作然后那图......
  • [Unity] 添加新建Lua脚本选项
    Unity添加新建Lua脚本选项最近学习Unity的XLua热更新框架的时候,会经常需要创建新的Lua脚本。然而,Unity本身不支持直接创建.lua后缀的文件,所以每次都必须手动在外部打开文件夹创建。为了提高效率,就需要在Unity新建文件的菜单中添加了一个“新建Lua脚本”的选项。并且,要达到和“......
  • 一款功能强大的Unity数据可视化图表库
    前言今天大姚分享一款免费(基于MITLicense协议)、开源、功能强大、简单易用、可配置的Unity数据可视化图表库:XCharts。XCharts特性持续维护和更新、稳定、可靠、开源免费、上手快、文档丰富。支持多种扩展组件和扩展图表。提供扩展定制服务,满足用户个性化需求。支持折......