iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >Unity如何制作一个分数统计系统
  • 334
分享到

Unity如何制作一个分数统计系统

2023-06-21 22:06:09 334人浏览 八月长安
摘要

这篇文章将为大家详细讲解有关Unity如何制作一个分数统计系统,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。首先定义一个分数信息的数据结构,使用Serializable特性使其可序列化:using&nbs

这篇文章将为大家详细讲解有关Unity如何制作一个分数统计系统,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

首先定义一个分数信息的数据结构,使用Serializable特性使其可序列化:

using System;using UnityEngine; namespace SK.Framework{    /// <summary>    /// 分数信息    /// </summary>    [Serializable]    public class ScoreInfo    {        /// <summary>        /// ID        /// </summary>        public int id;        /// <summary>        /// 描述        /// </summary>        [TextArea]        public string description;        /// <summary>        /// 分值        /// </summary>        public float value;    }}

ScoreInfo类可序列化后,创建ScoreProfile类继承ScriptableObject使其作为可通过菜单创建的Asset资产:

using UnityEngine; namespace SK.Framework{    /// <summary>    /// 分数配置文件    /// </summary>    [CreateAssetMenu]    public class ScoreProfile : ScriptableObject    {        public ScoreInfo[] scores = new ScoreInfo[0];    }}

Unity如何制作一个分数统计系统

使用ScoreIDConstant类编写所有分数项ID常量,创建ScoreID特性并使用PropertyDrawer使其可在面板选择:

namespace SK.Framework{    public sealed class ScoreIDConstant    {        public const int INVALID = -1;    }}
using UnityEngine; #if UNITY_EDITORusing UnityEditor;using System;using System.Reflection;using System.Collections;#endif namespace SK.Framework{    public class ScoreIDAttribute : PropertyAttribute { } #if UNITY_EDITOR    [CustomPropertyDrawer(typeof(ScoreIDAttribute))]    public class ScoreIDPropertyAttributeDrawer : PropertyDrawer    {        private int[] scoreIDArray;        private GUIContent[] scoreIDConstArray;         public override float GetPropertyHeight(SerializedProperty property, GUIContent label)        {            return base.GetPropertyHeight(property, label);        }         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)        {            if (scoreIDConstArray == null)            {                ArrayList constants = new ArrayList();                FieldInfo[] fieldInfos = typeof(ScoreIDConstant).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);                for (int i = 0; i < fieldInfos.Length; i++)                {                    var fi = fieldInfos[i];                    if (fi.IsLiteral && !fi.IsInitOnly) constants.Add(fi);                }                FieldInfo[] fieldInfoArray = (FieldInfo[])constants.ToArray(typeof(FieldInfo));                scoreIDArray = new int[fieldInfoArray.Length];                scoreIDConstArray = new GUIContent[fieldInfoArray.Length];                for (int i = 0; i < fieldInfoArray.Length; i++)                {                    scoreIDConstArray[i] = new GUIContent(fieldInfoArray[i].Name);                    scoreIDArray[i] = (int)fieldInfoArray[i].GetValue(null);                }            }            var index = Array.IndexOf(scoreIDArray, property.intValue);            index = Mathf.Clamp(index, 0, scoreIDArray.Length);            index = EditorGUI.Popup(position, label, index, scoreIDConstArray);            property.intValue = scoreIDArray[index];        }    }#endif}

有了ScoreID特性后,用于ScoreInfo中的id字段:

using System;using UnityEngine; namespace SK.Framework{    /// <summary>    /// 分数信息    /// </summary>    [Serializable]    public class ScoreInfo    {        /// <summary>        /// ID        /// </summary>        [ScoreID]        public int id;        /// <summary>        /// 描述        /// </summary>        [TextArea]        public string description;        /// <summary>        /// 分值        /// </summary>        public float value;    }}

Unity如何制作一个分数统计系统

数据可配置后,创建分数项Score类,声明以下字段:Flag表示该分数项的标识,注册分数项时返回该标识,用于后续获取或取消该分数项分值;Description即分数项的描述;Value表示该分数项的分值;IsObtained用于标记该分数项的分值是否已经获得。

namespace SK.Framework{    /// <summary>    /// 分数项    /// </summary>    public class Score    {        /// <summary>        /// 标识        /// </summary>        public string Flag { get; private set; }        /// <summary>        /// 描述        /// </summary>        public string Description { get; private set; }        /// <summary>        /// 分值        /// </summary>        public float Value { get; private set; }        /// <summary>        /// 是否已经获得分值        /// </summary>        public bool IsObtained { get; set; }         public Score(string flag, string description, float value)        {            Flag = flag;            Description = description;            Value = value;        }    }}

为了实现一个分数组合,例如某项操作,通过A操作方式可获得5分,通过B操作方式可获得3分,它们之间是互斥的,即获得了前者的5分,就不会获得后者的3分,创建ScoreGroup类:

using System.Collections.Generic; namespace SK.Framework{    /// <summary>    /// 分数组合    /// </summary>    public class ScoreGroup    {        /// <summary>        /// 组合描述        /// </summary>        public string Description { get; private set; }        /// <summary>        /// 计分模式        /// Additive表示组合内分值进行累加        /// MutuallyExclusive表示组内各分数项互斥 获得其中一项分值 则取消其它项分值        /// </summary>        public ValueMode ValueMode { get; private set; }         public List<Score> Scores { get; private set; }         public ScoreGroup(string description, ValueMode valueMode, params Score[] scores)        {            Description = description;            ValueMode = valueMode;            Scores = new List<Score>(scores);        }         public bool Obtain(string flag)        {            var target = Scores.Find(m => m.Flag == flag);            if (target != null)            {                switch (ValueMode)                {                    case ValueMode.Additive: target.IsObtained = true; break;                    case ValueMode.MutuallyExclusive:                        for (int i = 0; i < Scores.Count; i++)                        {                            Scores[i].IsObtained = Scores[i] == target;                        }                        break;                    default: break;                }                if (ScoreMaster.DebugMode)                {                    ScoreMaster.LogInfo($"获取分数组合 [{Description}] 中标识为 [{flag}] 的分值 [{target.Description}]");                }                return true;            }            if (ScoreMaster.DebugMode)            {                ScoreMaster.LogError($"分数组合 [{Description}] 中不存在标识为 [{flag}] 的分数项.");            }            return false;        }        public bool Cancle(string flag)        {            var target = Scores.Find(m => m.Flag == flag);            if (target != null)            {                if (ScoreMaster.DebugMode)                {                    ScoreMaster.LogInfo($"取消分数组合 [{Description}] 中标识为 [{flag}] 的分数项分值 [{target.Description}]");                }                target.IsObtained = false;                return true;            }            if (ScoreMaster.DebugMode)            {                ScoreMaster.LogError($"分数组合 [{Description}] 中不存在标识为 [{flag}] 的分数项.");            }            return false;        }    }}
namespace SK.Framework{    /// <summary>    /// 计分方式    /// </summary>    public enum ValueMode    {        /// <summary>        /// 累加的        /// </summary>        Additive,        /// <summary>        /// 互斥的        /// </summary>        MutuallyExclusive,    }}

最终编写分数管理类,封装Create、Obtain、Cancle、GetSum函数,分别用于创建分数组合、获取分数、取消分数、获取总分,实现Editor类使分数信息在Inspector面板可视化

using System;using UnityEngine;using System.Collections.Generic; #if UNITY_EDITORusing UnityEditor;using System.Reflection;#endif namespace SK.Framework{    public class ScoreMaster : MonoBehaviour    {        #region NonPublic Variables        private static ScoreMaster instance;        [SerializeField] private ScoreProfile profile;        private readonly Dictionary<string, ScoreGroup> groups = new Dictionary<string, ScoreGroup>();        #endregion         #region Public Properties        public static ScoreMaster Instance        {            get            {                if (instance == null)                {                    instance = FindObjectOfType<ScoreMaster>();                }                if (instance == null)                {                    instance = new GameObject("[SKFramework.Score]").AddComponent<ScoreMaster>();                    instance.profile = Resources.Load<ScoreProfile>("Score Profile");                    if (instance.profile == null && DebugMode)                    {                        LogError("加载分数信息配置表失败.");                    }                }                return instance;            }        }        #endregion         #region NonPublic Methods        private string[] CreateScore(string description, ValueMode valueMode, params int[] idArray)        {            Score[] scores = new Score[idArray.Length];            string[] flags = new string[idArray.Length];            for (int i = 0; i < idArray.Length; i++)            {                var info = Array.Find(profile.scores, m => m.id == idArray[i]);                if (info != null)                {                    var flag = Guid.NewGuid().ToString();                    flags[i] = flag;                    scores[i] = new Score(flag, info.description, info.value);                    if (DebugMode) LogInfo($"创建分数ID为 [{idArray[i]}] 的分数项 [{info.description}] flag: {flag}");                }                else if (DebugMode)                {                    LogError($"配置中不存在ID为 [{idArray[i]}] 的分数信息.");                }            }            ScoreGroup group = new ScoreGroup(description, valueMode, scores);            groups.Add(description, group);            if (DebugMode)            {                LogInfo($"创建分数组合 [{description}] 计分模式[{valueMode}]");            }            return flags;        }        private bool ObtainValue(string groupDescription, string flag)        {            if (groups.TryGetValue(groupDescription, out ScoreGroup target))            {                return target.Obtain(flag);            }            if (DebugMode)            {                LogError($"不存在分数组合 [{groupDescription}].");            }            return false;        }        private bool CancleValue(string groupDescription, string flag)        {            if (groups.TryGetValue(groupDescription, out ScoreGroup target))            {                return target.Cancle(flag);            }            if (DebugMode)            {                LogError($"不存在分数组合 [{groupDescription}].");            }            return false;        }        private float GetSumValue()        {            float retV = 0f;            foreach (var kv in groups)            {                var scores = kv.Value.Scores;                for (int i = 0; i < scores.Count; i++)                {                    var score = scores[i];                    if (score.IsObtained)                    {                        retV += score.Value;                    }                }            }            return retV;        }        #endregion         #region Public Methods        /// <summary>        /// 创建分数组合        /// </summary>        /// <param name="description">分数组合描述</param>        /// <param name="valueMode">分数组计分方式</param>        /// <param name="idArray">分数信息ID组合</param>        /// <returns>返回分数项标识符组合</returns>        public static string[] Create(string description, ValueMode valueMode, params int[] idArray)        {            return Instance.CreateScore(description, valueMode, idArray);        }        /// <summary>        /// 获取分数组合中指定标识分数项的分值        /// </summary>        /// <param name="groupDescription">分数组合</param>        /// <param name="flag">分数项标识</param>        /// <returns>获取成功返回true 否则返回false</returns>        public static bool Obtain(string groupDescription, string flag)        {            return Instance.ObtainValue(groupDescription, flag);        }        /// <summary>        /// 取消分数组合中指定标识分数项的分值        /// </summary>        /// <param name="groupDescription">分数组合</param>        /// <param name="flag">分数项标识</param>        /// <returns></returns>        public static bool Cancle(string groupDescription, string flag)        {            return Instance.CancleValue(groupDescription, flag);        }        /// <summary>        /// 获取总分值        /// </summary>        /// <returns>总分值</returns>        public static float GetSum()        {            return Instance.GetSumValue();        }        #endregion         #region Debugger        public static bool DebugMode = true;         public static void LogInfo(string info)        {            Debug.Log($"<color=cyan><b>[SKFramework.Score.Info]</b></color> --> {info}");        }        public static void LogWarn(string warn)        {            Debug.Log($"<color=yellow><b>[SKFramework.Score.Warn]</b></color> --> {warn}");        }        public static void LogError(string error)        {            Debug.Log($"<color=red><b>[SKFramework.Score.Error]</b></color> --> {error}");        }        #endregion    } #if UNITY_EDITOR    [CustomEditor(typeof(ScoreMaster))]    public class ScoreMasterInspector : Editor    {        private SerializedProperty profile;        private Dictionary<string, ScoreGroup> groups;        private Dictionary<ScoreGroup, bool> groupFoldout;         private void OnEnable()        {            profile = serializedObject.FindProperty("profile");        }         public override void OnInspectorGUI()        {            EditorGUILayout.PropertyField(profile);            if (GUI.changed)            {                serializedObject.ApplyModifiedProperties();                EditorUtility.SetDirty(target);            }             if (!Application.isPlaying) return;            Color color = GUI.color;            GUI.color = Color.cyan;            OnRuntimeGUI();            GUI.color = color;        }        private void OnRuntimeGUI()        {            if (groupFoldout == null)            {                groups = typeof(ScoreMaster).GetField("groups", BindingFlags.Instance | BindingFlags.NonPublic)                    .GetValue(ScoreMaster.Instance) as Dictionary<string, ScoreGroup>;                groupFoldout = new Dictionary<ScoreGroup, bool>();            }             foreach (var kv in groups)            {                if (!groupFoldout.ContainsKey(kv.Value))                {                    groupFoldout.Add(kv.Value, false);                }                 ScoreGroup group = kv.Value;                groupFoldout[group] = EditorGUILayout.Foldout(groupFoldout[group], group.Description);                if (groupFoldout[group])                {                    GUILayout.Label($"计分模式: {(group.ValueMode == ValueMode.Additive ? "累加" : "互斥")}");                    for (int i = 0; i < group.Scores.Count; i++)                    {                        Score score = group.Scores[i];                        GUILayout.BeginVertical("Box");                        GUI.color = score.IsObtained ? Color.green : Color.cyan;                        GUILayout.Label($"描述: {score.Description}");                        GUILayout.Label($"标识: {score.Flag}");                        GUILayout.BeginHorizontal();                        GUILayout.Label($"分值: {score.Value}   {(score.IsObtained ? "√" : "")}");                        GUI.color = Color.cyan;                        GUILayout.FlexibleSpace();                        GUI.color = Color.yellow;                        if (GUILayout.Button("Obtain", "ButtonLeft", GUILayout.Width(50f)))                        {                            ScoreMaster.Obtain(group.Description, score.Flag);                        }                        if (GUILayout.Button("Cancle", "ButtonRight", GUILayout.Width(50f)))                        {                            ScoreMaster.Cancle(group.Description, score.Flag);                        }                        GUI.color = Color.cyan;                        GUILayout.EndHorizontal();                        GUILayout.EndVertical();                    }                }            }            GUILayout.BeginHorizontal();            GUILayout.FlexibleSpace();            GUILayout.Label($"总分: {ScoreMaster.GetSum()}", "LargeLabel");            GUILayout.Space(50f);            GUILayout.EndHorizontal();        }    }#endif}

测试

namespace SK.Framework{    public sealed class ScoreIDConstant    {        public const int INVALID = -1;         public const int TEST_A = 0;        public const int TEST_B = 1;        public const int TEST_C = 2;        public const int TEST_D = 3;    }}

Unity如何制作一个分数统计系统

using UnityEngine;using SK.Framework; public class Foo : MonoBehaviour{    private string[] flags;     private void Start()    {        flags = ScoreMaster.Create("测试", ValueMode.MutuallyExclusive,            ScoreIDConstant.TEST_A, ScoreIDConstant.TEST_B,             ScoreIDConstant.TEST_C, ScoreIDConstant.TEST_D);    }     private void OnGUI()    {        if (GUILayout.Button("A", GUILayout.Width(200f), GUILayout.Height(50f)))        {            ScoreMaster.Obtain("测试", flags[0]);        }        if (GUILayout.Button("B", GUILayout.Width(200f), GUILayout.Height(50f)))        {            ScoreMaster.Obtain("测试", flags[1]);        }        if (GUILayout.Button("C", GUILayout.Width(200f), GUILayout.Height(50f)))        {            ScoreMaster.Obtain("测试", flags[2]);        }        if (GUILayout.Button("D", GUILayout.Width(200f), GUILayout.Height(50f)))        {            ScoreMaster.Obtain("测试", flags[3]);        }        GUILayout.Label($"总分: {ScoreMaster.GetSum()}");    }}

Unity如何制作一个分数统计系统

Unity如何制作一个分数统计系统 

关于“Unity如何制作一个分数统计系统”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: Unity如何制作一个分数统计系统

本文链接: https://www.lsjlt.com/news/301209.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Unity如何制作一个分数统计系统
    这篇文章将为大家详细讲解有关Unity如何制作一个分数统计系统,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。首先定义一个分数信息的数据结构,使用Serializable特性使其可序列化:using&nbs...
    99+
    2023-06-21
  • Unity 制作一个分数统计系统
    项目中经常遇到分数统计的需求,例如我们执行了某项操作或做了某个题目,操作正确则计分,相反则不计分失去该项分数,为了应对需求需要一个分数统计系统。 首先定义一个分数信息的数据结构,使用...
    99+
    2024-04-02
  • Unity利用XML制作一个简易的登录系统
    通过XML文件保存账号密码,存储到本地,不连接数据库的简易登录系统。 1.创建一个XML文件,设置一个初始的账号密码。 public void Creat() { ...
    99+
    2024-04-02
  • 如何设计一个RPC系统?
    RPC是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高。但是RPC本身的构成却比较复杂,由于受到编程语言、网络模型、使用习惯的约束,有大量的妥协和取舍之处。本文就是通过分析几...
    99+
    2023-06-05
  • 如何使用Unity制作一个简易的计算器
    这篇文章给大家分享的是有关如何使用Unity制作一个简易的计算器的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、前言Hello,又见面了,今天分享如何使用Unity制作计算器,难度中等,可以用来学习,或者当成其...
    99+
    2023-06-29
  • 如何制作一套ERP/CRM系统
    这篇文章将为大家详细讲解有关如何制作一套ERP/CRM系统,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。根据传统开发的速度,开发系统一般情况下,就算是中小型企业的管理系统都可能要3~6个月的...
    99+
    2023-06-03
  • 基于Unity制作一个简易的计算器
    目录一、前言二、效果图及源工程三、实现1.界面搭建2.代码实现四、后记一、前言 Hello,又见面了,今天分享如何使用Unity制作计算器,难度中等,可以用来学习,或者当成其他项目的...
    99+
    2024-04-02
  • 如何设计一个JavaScript插件系统
    这篇文章给大家介绍如何设计一个JavaScript插件系统,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。WordPress有插件、 jQuery有插件、Gatsby、Eleventy和...
    99+
    2024-04-02
  • 如何用ASP.NET MVC 3实现一个访问统计系统
    本篇文章为大家展示了如何用ASP.NET MVC 3实现一个访问统计系统,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。运营网站,我们经常需要分析用户的行为、用户的习惯,用户看重网站的哪一部分,哪一部...
    99+
    2023-06-17
  • Linux系统如何制作RamDisk
    今天给大家介绍一下Linux系统如何制作RamDisk。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。虚拟内存盘是通过软件将一部分内存(RAM)模拟为硬盘来使用...
    99+
    2023-06-28
  • win10系统就一个c盘如何分区
    在Win10系统中,如果您只有一个C盘,您可以使用以下方法进行分区:1. 使用磁盘管理工具:按下Win + X键,在弹出的菜单中选择...
    99+
    2023-09-14
    win10
  • 基于PyQT5制作一个课堂点名系统
    刷抖音的时候发现一个老师在用的课堂点名系统。用PyQt5实现了一下同款,导入学生姓名,测试了一下完美运行。 操作效果展示: 完整源代码块还是放在了文章的最后面 使用的时候准备好学生...
    99+
    2024-04-02
  • 怎么设计一个RPC系统
    这篇文章主要讲解了“怎么设计一个RPC系统”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么设计一个RPC系统”吧!由于RPC底层的网络开发一般和具体使用环境有关,而编程实现手段也非常多样化...
    99+
    2023-06-02
  • 跟大神一起15分钟制作一个属于自己的Linux操作系统!
    计算机已成为现代人日常工作、学习和生活中必不可少的工具。操作系统是计算机之魂,作为用户使用计算机的接口,它负责调度执行各个用户程序,使计算机完成特定的任务;作为计算机硬件资源的管理者,它负责协调计算机中各类设备高效地工作。操作系统的重要性不...
    99+
    2023-06-05
  • php如何统计数组个数
    在php中使用sizeof函数统计数组中元素的个数:sizeof函数是用于计算数组中元素的个数,语法:int sizeof(array,mode);在php中使用sizeof函数统计数组中元素的个数,具体方法如下:sizeof函数作用:ph...
    99+
    2024-04-02
  • Linux系统下如何制作RamDisk
    这篇“Linux系统下如何制作RamDisk”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“Linux系统下如何制作RamDisk”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细节处理妥当,希望大家通过这篇文章...
    99+
    2023-06-28
  • 操作系统安装:如何一步一步安装操作系统?
    1. 准备工作 在开始安装操作系统之前,您需要准备以下几项: 光盘或U盘:如果您使用光盘安装操作系统,请确保光盘没有划痕或损坏;如果您使用U盘安装操作系统,请确保U盘有足够的空间来容纳操作系统安装文件。 安装介质:将操作系统安装文件复制...
    99+
    2024-02-05
    操作系统安装 安装过程 注意事项 准备工作
  • Linux如何制作系统镜像
    这篇文章将为大家详细讲解有关Linux如何制作系统镜像,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。环境Red Hat Enterprise Linux Server release 7.3 VMware...
    99+
    2023-06-28
  • php如何统计数组里同一个值有几个
    本篇内容介绍了“php如何统计数组里同一个值有几个”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在php中,可以使用array_count_...
    99+
    2023-06-30
  • 一条sql实现统计总数、分组分别统计总数
    wshanshi:个人使用记录… 一、 方法一 SELECT COALESCE( sex, '总数' ),COUNT( id ) '人数'FROMtestGROUP BYsex WIT...
    99+
    2023-09-02
    sql 数据库 mysql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作