--- title: Animation date: 2026-05-03 00:00:00 excerpt: ARC 引擎动画系统修改:常量关键帧压缩、FBX 导入扩展 tags: - ARC - Animation rating: ⭐ --- # Animation — 动画系统 返回 [[ARC引擎修改总览]] ## 概述 ARC 引擎的动画系统修改围绕**格斗游戏对帧精确动画的需求**展开。格斗游戏的攻击判定、无敌帧等核心机制要求动画必须以固定帧率精确播放,不能有插值误差。 ## 功能列表 | 功能 | 说明 | |------|------| | 常量关键帧压缩 | 60fps 帧限动画、4F 间隔校正 | | FBX 导入扩展 | RED 动画数据、轮廓线 ID、首末帧处理 | ## 常量关键帧压缩 ### 概述 新增 `AnimCompress_Constant` 压缩方案,将动画关键帧限定在 60fps 的固定帧率网格上。格斗游戏的核心机制(攻击判定、无敌帧、帧优势等)要求动画在每一帧的状态都是确定性的,不能依赖插值。 ### 实现 #### AnimCompress_Constant ```cpp // AnimCompress_Constant.h/.cpp // 常量关键帧插值 — 不做帧间插值,直接使用最近的关键帧 ``` 核心行为: - 每帧独立存储(不做 delta 编码) - 运行时取值不做线性插值,直接 snap 到最近关键帧 - 确保 60fps 下每帧状态与 DCC 工具导出完全一致 #### 4F 间隔自动校正 Avatar 动画使用 4 帧间隔(15fps 的关键帧),自动校正导入的帧时间到 4F 网格: ``` 原始帧: 0, 3, 7, 11, ... 校正后: 0, 4, 8, 12, ... (snap 到 4F 倍数) ``` #### AnimCompress_Automatic 扩展 标准 UE4 的 `AnimCompress_Automatic` 也被扩展以支持常量帧模式选项。 ### 完整代码解析 ```cpp // AnimCompress_Constant.h/.cpp // 常量关键帧压缩 — 不做帧间插值 class UAnimCompress_Constant : public UAnimCompress { // 每帧独立存储位置/旋转/缩放 // 运行时取值 snap 到最近关键帧(不做线性插值) // 确保 60fps 下每帧状态确定性 // 4F 间隔自动校正(Avatar 动画): // 将导入的帧时间 snap 到 4 帧倍数 // 原始帧: 0, 3, 7, 11, ... // 校正后: 0, 4, 8, 12, ... }; ``` ### 关联文档 - [[Animation#FBX 导入扩展]] — `bImportREDAnimationData` 控制导入时的帧限处理 ### 代码修改情况 | 文件路径 | 修改类型 | 修改内容 | |---------|---------|---------| | `Source/Runtime/Engine/Public/Animation/AnimCompress_Constant.h` | **新增文件** | 常量关键帧压缩类声明 | | `Source/Runtime/Engine/Private/Animation/AnimCompress_Constant.cpp` | **新增文件** | 实现:无插值采样 + 4F 间隔校正 | | `Source/Runtime/Engine/Public/Animation/AnimCompress_Automatic.h` | 修改 | 扩展支持常量帧模式选项 | ## FBX 导入扩展 ### 概述 ARC 引擎大幅扩展了 FBX 导入功能,添加了格斗游戏和卡通渲染所需的专用数据导入支持。 ### RED 动画数据导入 `bImportREDAnimationData` 选项启用时: - 动画以 60fps 帧限模式导入 - 关键帧 snap 到固定帧率网格 - 配合常量关键帧压缩使用 ### 首末帧处理 两个独立选项: - **首帧删除** — 删除动画第一帧(DCC 工具常在第 0 帧放置 T-Pose) - **末帧复制** — 将最后一个关键帧复制到动画末尾(确保循环动画平滑衔接) ### 轮廓线 ID 导入 `OutlineIndexUVChannel` 选项指定从哪个 UV 通道导入轮廓线 ID: ``` UV Channel 0 → 标准 UV UV Channel 1 → Lightmap UV UV Channel N → OutlineID 数据(由美术在 DCC 中绘制) ``` 导入后的 OutlineID 存储在网格数据中,BasePass 时写入 GBufferD 供 [[RED自定义数据通道]] 使用。 ### 法线导入模式扩展 新增法线处理模式: ```cpp // FBXNIM_ImportNormalsAndComputeNormalsToTangents // 导入法线 + 从法线计算切线 // (标准 UE4 只有导入法线、计算法线、导入法线和切线三种) ``` ### XSI 2015 支持 扩展 FBX 导入器支持 Softimage XSI 2015 格式的 FBX 文件。 ### LOD 重导入 骨骼网格和静态网格的 LOD 重导入时保留 OutlineID 数据和 RED 自定义骨骼网格数据。 ### 完整代码解析 ```cpp // FbxImporter.h — 新增导入选项 struct FBXImportOptions { bool bImportREDAnimationData; // 启用 60fps 帧限动画导入 bool bDeleteFirstFrame; // 删除第一帧(T-Pose) bool bCopyLastFrame; // 复制末帧到动画结尾 int32 OutlineIndexUVChannel; // 轮廓线 ID 所在的 UV 通道 // -1 = 不导入 OutlineID // 0 = UV0, 1 = UV1, ... N = UVN }; // 法线导入模式扩展 enum EFBXNormalImportMethod { FBXNIM_ComputeNormals, FBXNIM_ImportNormals, FBXNIM_ImportNormalsAndTangents, FBXNIM_ImportNormalsAndComputeNormalsToTangents // <-- ASW 新增 // 导入法线 + 从导入的法线计算切线 // 标准 UE4 只支持"导入法线和切线"或"完全计算" }; ``` ### 关联文档 - [[RED自定义数据通道]] — OutlineID 的渲染端使用 ### 代码修改情况 | 文件路径 | 修改类型 | 修改内容 | |---------|---------|---------| | `Source/Editor/UnrealEd/Public/FbxImporter.h` | 修改 | 新增 `bImportREDAnimationData`、`OutlineIndexUVChannel` 等选项 | | `Source/Editor/UnrealEd/Private/Fbx/FbxAnimationImport.cpp` | 修改 | 60fps 帧限导入 + 首末帧处理 | | `Source/Editor/UnrealEd/Private/Fbx/FbxMeshImport.cpp` | 修改 | 轮廓线 ID 从 UV 通道导入 | | `Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp` | 修改 | XSI 2015 FBX 格式支持 | | `Source/Editor/UnrealEd/Private/Fbx/FbxStaticMeshImport.cpp` | 修改 | `FBXNIM_ImportNormalsAndComputeNormalsToTangents` 法线模式 | | `Source/Editor/UnrealEd/Private/SkeletalMeshEdit.cpp` | 修改 | LOD 重导入时保留 OutlineID | | `Source/Editor/UnrealEd/Private/StaticMeshEdit.cpp` | 修改 | 同上 |