April 27, 2018

动态第三人称摄像机的六大要素

作者 Nick Pruehs

十几年来,Daedalic Entertainment因广受好评的冒险游戏而广为人知,我们的作品包括《Deponia》《圣殿春秋》。长期以来,我们也一直在探索其他类型的游戏,比如第三人称冒险游戏《心境》,以及另一个我们即将讨论的第三人称动作冒险原型。

对于这些游戏,虚幻引擎4是我们理所当然的选择,因为它让包括程序员、美术和游戏设计师在内的整个团队都能保证最终成品达到最高品质。

在本文中,我们将讨论第三人称动作冒险游戏中使用的动态摄像机。其目的是在不干扰玩家意图的前提下,设计一个摄像机来重点拍摄每个关卡的关键探索区域,并辅助近身格斗。后者尤其重要,因为如果玩家觉得摄像机走位不合理,就会立即感到不适甚至沮丧。

虚幻引擎4已经提供了非常灵活的内置系统来定义任意摄像机修饰符,这些修饰符可以应用或不用相对视图平移和旋转。因此,不同的玩法元素就可以修改摄像机而不会彼此干扰。

我们已在这个摄像机模型的基础上进行了扩展,以便能够:

  • 在玩家探访关卡的特定区域时调整摄像机
  • 根据当前俯仰角自动更改摄距和视野
  • 聚焦玩家选定的技能目标
  • 以玩家角色的当前运动方向旋转
  • 在战斗中更改摄像机属性
  • 确保摄像机和玩家角色之间的视线永远不会被关卡障碍物遮挡
  • 始终允许玩家用玩家输入覆盖动态摄像机

动态摄像机可能会更改一些属性,例如:

  • 视野
  • 摄距
  • 景深
  • 摄影角度
  • 相对摄影位置

以上的某些属性(例如视野或景深)已经可以通过FPostProcessSettings等内置引擎类型进行更改,但我们增加了一些其他属性,例如动态摄距。

上述所有要求都基于John Nesky发表的著名演讲“50 Camera Mistakes in Journey”,对于关心本主题的所有人而言,该演讲绝对是必看材料。

摄像机系统架构

每一帧中,玩家视野的终点都由虚幻的摄像机责任链决定。摄像机、玩家控制器以及玩家摄像机管理器需要共同寻找游戏中每一个瞬间的摄影位置和角度。玩家摄像机管理器允许更多摄像机修饰符记录和调整视野终点。

CameraResponsibilityChain.png

所有摄像机修饰符的基类UHoatCameraModifier可扩展内置UCameraModifier。它为所有摄像机修饰符提供共享功能,例如每次玩家输入后的冷却期,禁用动态摄像机行为以确保玩家意图总是优先,以及平滑地进出摄像机效果,如摄距更改或景深更改。

所有特定修饰符用于扩展UHoatCameraModifier,其中大多数修饰符引用名为FHoatCameraInfo的自定义结构体。该结构体存储可能会被某个修饰符更改的所有属性,例如视野或摄距,并在所有蓝图中提供一个通用接口,用于指定摄像机行为。

HoatCameraSystem.png

摄像机弹簧臂

我们可以使用摄像机修饰符更改角色和摄像机之间的距离。但是,在这种情况下,我们会失去引擎内置USpringArmComponent的优势,它可以确保摄像机到玩家角色之间保持特定距离,除非二者之间的视线受阻。如果视线受阻,弹簧臂会自动将摄像机拉近角色以保持视线通畅。

默认摄距可以通过USpringArmComponent的插槽偏移(Socket Offset)更改。我们发现,如果确保整个团队仅使用该插槽偏移来设置摄距,那么大家的工作都会轻松得多。如果我们允许所有人自由更改摄像机变换(例如Z方向),则更难理解确定游戏中最终摄影位置的计算。

因为我们不想失去弹簧臂功能,所以创建了自定义UHoatCameraSpringArmComponent,用于扩展USpringArmComponent。我们的组件允许任意数量的摄像机修饰符更改弹簧臂长度,并且逐帧应用结果,同时保留基本弹簧臂功能。

摄影角度、视野、摄像机延迟

虚幻引擎4本身已经更改了许多其他重要的默认摄像机属性:您可以根据需要在摄像机组件中指定默认视野。

CameraSettings.png

玩家摄像机管理器允许您指定摄像机的最小和最大俯仰角。

PlayerCameraManager.png

弹簧臂组件还可以提供用于启用摄像机延迟的选项。要启用此功能,可以启用摄像机延迟和摄像机旋转延迟,并指定其各自的速度来创建所谓的“橡皮筋摄像机”:每次角色在短时间的静止站立后,开始朝着任意方向移动时,这个摄像机不会立即跟拍,而是稍候片刻,以提供一种不那么生硬的游戏体验。同样,玩家角色停止移动后,摄像机也会在片刻之后才停止移动。

CameraLag.png

基于俯仰的摄像机修饰符

我们的动态摄像机的所有其他功能均基于摄像机修饰符。换言之,它们是使用从UHoatCameraModifier中派生的类实现的。

第一个修饰符允许根据当前摄像机俯仰角调整多个摄像机属性。通常,摄像机俯仰角会直接通过玩家输入更改(例如,使用游戏手柄右摇杆的Y轴)。我们希望在玩家倾斜摄像机时也能更改其他摄像机属性,例如摄距以及因摄距而变的视野。为设计师提供最大的灵活性始终是我们的主要目标之一,所以在此公开UCurveFloat资源指针,该指针允许定义从玩家摄像机俯仰输入派生的任意摄像机行为。

CameraPitchToDistanceCurve.png

摄像机修改体积

在大多数情况下,关卡设计师想要重点拍摄非常重要的关卡区域,例如,在离开洞穴,在一片空旷的开阔区域与玩家对抗时。在其他情况下,谜题或其他游戏机制也需要更好地观察玩家周围的环境。

对于这两种情况,我们提供了可以放置在关卡任意位置的AHoatCameraModificationVolumes

这些体积提供一个FHoatCameraInfo属性,该属性与转变时间一起设置后再次由摄像机修饰符使用。

CameraModificationVolume.png目前不支持重叠体积,但可以轻松添加。

战斗摄像机

我们的游戏包括远程战斗和近身战斗,后者需要玩家充分了解周围环境,包括从后面攻击的敌人。与此同时,我们希望玩家能够更容易专注于附近的敌人,而不会被远处的景象所吸引。

我们再次使用一个摄像机修饰符,应用FHoatCameraInfo,并增大了玩家参与战斗时的摄距和景深。

聚焦行走方向

动态摄像机的一个更基本的要求是自动聚焦玩家角色的行走方向。玩家自行调整摄像机的需求越低越好,而聚焦玩家角色的行走方向是玩家最有可能自己动手操作的事情,而且频率颇高。

因此,我们添加了一个摄像机修饰符来执行此操作,而不需要玩家输入,并试验了玩家不在静止状态时的旋转摄像机等参数。但如果玩家想要旋转摄像机,他们的优先级必须始终高于我们的动态系统。如果你旋转了摄像机来观察附近的某个关注点,结果摄像机却很快自动慢慢回调,这肯定会令人十分沮丧。

聚焦技能目标

我们的玩家角色有很多可以对敌人使用的实用技能。在用游戏手柄右摇杆选择目标时,游戏会进入慢动作,并将摄像机对准当前目标。

TargetSelection.png

这是我们最早开发的功能之一,所以最初实现的时候并没有使用摄像机修饰符。后来,我们发现目标选择会干扰动态摄像机系统,所以也为此创建了一个摄像机修饰符,让设计师可以指定摄像机旋转速度和锁定速度等参数。

保持视线

我们添加的最后一个摄像机修饰符会确保摄像机不会失去与玩家之间的视线。摄像机弹簧臂的默认行为已经能够通过将摄像机拉近角色来满足这一要求。

另一种满足该要求的方法是让摄像机绕过可能遮挡玩家角色的任何障碍物。为了检测到任何可能的障碍物,我们会从摄像机向玩家左右两侧以逐渐增加角度发出多条光线。正如“50 Camera Mistakes in Journey”所介绍的,这些“须状”光线投射会在玩家真正被遮挡之前,提前检测可能会遮挡玩家的任何障碍物。如果发现障碍物,摄像机会慢慢地围绕着角色旋转以保持视线。我们向设计师公开一些属性,例如摄像机旋转速度、两个须状光线投射之间的弧度步长以及提前探测的距离。

显而易见,摄像机拉近和绕着障碍物旋转无需同时实现。因此,我们引入了另一个碰撞通道,叫做CameraRotateAround。对于任何指定障碍物,只会有一个碰撞通道做出响应。

总结

虚幻引擎4的摄像机责任链提供了可靠而又非常灵活的基础,可供创建复杂的动态第三人称摄像机行为。

借助稍加修改的摄像机弹簧臂组件和若干其他摄像机修饰符,我们能够开发出动态摄像机,既能确保愉悦的玩家体验,同时重点拍摄关键关卡区域,而且始终优先考虑玩家意图。

同样的,如果大家有任何想法或改进意见,请在下方评论区留言。完整的代码可以在GitHub上找到。感谢阅读!