Intro
PlayMaker 是 Unity 环境下的第三方可视化状态机编辑器与运行时,由 Hutong Games 开发,发布于 2011 年,通过 Unity 资源商店供广大开发者下载使用,是商店中下载最多的付费工具。PlayMaker 经历战火考验,有着不少经典案例,《炉石传说》《Inside》《Hollow Knight》《看火人》等一众优秀游戏都使用到了 PlayMaker 。
本文主要围绕以下话题展开:
- PlayMaker 是什么?
- PlayMaker 为什么受欢迎?
- 我们从中能得到什么启发?
是什么
简单来说,PlayMaker 是一个可视化的有限状态机编辑器与运行时。
▐ 有限状态机(Finite State Machine,FSM)
有限状态机又称有限状态自动机(finite-state automation,缩写:FSA),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型。—— 有限状态机 Wikipedia。
在游戏开发中会用到很多编程模式来实现游戏逻辑或者优化性能,状态机是应用最多的一种,例如 AI 行为、角色/物品动画状态、互动玩法、剧情流程等都可以用状态机来表示。PlayMaker 核心采用了状态机的概念,借助状态(State)、动作(Action)和事件(Event)来快速构建游戏内行为逻辑。
状态机方便将复杂的游戏逻辑组织为离散的状态,例如:打开、关闭、行走,再以事件对状态机进行驱动,实现逻辑。
FSM 具有以下特征:
- 状态的总数是有限的
- 状态机同一时刻只能处于一种状态
- 某种条件下,会从一种状态转变到另一种状态状态机除了使用状态图来表示,还可以使用状态转移表来表示。
- 以上图中的 FSM 为例。首先 START 事件会被发送,然后 Walking 状态会被激活,当 Walking 里所有的 Action 都执行完毕后,stop 事件会被发送,然后 4 箭头所指的 Idle 状态会被激活,此时执行流程一直停留在 Idle。当 hit 全局事件被发送后,FallFown 状态会被激活。
PlayMaker 中的 FSM 实现由以下几部分构成:
State
每一个状态都会执行若干个行为,同一时间只有一个状态会被激活,并且只有处于激活的状态会执行动作(Action)和接收事件(Events)。
Transition
Transition 表明了状态间的跳转。当某事件触发时,当前激活的 State 退出,进入新的 State。通过改变连线就可以改变状态机之间的跳转逻辑。状态机可视化后,使得 Transition 的构建和调试变得更容易。
PlayMaker 中还存在全局跳转(Global Transition)的概念,在可视化图形中以黑底方块表示。当设定的全局事件被触发时,不管当前状态是哪个状态,状态机都会直接跳转到全局事件指向的状态。全局跳转事件有利于减少过多的跳转事件,简化状态机的跳转逻辑。
Event
事件会触发当前状态跳转到下一个状态,所有的状态跳转都是依赖事件触发的。事件可以既可以来自 Unity 的脚本或者组件,例如应用级和一些通用的事件,如应用运行、暂停、退出,碰撞的进入、停留、离开,关卡载入,鼠标的点击、拖拽、进入、退出,触发器的触发、停止等。也可以来自 PlayMaker 自己的 Action。
开始事件(Start Event)是 PlayMaker 状态机的第一个事件(START 是一个系统事件),当 FSM 组件激活时,开始事件会调用,它所指向的状态即为状态机的第一个状态。“FINISHED”也是一个系统事件,代表“本状态已经执行完所有操作的意思。
普通的Event只能在Fsm内部被触发,而 Global Event 可以从 FSM 外部被触发。
Action
在 PlayMaker 中,一个 Action 定义的参数,可以像编辑其他 UI 的控件或者 Unity 的组件参数一样,填一个具体的值,也可以使用一个变量,而这个变量可以是另一个Action操作的结果,也可以是其他代码中传给 PlayMaker 的某个值。PlayMaker 将游戏中的物体行为划分为多个步骤组成的序列,通过事件在不同状态间进行切换。如果把行为中的每一个步骤都称为一个状态(State),那么整个行为就可以通过把多个状态相互连接来表示。这些状态之间的连接,也就是从一个状态跳转至另一个状态的转换事件(Transition)。而这种把多个状态连接到一起、共同表现游戏对象的某种行为的方式,就被称为有限状态机。所以 FSM 描述的就是这种行为到底应该按照什么步骤来执行。进一步,对于每一个步骤来说,又可以继续向下细分为一系列 的动作(Action) 。这种由 Action-State-Transition-FSM 构成的描述逻辑,正是 PlayMaker 替代程序、控制 Unity 中游戏对象的基础。
▐ 编辑器能力
PlayMaker 基于 Unity IDE 的扩展能力提供了一个强大的状态机可视化编辑器。
- 编辑器
编辑器整体视觉风格十分简洁,特别是核心状态机视图,在状态非常复杂的情况下不会有太多的干扰元素。
另外,编辑器还提供了一些辅助功能来提高体验和效率,如 minimap、节点颜色、节点文档注释等。
- Template
模板功能可以将 FSM 存为模板,以实现通用逻辑复用。
- 调试
PlayMaker 具备强大的调试功能,方便定位问题,对于复杂的逻辑排查很有帮助。在编辑阶段,编辑器会实时进行校验与错误提示;
针对单个 FSM,可查看当前的 state 与 transition 日志,设置断点进行跟踪调试。在 Debug 时,可以实时看到状态间的跳转。PlayMaker 支持断点调试,如果在某个状态上打上断点,则当跳转到该状态时,游戏会暂停。
▐ 扩展开放能力
PlayMaker 的扩展开放能力主要体现在以下两点:
- PlayMaker 中的 Action 支持使用 C# 自定义开发
- 其他代码可以直接与 PlayMaker 进行交互
设计实现复杂的算法,封装成为 PlayMaker Action,然后交由策划或美术来使用。但是也应考虑到 PlayMaker 完全基于状态机这种“策略”,也会带来 Action 这个适配层的开发成本。
为什么
PlayMaker 为什么能够如此受欢迎呢?从表面看,无疑“可视化、无代码开发”这样的噱头吸引了不少初学者,但对于真实的游戏开发场景有着更深层次的原因。
▐ 从技术角度
PlayMaker 选择了状态机这个适用范围广泛的模式,状态机工作方式条理清晰,逻辑明确。并且围绕状态机提供了强大的可视化编辑器,易于设计、维护与调试整体逻辑。
可扩展能力强,除了内置的常用 Action 外,Unity Assets Store 里的大多数流行插件都有对应的 PlayMaker Action 包。开发者还可以方便的自己开发 Action,或者使用 C# 代码与 PlayMaker 进行交互。
▐ 从协作角度
在游戏的开发过程中有多种参与角色:策划、编剧、关卡、美术、数值、动画、音效、开发。仅与编程直接相关的就有 Game Engine Programmer、Gameplay programmer、Technical Artist 等。随着游戏行业的发展与独立游戏的崛起,艺术创意类角色的参与比重越来越大,视觉、剧情在游戏中越来越重要,纯编程的方式无法让更多的非开发角色参与其中,限制了创意的发挥,这就对纯编程开发的方式提出了挑战。
例如我们要实现一个带有解谜剧情的关卡流程:通过机关 A 和机关 B 打开机关 C,解开谜题一从而触发谜题二。使用代码开发这段逻辑并不困难,但是如果谜题或者剧情设计后续要不断进行调整,纯代码的方式将会变得十分低效。
PlayMaker 就像是开发与非开发之间的连接器,互相屏蔽了对方不需要关系的内容。方便非开发人员去调整游戏逻辑行为,也方面了开发人员对这些逻辑进行维护和管理。从协作流程上来说,PlayMaker 符合游戏设计的趋势要求,满足了不同编程水平参与者的需求。
艺术家出身的开发者创作会更喜欢 Playmaker,Playmaker 是一种发散型思维,散乱的做,做到哪里想到哪里,随心所欲,发现 Bug 再去纠正;这在前期的创作中非常重要,我没有去花大的精力考虑那些需要注重的程序先后关系,而把精力完全花在了创意上面。
PlayMaker 以正确的方式解决了正确的问题。
▐ 不适用场景
当然 PlayMaker 也不是万能的,会存在不适用的场景。例如在以跳跃为关键机制的游戏《Celeste》中,主角控制代码有 5471 行之多,实现了奔跑、跳跃、攀爬、冲刺精确顺畅的操控体验,涉及大量的变量与数学计算。可以想象这样的代码逻辑如果用可视化的 FSM 来表示会是多么壮观的场景。(但有趣的是这段逻辑中,还是以代码的方式使用了状态机)
主角控制代 码地址:https://github.com/NoelFB/Celeste/blob/master/Source/Player/Player.cs
启示
▐ 解决问题的策略
宏观层面,PlayMaker 并没有想要解决开发中的全部编程问题,而是聚焦于重要实体的状态逻辑。
微观层面,PlayMaker 选择了 FSM 这种模式来作为核心,而将具体逻辑下沉到了 Action 内,大大降低了对使用者的编程能力要求。
- 与 Visual Scripting 的区别
通过上面的了解,我们其实可以看到 PlayMaker 与常见的逻辑编排有着不小的区别。Visual Scripting 是典型的面向过程编程,体现了线性程序思维,与代码十分相似,需要严谨性,更像是代码的可视化。典型的代表有虚幻引擎的 BluePrint,Unity 官方的 Bolt 等。
从严格意义上来讲 PlayMaker 并不是 Visual Scripting(虽然官方网站上说),不涉及具体的代码、数据转换等(这部分在 Action 中)。而是选择了游戏开发中最常见的场景进行可视化,尽可能多的覆盖了编程中较为繁琐、灵活的任务,而非将整个编程可视化。这种思路值得学习。
参考链接
- PlayMaker 官网(地址:https://hutonggames.com/index.html)
- PlayMaker - Unity Assets Store(地址:https://assetstore.unity.com/packages/tools/visual-scripting/playmaker-368)