通用交互系统概述
无需等待官方制作,使用GGS的通用交互系统,你今天就可以拥有基于SmartObject和GameplayAbilities的玩家交互系统。(还没发布,但快了。)

功能特性:
- 基于SmartObject和GameplayAbilities,有足够的灵活度去完成简单到复杂的交互。
- 基于SmartObject,可实现多交互对象选择,单个交互对象多交互入口。
- 基于GameplayAbilities,以模块化的方式处理玩家交互,将单种类交互逻辑以Ability形式封装,支持网络同步和客户端预测。
- 简单易用,一个组件,一个技能,你只需要配置SmartObject定义,并专注于开发交互逻辑(Ability)本身。
使用案例:
它能做很多有趣的事情,下面只是一些例子。
- 一把长椅子,有两处交互点,两个玩家可以同时坐上去,如果坐满了,其他玩家无法交互。
- 一匹马,有4个交互点,左右和马屁股处可以上马,马嘴处可以给它喂草。
- 一个骑马与砍杀里的攻城车,可以有4个交互点,如果三个AI占用一个点,再来个玩家也占一个点,攻城车才会推进。
- 一个敌人,要死了跪在地上,这时候会出现救援,斩杀,劝降等交互。
- 当然,也可以就是“拾取”一个东西而已的瞬间性交互。
开发动机/为什么你要使用我的交互系统
交互系统是每个游戏项目都会用到的基础功能,它说起来很简单,但要把它做好非常不容易,可能整个游戏开发生命周期过程中,你都在写交互。
玩家与游戏世界中的其他对象发起交互的形式其实都差不多,只要附近有可以交互的对象,就会在UI上弹出一些可用的交互选项,玩家按下某个键,就可以开始交互。
但是被交互那一方的信息,你在很多时候是无法提前知道的。
取决于游戏开发者的经验,实现交互系统的方式也截然不同,且这些方式各有缺陷。
心路历程:
最开始,我采用初级的写法:
如果玩家是在与一个交互Pickup,那么走pickup流程;如果玩家是在与一扇门交互,就走与门的交互逻辑;如果玩家是在与椅子/楼梯交互,就走对椅子/楼梯应交互流程。
结果:玩家的交互代码非常耦合,发起交互的那一个对象(玩家)需要知道和处理的信息太多,代码难以维护。
当我经过一段时间学习后,我采用了一些中级的写法:
我会通过接口去解耦,将一部分交互逻辑委托给被交互的对象去执行,而玩家只负责交互的发起。比如玩家在与一扇门进行交互,当交互开始后,由这个门去协调和处理玩家与门之间的交互。
结果:将很多交互代码从交互发起者转移到了被交互对象上,一定程度上使得代码比较容易维护。但当涉及到多人游戏,或者一个对象有多交互形式后,一切又变得更加复杂起来。如何确保一个可交互物同时只能被一个玩家使用?如何实现多个对象之间的协同交互?
当UE5发布了SmartObject后:
SmartObject,是一个非常优秀的设计,它将所有的交互行为完全由交互物本身去定义。游戏中的Pawn只需要负责搜到可交互的SmartObject,并根据不同的交互入口(Slot)开启不同的交互行为,而交互行为的内部逻辑全部由被交互的对象决定。它支持多交互入口,比如一把椅子可以:坐,打碎,搜集。它支持多个Pawn同时与其交互,比如可以两个Pawn去做一把长椅。它支持预定系统,可以知道哪些交互被占用,哪些交互可以使用。
SmartObject看起来是一个制作游戏交互的杀手锏,官方还基于其上开发了GameplayInteraction插件,和GameplayBehavior插件,允许用户以灵活的方式去制作复杂的游戏内交互。
有关于SmartObject的使用,能找到的现成案例中,全都是专注于AI/NPC交互的,基本上找不到与玩家交互相关的教程/案例,且它们不支持网络同步。
同时,在Lyra“初学者”项目中,有提供一个半成品的基于GameplayAbilities的玩家交互系统,我对其也进行了深入的研究,它能很好的处理多人游戏中的网络交互预测,但是它没有采用SmartObject,没有多交互入口的支持。
结论:
因此我认为:通过结合SmartObject+GameplayAbilities,可以开发出一个非常强大且具备足够通用性的交互系统,而这,就是我要开发通用交互系统的动机。
交互系统组件
TODO...