游戏引擎:Unity
版本:2019.4.1f (2017版本以上)
权限卡,作为SCP系列最为常见和重要的通行道具,丰富了玩家对SITE区域的探索过程。尤其是参观一些特殊的房间,如SCP-914加工机,SCP-079收容室,SCP-106收容操作,核弹室房门许可等。本文意在分享和探讨在Unity中实现一个更加操作自由、便利的权限卡。
本文章仅用于学习交流,允许转载但严禁任何商业行为。
什么是权限卡?
答:给予玩家通过某特定区或允许执行某一特定操作的IDCard。
SCP基金会的权限卡是什么?
答:基金会的权限卡大致分为5个级别。
权限卡级别 | 详细说明 |
---|---|
Level 1 | 最低级别 |
Level 2 | … |
Level 3 | … |
Level 4 | … |
Level 5 | 最高级别,允许所有操作 |
视情况,可根据策划规定的等级内容进行扩容或收缩权限分级制度。
因为权限卡的等级众多,仅使用Unity内置功能是不能高效实现权限卡的功能,为更好的区别权限卡等级,我的构造思路从最初始,经历以下变化:
经历时期 | 解决方案 | 优点 | 长远角度上是否可行 |
---|---|---|---|
初始想法 | 5个等级写5份权限脚本,每个脚本用于存储不同权限下许可的操作行为 | 不可行 | |
有点门道 | 使用Enum(枚举)列举5个等级,以bool(布尔)列举所有存储权限下的操作行为,通过勾选Bool来作为判断是否拥有此类权限的依据 | 将5个脚本数量缩减至1个。减少后期为新增权限级别类而再重写一个脚本 | 可行 (不提倡) |
小有技巧 | 用Enum(枚举)制作复选框,由复选框的勾选作为判定的依据 | 可视化操作上更为直观,相较于Bool(布尔)更易直接通过Unity的Inspector面板直观呈现 | 可行(提倡) |
从长远的角度看,三个不同时期的解决方案放在后期的开发拓展中——增删一些权限/设置更多的权限 是行不通的。“有点门道”方案看上去可行,一旦布尔判断变量过多却并不显得很便利。所以“熟练掌握”的使用Enum(枚举)制作复选框是目前最佳的解决方案【若有更有选择方案请写文章分享并@我前来学习】。在很多时候上确实有很多优点如下
答: 复选框是一种可同时选中多项的基础控件,也是基于计算机语言(C语言、java语言、CSS+HTML超文本标记语言)的编程代码框架。
答:很遗憾的是Unity本身是没有提供公开的复选框方法【可能有误,但笔者没有找到】,在Inspector窗口对GameObject中的Static内容描述中出现使用过。既然没有公开的复选框制作方法,我们就做一个复选框的方法。值得注意的是这里涉及到一个重要知识点——Unity扩展组件。
基于Unity提供的UnityEditor,由第三方自制Unity工具应用于Unity的插件。在Unity的Asset Store中由很多的这类插件,只不过大多数是付费,当然UnityPackage也会提供很多有用的插件辅助,Post-Processing后处理插件、Shader Graph插件等不收费使用。如:现在Unity内置的UGUI组件,Unity官方为加大UGUI的应用和完善,把NGUI的开发人员重金聘用参与UGUI的开发。
注:后续操作将围绕着Unity扩展组件进行复选框制作,请勿跳过操作顺序避免出现一些笔者之前遇到的坑。
Unity编辑器主用C#语言,因此我们选择C#作为主要语言进行"复选框"的制作。
using UnityEngine;
//命名空间-Unity的Assets包下SCPYM文件下的脚本路径(不作要求)
namespace Assets.SCPYM.GUIEditor
{
//定义多选属性
public class EnumFlagsAttribute : PropertyAttribute {
}
}
PropertyAttribute: 从UnityEngine中派生自定义属性属性的基类。使用它来创建脚本变量的自定义属性。 可以将自定义属性与自定义PropertyDrawer类关联,以控制如何在Inspector中显示具有该属性的脚本变量。而我们下一步要做的就是对Inspector窗口的变量进行编辑。
using UnityEngine;
using UnityEditor;
//命名空间-Unity的Assets包下脚本路径(有要求)
namespace Assets.SCPYM.Editor
{
//绘制多选属性
[CustomPropertyDrawer(typeof(GUIEditor.EnumFlagsAttribute))]
public class EnumFlagsAttributeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
property.intValue = EditorGUI.MaskField(position, label, property.intValue, property.enumNames);
}
}
}
注意:EnumFlagsAttributeDrawer的新建位置严格在Assets包内的Editor文件夹内【没有则新建命名为Editor】。虽然在Unity开发中不会出现此类报错,但在后续进行项目整理打包将会出现查找不到此类复选框的报错信息。
using UnityEngine;
//此处命名空间无须设置与之相同,请根据自己的命名空间进行调整设置
namespace Assets.SCPYM.Item
{
//这是一个示例脚本,如若想添加更多权限信息,直接在Application中添加枚举类型
//enum枚举内容为 914房门,096房门,173房门。
//若对SCP系列无了解,简易理解为3个不同房门的类型
public enum ApplicationList
{
SCP_914Room_DoorApplication,
SCP_096Room_DoorApplication,
SCP_173Room_DoorApplication,
}
//在Unity的Inspector窗口可见【意味着我想通过窗口可见操作】
[System.Serializable]
public class IDCardPermission : MonoBehaviour
{
//引用使用制作的枚举类型,让其以[复选框]的方式呈现
[GUIEditor.EnumFlags]
public ApplicationList permission;
}
//详细参数说明[仅说明内容,无需复制]
#region SCP-914 房间权限表
// SCP_914Room_DoorApplication 【SCP-914车间门许可】
#endregion
#region SCP-096 房间权限表
// SCP_096Room_DoorApplication 【SCP-096房间门许可】
#endregion
#region SCP-173 房间权限表
// SCP_173Room_DoorApplication 【SCP-173房间门许可】
#endregion
}
namespace Assets.SCPYM.Item
{
public class IDCard : IDCardPermission
{
public string OwnerName;
public string OwnerIdentity;
}
}
如上图所示,如果让它拥有所有的权限只需勾选Everything。反之,None则是什么也没有。
为完成权限卡的制作,我曾设想了很多中构建方法,出于代码量的庞大和后期加入其他内容的操作可便利性,在偶然间遇到了Enum复选框的解决方式,在当时是所想的最佳方案。但在自身不断认知到新的内容知识后,也逐渐认为还有更优的方案存在。或许这个方案并不理想,但定有人会了解和使用复选框这一知识来便利创作自己的游戏。