• 游戏
  • 工业
  • 资源
  • 社区
  • 学习
  • 支持
开发
Unity 引擎
为任何平台构建2D和3D游戏
下载计划和定价
商业化
应用内购买(IAP)
发现并管理各商店的IAP
聚合平台
最大化收入并优化变现
Ad Quality
保护您应用的用户体验
Tapjoy
建立长期用户忠诚度
所有变现产品
用户获取
用户获取
被发现并获取移动用户
Unity向量AI
将玩家与合适的游戏连接
Aura设备内广告
在用户高峰参与时触达用户
所有增长产品
使用案例
3D协作
实时构建和审查3D项目
沉浸式培训
在沉浸式环境中培训
客户体验
创建互动3D体验
所有行业解决方案
行业
制造业
实现运营卓越
零售
将店内体验转化为在线体验
汽车
提升创新和车内体验
所有行业
技术库
文档
官方用户手册和API参考
开发者工具
发布版本和问题跟踪器
路线图
查看即将推出的功能
术语表
技术术语库
洞察
案例分析
真实成功案例
最佳实践指南
专家提示和技巧
所有资源
新增功能
博客
更新、信息和技术提示
新闻
新闻、故事和新闻中心
社区中心
讨论
讨论、解决问题和连接
事件
全球和本地活动
社区故事
Made with Unity
展示Unity创作者
直播活动
加入开发者、创作者和内部人员
Unity奖项
庆祝全球的Unity创作者
适合每个级别
Unity Learn
免费掌握Unity技能
专业培训
通过Unity培训师提升您的团队
Unity新手
准备开始
开始您的学习
Unity基础路径
你是Unity 新手?开始您的旅程
使用指南
可操作的技巧和最佳实践
教育
对于学生
开启您的职业生涯
对于教育者
增强您的教学
教育资助许可证
将Unity的力量带入您的机构
认证
证明您的Unity精通
支持选项
获取帮助
帮助您在Unity中取得成功
成功计划
通过专家支持更快实现目标
常见问题解答
常见问题解答
联系我们
与我们的团队联系
计划和定价
语言
  • English
  • Deutsch
  • 日本語
  • Français
  • Português
  • 中文
  • Español
  • Русский
  • 한국어
社交
货币
采购
  • 产品
  • Unity Ads
  • 订阅
  • Unity Asset Store
  • 经销商
教育
  • 学生
  • 教师
  • 机构
  • 认证
  • 学习
  • 技能发展计划
下载
  • Unity Hub
  • 下载存档
  • Beta 版测试
Unity Labs
  • 实验室
  • 作品
资源
  • 学习平台
  • 社区
  • 文档
  • Unity QA
  • 常见问题解答
  • 服务状态
  • 案例分析
  • Made with Unity
Unity
  • 我们公司
  • 新闻简报
  • 博客
  • 事件
  • 工作机会
  • 帮助
  • 新闻
  • 合作伙伴
  • 投资人
  • 附属机构
  • 安防
  • 社会影响力
  • 包容性与多样性
  • 联系我们
版权所有 © 2025 Unity Technologies
  • 法律
  • 隐私政策
  • Cookie
  • 不要出售或分享我的个人信息

“Unity”、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其分支机构在美国及其他地区的商标或注册商标(单击此处获取更多信息)。其他名称或品牌是其各自所有者的商标。

Hero background image

在您的Unity项目中使用基于ScriptableObject的枚举

为方便起见,此网页已进行机器翻译。我们无法保证翻译内容的准确性或可靠性。如果您对翻译内容的准确性有疑问,请参阅此网页的官方英文版本。
请点击这里。

本页面解释了如何在您的Unity项目中使用基于ScriptableObject的枚举。

这是为帮助Unity开发者创建与电子书在Unity中使用ScriptableObjects创建模块化游戏架构相关的演示而制作的六个迷你指南中的第三个。

该演示受经典的球和桨街机游戏机制的启发,展示了ScriptableObjects如何帮助您创建可测试、可扩展且设计友好的组件。

电子书、演示项目和这些迷你指南共同提供了在您的Unity项目中使用编程设计模式与ScriptableObject类的最佳实践。这些提示可以帮助您简化代码、减少内存使用并促进代码重用。

本系列包括以下文章:

  • 开始使用Unity ScriptableObjects演示
  • 使用ScriptableObjects分离游戏数据和逻辑
  • 将ScriptableObjects用作委托对象
  • 在游戏代码中将ScriptableObjects用作事件通道
  • 如何使用基于ScriptableObject的运行时集合
  • 开始之前的重要说明
  • 可扩展枚举
  • 基于ScriptableObject的枚举
  • PaddleBallSO中的玩家ID
  • 模式演示
  • 扩展行为
  • 基于ScriptableObject的枚举的好处
  • 更多ScriptableObject资源

开始之前的重要说明

在你深入了解ScriptableObject演示项目和这一系列迷你指南之前,请记住,设计模式的核心只是一些想法。它们并不适用于每种情况。这些技术可以帮助你学习与Unity和ScriptableObjects合作的新方法。

每种模式都有优缺点。只选择那些对你的特定项目有实质性好处的模式。你的设计师是否在很大程度上依赖Unity编辑器?基于ScriptableObject的模式可能是一个不错的选择,可以帮助他们与你的开发人员协作。

最终,最佳的代码架构是适合你的项目和团队的架构。

标签 1
删除或重新排序枚举值可能会导致意外行为。

可扩展枚举

枚举是一种方便的方式来管理代码中固定的一组命名值。然而,它们也有一些限制。由于序列化的枚举值以整数而不是其符号名称存储,删除或重新排序一个值可能会导致不正确或意外的行为。这意味着枚举,尤其是当你有很多枚举时,可能会在Unity开发中造成麻烦。

标准方法

以下是一个典型的枚举的样子:

[System.Serializable]
public enum HandGestures
{
石头,
纸,
剪刀
}

您可以使用System.Serializable属性序列化枚举,它会出现在检查器中。

问题

重新排序或删除一个值可能会导致问题。因为每个值在内部都是一个整数,它所代表的内容可能会变得不同。在给定的示例中,删除纸张值会导致剪刀假设值为1。

或者,如果我们添加一个值,如下面的示例所示。

如果选定的枚举值在删除的条目之后,它将会改变。

当维护和更新项目时,这可能会导致问题,特别是当您的枚举包含许多值时。您可以通过保留一个空白或未使用的元素,或通过显式设置整数值来减轻此问题。然而,这两种解决方案都不是理想的。

下载PaddleBallSO
tab3
检查SCRIPTABLEOBJECT之间的相等性

基于ScriptableObject的枚举

基于ScriptableObject的枚举为您提供传统枚举的功能,但作为单独的资产存储。例如,请查看下面示例中PaddleBallSO项目中的PlayerIDSO ScriptableObject。

本质上,这是一个空白的ScriptableObject。

您可以用它在项目中创建多个ScriptableObject资产,如P1、P2等。即使它们不包含任何数据,您也可以使用ScriptableObjects进行比较。只需在项目中创建一个新的ScriptableObject资产并给它命名。

您可以在项目中创建尽可能多的玩家ID,并轻松切换它们。只需更改 GameDataSO 脚本中分配的素材资源。

如果您正在检查相等性,这与枚举的工作方式类似。两个变量是否指向同一个 ScriptableObject?如果是,它们是相同的项目类型。否则,它们不是。

即使没有任何额外数据,ScriptableObject 也代表一个类别或项目类型。

PaddleBallSO中的玩家ID

在 PaddleBallSO 中,PlayerIDSO 成为团队标识。我们在 GameDataSO 中使用 P1 和 P2 素材资源来区分两个球拍。

GameSetup 脚本为每个球拍分配一个玩家 ID。在游戏过程中,Paddle 脚本将玩家输入与指定的团队 ID 进行比较。

这对任何类型的多人游戏都有应用。或者,考虑在您需要枚举的其他地方采用它们。

由于它们仅仅是在检查器中的分配,ScriptableObjects 不会面临重命名和重新排序的相同问题。

想将标识符名称分别更改为“Player1”或“Player2”吗?您可以这样做,一切仍然正常工作。添加更多 ScriptableObjects?没问题 - 检查器中的素材资源分配保持不变。

tab5
块使用分配的团队进行比较。

模式演示

这种行为对于创建游戏玩法非常有用。在 Patterns 演示中,单击切换枚举按钮以更改团队。DemoBall上的MonoBehaviour会相应地更新SpriteRenderer。

当球与一个方块碰撞时,它会造成伤害吗?通过运行快速的相等性测试来找出答案。以下代码示例中有一种比较它们的方法。

此方法可以确定两个GameObjects是否在同一队,这在检查友方与敌方交互时非常有用。这种简单的比较可以应用于物品拾取、伤害或任何其他具有“团队”或“对齐”的内容。

下载PaddleBallSO

扩展行为

有趣的部分发生在你为ScriptableObjects添加逻辑时。与传统的枚举不同,ScriptableObject可以拥有字段和方法,除了保存数据。

使用这些,以便每个ScriptableObject可以拥有专门的比较逻辑。例如,你可以有一个ScriptableObject定义特殊的伤害效果(例如,寒冷、热量、电、魔法等)。

如果你的应用程序需要一个库存系统来装备游戏物品,ScriptableObjects可以表示物品类型或武器槽。某些角色是否不允许持有某些物品?某些物品是否是魔法的或具有特殊能力?基于ScriptableObject的枚举可以添加方法来检查这一点。

前一个示例中的MonoBehaviour DemoBall 包含 AreEqual 方法来比较ScriptableObjects。在扩展行为时,你可以将比较逻辑捆绑在ScriptableObject本身内。

在Patterns演示中,你可以修改球,使其在与物体碰撞时更加挑剔。查看下面代码示例中的通用物品以进行碰撞。

这可以实现与当前演示类似的结果,但现在它有一个 m_Weakness 字段。这允许每个ScriptableObject定义另一个在碰撞时销毁的ScriptableObject。

与其调用AreEqual方法,每个ScriptableObject只需管理自己的比较逻辑。

结果更加灵活和可扩展。你可以更具体,而不是让球摧毁不同团队的方块。场景中的多个球可以摧毁不同的方块,具体取决于它们各自的CollisionItems。

这为不同的、更复杂的交互设置了舞台。如果你想制作一个剪刀石头布系统,你可以定义三个ScriptableObjects:石头、纸和剪刀。每个都可以有自己独特的m_Weakness,并使用IsWinner方法来处理交互。

与枚举不同,ScriptableObjects使这个过程模块化和适应性强。无需依赖额外的数据结构或添加额外的逻辑来与一组单独的数据同步。只需添加一个额外的字段和/或方法来处理逻辑。

基于ScriptableObject的枚举的好处

一旦你熟悉了基于ScriptableObject的枚举,你会发现它们可以改善你的工作流程,特别是在与队友合作时。由于它们是素材资源,更新它们会减少合并冲突,降低数据丢失的风险。

添加新的基于ScriptableObject的枚举就像创建另一个素材资源一样。与传统枚举不同,添加新值不会破坏你现有的代码。此外,Unity已经内置了工具来搜索、过滤和组织它们,就像任何其他素材资源一样。

作为额外奖励,使用编辑器的拖放UI使你的设计师能够在没有软件开发人员额外支持的情况下扩展游戏数据。你仍然需要协调如何最初设置字段,但设计师可以自己填充这些字段的数据。

下载PaddleBallSO
可脚本化的结尾

更多ScriptableObject资源

基于ScriptableObject的枚举是你的团队可以用来改善协作和效率的又一资源。

阅读更多关于使用ScriptableObjects的设计模式的信息,参见我们的技术电子书 在Unity中使用ScriptableObjects创建模块化游戏架构。您还可以在 通过游戏编程模式提升您的代码 中找到有关常见Unity开发设计模式的更多信息。