UE5.8 Gameplay Cameras 专题系列

UE5.8 Gameplay Cameras 专题(四):Camera Asset、Camera Rig、Camera Node 三件套

讲清 Camera Asset、Camera Rig Prefab、Camera Node 的职责、构建流程、运行时 Evaluator,以及如何写一个项目自定义节点。

总览

这三个名字很像,新手最容易混。记住一句话:Camera Asset 是完整相机方案入口,Camera Rig 是可复用镜头预制,Camera Node 是节点树里的一个运算步骤。

UE5.8 Gameplay Cameras 专题(四):Camera Asset、Camera Rig、Camera Node 三件套 配图
Camera Asset 管总谱,Camera Rig 管一种镜头方案,Camera Node 管每一步姿态运算。

架构分析

UCameraAsset 持有 UCameraDirector、共享 Enter/Exit Transitions、默认参数、参数定义和 AllocationInfo。你把它挂到 UGameplayCameraComponent 上,运行时就从这里找到 Director。

UCameraRigAsset 继承 UBaseCameraObject,核心属性是 RootNode。它还持有 GameplayTags、进入/退出 Transition 和 ECameraRigInitialOrientation。一个项目通常会有很多 Rig:Follow、Aim、LockOn、Dialogue、Vehicle、Death、Spectator。

UCameraNode 是抽象基类。它有 GetChildrenPreBuildBuildBuildEvaluator,真正每帧执行的是对应的 FCameraNodeEvaluator。也就是说,资产里的 UObject 节点负责配置,运行时 Evaluator 负责算。

常用 Node 选择

节点类型 用途 项目里怎么用
AttachToPlayerPawn / AttachToActor 确定跟随对象 第三人称、载具、对话目标
BoomArm 绕支点旋转和拉臂 替代一部分 SpringArm 行为
DampenPosition / DampenRotation 平滑移动和旋转 角色急停、镜头延迟
CollisionPush 防止穿墙 第三人称必备
FieldOfView / Filmback / Lens 镜头参数 冲刺、瞄准、电影感
InputAxisBinding2D / AutoRotate 输入和自动回正 右摇杆、鼠标、手柄
CameraRigCameraNode 嵌套 Rig 复用通用子镜头

自定义节点骨架

自定义节点适合处理项目特有逻辑,例如“锁定目标时根据敌人高度微调肩位”。不要把能用参数解决的东西都写成节点。

#include "Core/CameraNode.h"
#include "Core/CameraNodeEvaluator.h"

UCLASS(meta=(CameraNodeCategories="Project,Transform"))
class ULockOnShoulderOffsetCameraNode : public UCameraNode
{
    GENERATED_BODY()

public:
    UPROPERTY(EditAnywhere, Category="LockOn")
    FVector3dCameraParameter ShoulderOffset = FVector(0.0, 60.0, 20.0);

protected:
    virtual FCameraNodeEvaluatorPtr OnBuildEvaluator(FCameraNodeEvaluatorBuilder& Builder) const override;
};

class FLockOnShoulderOffsetEvaluator : public UE::Cameras::FCameraNodeEvaluator
{
    UE_DECLARE_CAMERA_NODE_EVALUATOR(GAMEPLAYCAMERAS_API, FLockOnShoulderOffsetEvaluator)

protected:
    virtual void OnRun(const FCameraNodeEvaluationParams& Params, FCameraNodeEvaluationResult& OutResult) override
    {
        const FVector Current = OutResult.CameraPose.GetLocation();
        OutResult.CameraPose.SetLocation(Current + FVector(0.0, 60.0, 20.0));
    }
};

上面只是骨架。真实项目里你会用 TCameraParameterReader 读取参数、在 OnBuild 注册需要的变量或上下文数据,并在 DebugBlock 里输出当前偏移值。

使用案例

如果你要做“右肩/左肩切换”,优先把肩位做成 FVector3dCameraParameter,由参数覆盖或变量驱动;如果你要做“目标太高时镜头自动抬一点,并且要参与调试”,再考虑自定义 Node。判断标准是:它是否需要访问运行时上下文、是否在多个 Rig 中复用、是否需要 Debug 输出。

项目落地

先用内置节点搭出 80% 行为。只有当你发现同一类逻辑在多个 Rig 里重复,并且需要访问项目数据时,才写自定义节点。资产层面保持 Rig 小而清楚:Follow Rig 管跟随,Aim Rig 管瞄准,Dialogue Rig 管对话构图,不要在一个 Rig 里用一堆开关模拟所有状态。

常见坑

  • 把 Camera Asset 当成 Rig:Asset 是入口,Rig 才是节点树。
  • 忽略 Build:Rig/Asset 会生成运行时分配信息和参数定义,Dirty 状态要处理。
  • 自定义节点里直接找世界对象:优先通过 EvaluationContext、变量或 Context Data 传入。
  • 一个节点既改 Location 又管输入又管碰撞:职责太大,后期无法调试。

源码依据

UCameraAssetBuildCamera 会构建并验证所有 Camera Rig;UCameraRigAssetRootNode 是节点树入口;UCameraNodeOnBuildEvaluator 产生运行时 Evaluator;FCameraNodeEvaluationResult 里包含可修改的 CameraPose、VariableTable、ContextDataTable 和 PostProcess。

源码路径索引

  • GameplayCameras/Public/Core/CameraAsset.h
  • GameplayCameras/Public/Core/CameraRigAsset.h
  • GameplayCameras/Public/Core/CameraNode.h
  • GameplayCameras/Public/Core/CameraNodeEvaluator.h