我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

这篇文章将为大家详细讲解有关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如何制作一个分数统计系统”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

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

下载Word文档

猜你喜欢

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

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

如何使用Unity制作一个简易的计算器

这篇文章给大家分享的是有关如何使用Unity制作一个简易的计算器的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、前言Hello,又见面了,今天分享如何使用Unity制作计算器,难度中等,可以用来学习,或者当成其
2023-06-29

如何设计一个RPC系统?

RPC是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高。但是RPC本身的构成却比较复杂,由于受到编程语言、网络模型、使用习惯的约束,有大量的妥协和取舍之处。本文就是通过分析几
2023-06-05

如何制作一套ERP/CRM系统

这篇文章将为大家详细讲解有关如何制作一套ERP/CRM系统,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。根据传统开发的速度,开发系统一般情况下,就算是中小型企业的管理系统都可能要3~6个月的
2023-06-03

Linux系统如何制作RamDisk

今天给大家介绍一下Linux系统如何制作RamDisk。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。虚拟内存盘是通过软件将一部分内存(RAM)模拟为硬盘来使用
2023-06-28

如何用ASP.NET MVC 3实现一个访问统计系统

本篇文章为大家展示了如何用ASP.NET MVC 3实现一个访问统计系统,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。运营网站,我们经常需要分析用户的行为、用户的习惯,用户看重网站的哪一部分,哪一部
2023-06-17

win10系统就一个c盘如何分区

在Win10系统中,如果您只有一个C盘,您可以使用以下方法进行分区:1. 使用磁盘管理工具:按下Win + X键,在弹出的菜单中选择“磁盘管理”。在磁盘管理界面上,您可以看到您的C盘和其他可用磁盘空间。右键单击C盘,选择“缩小卷”。然后输入
2023-09-14

跟大神一起15分钟制作一个属于自己的Linux操作系统!

计算机已成为现代人日常工作、学习和生活中必不可少的工具。操作系统是计算机之魂,作为用户使用计算机的接口,它负责调度执行各个用户程序,使计算机完成特定的任务;作为计算机硬件资源的管理者,它负责协调计算机中各类设备高效地工作。操作系统的重要性不
2023-06-05

设计制作个性Windows 8系统开始屏幕

大多数第一次看到微软Windows 8系统开始屏幕的朋友也许都会惊讶地睁大眼睛——出现在大家眼前的根本不是熟悉的传统Windows桌面,遍布屏幕的是一堆花花绿绿的方块和长条……是的,这就是
2022-06-04

Linux如何制作系统镜像

这篇文章将为大家详细讲解有关Linux如何制作系统镜像,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。环境Red Hat Enterprise Linux Server release 7.3 VMware
2023-06-28

操作系统安装:如何一步一步安装操作系统?

操作系统安装是一个相对复杂的过程,需要一定的技术知识和耐心。本文将详细介绍如何一步一步安装操作系统,包括准备工作、安装过程和注意事项等,希望能帮助您顺利完成操作系统安装。
操作系统安装:如何一步一步安装操作系统?
2024-02-05

Linux系统下如何制作RamDisk

这篇“Linux系统下如何制作RamDisk”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“Linux系统下如何制作RamDisk”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细节处理妥当,希望大家通过这篇文章
2023-06-28

MySQL如何统计每个分组的数据条数

在MySQL中,可以使用COUNT函数来统计每个分组的数据条数。下面是一个示例查询:SELECT column_name1, column_name2, COUNT(*) AS countFROM table_nameGROUP BY
MySQL如何统计每个分组的数据条数
2024-04-09

php如何统计数组里同一个值有几个

本篇内容介绍了“php如何统计数组里同一个值有几个”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在php中,可以使用array_count_
2023-06-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录