For the complete documentation index, see llms.txt. This page is also available as Markdown.

摄像机

了解如何控制玩家的摄像机

作为创作者,你可以完全控制玩家的摄像机。默认情况下,玩家在探索你的场景时可以自由选择第一人称或第三人称摄像机模式,但你也可以强制使用不同的摄像机模式。

虚拟摄像机可以是静态的,可以旋转以始终朝向玩家或其他实体,也可以附加到玩家或其他实体上,从而始终伴随其移动。

第一人称和第三人称摄像机模式

玩家通常可以通过按键盘上的 V 在第一人称和第三人称摄像机之间切换。使用 CameraModeArea 来强制让位于场景中特定区域内的所有玩家使用第一人称或第三人称摄像机模式。

const entity = engine.addEntity()

CameraModeArea.create(entity, {
	area: Vector3.create(4, 3, 4),
	mode: CameraType.CT_FIRST_PERSON,
})

如果玩家当前的摄像机模式与……的 CameraModeArea,他们将切换到该摄像机模式。屏幕上会显示一条提示,说明此更改是由于场景造成的。在区域内时,玩家无法更改其摄像机模式。当玩家离开 CameraModeArea时,其摄像机模式会恢复为进入之前的状态。

使用 CameraModeArea 在使用某种特定摄像机模式能显著提升体验的区域中。例如,当玩家需要点击小物体时,第一人称最合适;或者当玩家需要注意到场景在其头顶附加的某个实体时,第三人称会很有用。不要假设玩家知道如何切换摄像机模式,许多首次进入的玩家可能不知道自己有这个选项,也可能不记得该按哪个键。

在创建一个 CameraModeArea 组件时,你必须提供以下内容:

  • 区域:修饰区域的大小

  • mode:要在此区域强制使用哪种摄像机模式,来自 CameraType 枚举。

支持的摄像机模式有:

  • CameraType.CT_FIRST_PERSON

  • CameraType.CT_THIRD_PERSON

查询摄像机模式

你可以通过使用 CameraMode 组件来查询玩家的摄像机模式,位于 engine.CameraEntity.

你也可以通过使用 onChange 在……上的函数 CameraMode 组件。

使用虚拟摄像机

要在你的场景中使用自定义摄像机行为,你需要两样东西:

  • 创建一个虚拟摄像机:在场景中创建一个实体,并给它添加一个 VirtualCamera.

  • 分配该虚拟摄像机:添加一个 MainCamera 组件到 保留实体 engine.CameraEntity,并引用带有 VirtualCamera 组件。

摄像机随后将附加到带有 VirtualCamera 组件的实体上。如果该实体移动或旋转,摄像机也会随之移动。

在这个示例中,只要玩家留在场景边界内,摄像机就会始终处于场景中的固定位置。一旦玩家走出场景边界,默认的摄像机行为就会恢复。

视野

你可以通过设置 fov 属性(以度为单位)来覆盖虚拟摄像机的 Explorer 默认视野(FOV)。该覆盖仅在此虚拟摄像机处于活动状态时生效。省略 fov 时,将使用 Explorer 的默认值(通常为 60 度)。

更窄的 FOV(较低值)会放大画面,适合过场动画或瞄准。更宽的 FOV(较高值)会显示更多场景内容,适合全景视图。

你的场景可以包含任意多个带有 VirtualCamera组件的实体,并随着玩家移动或执行某些动作,在多个虚拟摄像机之间动态切换。在任何给定时刻只会有一个虚拟摄像机处于活动状态,这是由 MainCamera 组件中的 engine.CameraEntity.

若要恢复为默认摄像机行为,请将值设置为 undefined 位于 MainCamera.virtualCameraEntity。此后玩家就可以自由在第一人称和第三人称摄像机之间切换。如果你希望玩家只使用这两种模式中的一种,可以使用 摄像机修饰区域 来强制使用其中一种。

💡 提示:当摄像机转离头像时,通常也最好冻结头像的移动。这样玩家就不会盲目地撞上障碍物。参见 输入修饰器

要让玩家使用鼠标操控虚拟摄像机,请读取 screenDelta 组件的 PrimaryPointerInfo 组件,查看每一帧光标移动了多远,然后将该移动应用到摄像机的旋转上。即使光标被锁定,这也适用。参见 鼠标移动 以查看完整的鼠标视角示例。

鸟瞰视角

你可以使用虚拟摄像机从俯视角度查看场景,这可以作为你的头像常规视角的一种有趣变体,并启用不同的游戏机制。

你应避免将摄像机放置为完全垂直向下的方向。相反,应始终让摄像机稍微倾斜,即使 1 度也足够。这是因为玩家方向控制是基于摄像机视角,而不是头像朝向。如果摄像机是完美的鸟瞰视图,那么就无法清晰定义哪个方向对应哪个方向。只需 1 度的微小倾斜就足以建立前进方向。

视野

你可以使用 fov 属性在虚拟摄像机上设置自定义视野(FOV)。该值以度为单位。若省略,则默认为 60。

更宽的 FOV(更高的值)会一次显示更多场景内容,并营造速度感,这对赛车游戏很有用。更窄的 FOV(较低值)会放大画面,适合瞄准或电影式镜头。

摄像机过渡

每当场景在虚拟摄像机之间,或在默认摄像机行为与虚拟摄像机之间切换时,玩家都会看到过渡效果。虚拟摄像机的位置、旋转以及其他任何参数都会在一段时间内平滑变化。

虚拟摄像机上的过渡设置决定了你如何将视角过渡 到 该摄像机,从场景中的任何其他摄像机(包括默认摄像机)切换过来。它们不会影响你如何从该摄像机过渡 out 离开。

💡 提示:若想避免过渡并立即切换到某个摄像机,可将过渡时间或速度设为 0。

根据你的使用场景,你可能更倾向于设置过渡速度而不是持续时间:

  • 固定时间:你设置过渡的持续时间,摄像机将以完成该路径所需的速度移动,在这段时间内完成切换。

  • 固定速度:你设置希望虚拟摄像机在过渡期间移动的速度,持续时间将取决于距离。用于速度的值会被解释为 米/秒.

以下是这两种过渡模式的示例:

下面是一个包含两个虚拟摄像机及其之间过渡的完整示例:

过渡总是沿直线移动,不考虑路径上的任何障碍物。你也可以改为手动创建过渡,使用另一个虚拟摄像机作为中介,这样你就能完全控制其移动。这个中介虚拟摄像机可以执行 补间 从第一台摄像机的位置到第二台摄像机的位置的过渡,或者遵循一条更自定义的路径,以避开障碍物或进行电影式绕行。

摄像机跟随

你可以配置一个虚拟摄像机,使其始终面向玩家的方向,或者场景中的某个特定实体。摄像机的位置将保持静态,但它的旋转会改变,以始终让该实体居中。

这可以通过 lookAtEntity 属性在 VirtualCamera 组件来实现。要跟随玩家,请使用 保留实体 engine.PlayerEntity.

如果摄像机正在跟随某个实体,这只会改变旋转,不会改变摄像机的位置。

当摄像机旋转时,带有 VirtualCamera 组件的实体的 Transform 不会改变。不过,你可以从 engine.CameraEntity上的 Transform 中读取摄像机的旋转。该实体的旋转和位置将是绝对的,不会受到带有 VirtualCamera 组件的实体的影响。此变换的旋转会受到 lookAtEntity 行为的影响。

附加到玩家

虚拟摄像机的另一种用途是通过将虚拟摄像机附加到玩家实体,以自定义距离或角度跟随玩家。请注意,玩家不能自由改变摄像机的旋转,因此在这种情况下,摄像机的旋转将固定为虚拟摄像机的旋转。这对例如赛车游戏很有用,因为玩家预计始终向前看。

摄像机与碰撞体

当玩家的摄像机以第三人称模式移动时,摄像机可能会被碰撞体阻挡,也可能不会,这取决于分配给实体的碰撞层。在设计场景时要注意这一点,你可能会希望阻止摄像机穿过墙壁或其他实体。

参见 碰撞体 以了解更多关于如何为你的场景配置碰撞体的细节。

旁观模式(观察者摄像机)

你可以构建一种旁观模式,将玩家从正常的头像移动切换到自由漫游或跟随玩家的摄像机。这对于竞技游戏中的观察者角色、现场活动中的导演摄像机或回放系统都很有用。

这种模式组合了多个 SDK 功能:

功能
SDK API
用途

自定义摄像机视图

VirtualCamera + MainCamera

替换玩家的摄像机

冻结头像移动

InputModifier (disableAll: true)

释放 WASD 来操控摄像机

跟踪场景中的玩家

onEnterScene / onLeaveScene

构建跟随目标名单

摄像机控制

inputSystem.isPressed(InputAction.IA_*)

WASD 控制俯仰/偏航,E/F 控制缩放

鼠标视角

PrimaryPointerInfo.screenDelta

使用鼠标旋转摄像机

摄像机支架架构

使用一个 双实体支架 使偏航和俯仰保持独立:

rigRoot 保存偏航(左/右转),并朝向跟随目标或自由摄像机枢轴进行插值。 rigCamera 处理俯仰(上下倾斜)以及从根节点到环绕距离。将偏航和俯仰拆分到两个 Transform 上,可使欧拉角运算更直接。

启用和禁用

摄像机边界

引擎会禁用 VirtualCamera 超出场景地块边界移动的实体。如果摄像机离开场景范围,它会静默停止工作。每帧都将摄像机位置限制在场景的轴对齐包围盒(AABB)内,并留出一点边距。

对于更大的场景,请将边界设置为与你的 scene.json 地块相匹配。无论地块数量多少,场景高度上限都是 330 米。一个 4x4 地块的场景可以使用 Vector3.create(64, 330, 64).

跟随玩家

使用 onEnterScene 和 onLeaveScene 以在场景中构建一个实时玩家名单。然后玩家可以使用按键在跟随目标之间轮换(例如, IA_ACTION_3 和 IA_ACTION_4)。当跟随某个玩家时,支架根节点会向被跟随玩家的 Transform 位置插值,子摄像机则会以可配置的距离环绕。

要在每帧跟随玩家,请将支架根节点插值到其位置:

参见 玩家进入或离开场景 更多关于 onEnterScene 和 onLeaveScene.

旁观时的鼠标视角

阅读 PrimaryPointerInfo.screenDelta 每帧来使用鼠标旋转摄像机。即使指针被锁定,这也有效。参见 鼠标移动 以查看完整的鼠标视角示例。

完整参考实现

该 33,20-旁观模式 测试场景中在 src/spectate.ts中包含一个自包含的旁观模块。它支持自由摄像机和跟随摄像机模式、WASD + 鼠标视角控制、玩家轮换、环绕距离缩放、边界限制,以及一个显示控制和当前跟随目标的屏幕 HUD。

要在你自己的项目中使用它:

  1. 复制 src/spectate.ts 到你的场景中。

  2. 更新 PIVOT, BOUNDS_MIN、以及 BOUNDS_MAX 在文件顶部,使其与你的场景地块相匹配。这是最常见的集成错误。

  3. 连接 toggleSpectate() 到任何触发方式:可点击实体、UI 按钮或按键。

💡 提示:如需摄像机控制的实际示例,请参见 2,22-虚拟摄像机 测试场景,它会轮换多个 VirtualCamera 实体通过 MainCamera 包括 lookAtEntity 面向玩家的摄像机和一个缓动摄像机; 32,20-virtual-camera-mouse-look,它在指针锁定时驱动鼠标视角摄像机; 33,20-旁观模式,它实现了一个完整的旁观/观察者摄像机,包含跟随摄像机和自由摄像机模式;以及 9,99-修饰区域,它强制在一个体积内使用某种摄像机模式 CameraModeArea.

最后更新于