IKRigaddsolver_新旧版本差异
# UE IKRig add_solver 新旧版本差异:从 UIKRigSolver 到 FIKRigSolverBase
# 背景
在使用 Python 自动化搭建 IK Rig 时,很多人会遇到同一个问题:
- 旧教程里写的
IKRigFBIKSolver还能不能直接传给add_solver? - 为什么有的版本传字符串能成功,有的版本会报找不到类型?
FullBodyIKSolver、IKRigFullBodyIKSolver、IKRigFBIKSolver到底该用哪个?
这篇文章聚焦 UE5.6+(包含 5.7)中 IKRig 的“新旧架构切换”,并给出可直接复制的调用方式。
# 一句话结论
在 UE5.6+ 中,IKRigController.add_solver() 应该传 新 UStruct Solver 的类型路径,而不是旧 UObject Solver 类名。
FBIK 场景优先使用:
controller.add_solver("/Script/IKRig.IKRigFullBodyIKSolver")
1
# 旧版 vs 新版:核心差异
# 1) 旧版(Legacy)
- 以
UIKRigSolver(UObject)为核心 - 典型名称:
UIKRigFBIKSolver - 更偏编辑器对象模型,运行时不够轻量
# 2) 新版(5.6+ 主流)
- 以
FIKRigSolverBase(UStruct)为核心 - Solver 栈存储为
TArray<FInstancedStruct> - 典型名称:
FIKRigFullBodyIKSolver、FIKRigLimbSolver等 - 更适合运行时和数据驱动流程
# 为什么会“看起来都存在”但调用表现不同?
因为 Epic 为兼容旧资产,保留了部分旧类与重定向逻辑:
- 你还能在代码/生成头文件里看到
UIKRigFBIKSolver - 但
add_solver走的是新 Solver 栈(FIKRigSolverBase子类) - 旧类主要用于 升级/转换路径,不是新项目首选入口
这就是“类还在,但新增流程应该用新类型”的根本原因。
# add_solver 期望的参数类型
UIKRigController::AddSolver(const FString InIKRigSolverType) 的语义是:
- 传入
UStruct类型的完整路径字符串 - 内部会
FindObject<UScriptStruct>去找类型 - 并校验是否是
FIKRigSolverBase子类
因此,参数本质上是“可被解析到的 Solver UStruct 路径”。
# UE5.7 可用 Solver(常见)
在 IKRig 插件源码中可对应到以下新 Solver:
/Script/IKRig.IKRigFullBodyIKSolver/Script/IKRig.IKRigLimbSolver/Script/IKRig.IKRigPoleSolver/Script/IKRig.IKRigStretchLimbSolver/Script/IKRig.IKRigBodyMoverSolver
其中做全身 IK(FBIK)时,通常选择 IKRigFullBodyIKSolver。
# 推荐写法(Python)
import unreal
ik_rig = unreal.load_asset("/Game/MyIKRigAsset")
controller = unreal.IKRigController.get_controller(ik_rig)
solver_index = controller.add_solver("/Script/IKRig.IKRigFullBodyIKSolver")
if solver_index == -1:
unreal.log_error("add_solver 失败:请检查类型路径、插件版本或API可见性")
else:
unreal.log(f"已添加 FBIK Solver,索引: {solver_index}")
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 兼容性策略(建议用于工具脚本)
如果你需要兼容多个 UE 版本,建议做“新优先,旧兜底”:
- 先尝试新类型路径(
IKRigFullBodyIKSolver) - 失败再尝试旧名称/旧流程
- 在日志中打印当前引擎版本与实际命中分支
示例思路:
candidate_types = [
"/Script/IKRig.IKRigFullBodyIKSolver", # 5.6+ 首选
"/Script/IKRig.FullBodyIKSolver", # 某些文档/注释中的旧示例
]
solver_index = -1
for t in candidate_types:
solver_index = controller.add_solver(t)
if solver_index != -1:
unreal.log(f"命中 solver 类型: {t}")
break
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
注:是否需要保留
FullBodyIKSolver这个候选,取决于你实际项目中的引擎分支与二次修改情况。
# 常见坑位排查清单
- 传了显示名而不是类型路径(例如只传
FullBodyIKSolver) - 路径拼写错误(大小写、前缀
/Script/IKRig.) - 使用了旧教程里的
UIKRigFBIKSolver作为新增入口 - IKRig 插件未启用或 Python API 版本与引擎不一致
- 资产控制器拿错对象(不是
IKRigDefinition对应的 controller)
# 迁移建议(旧脚本升级到 5.7)
- 把“新增 Solver”的入口统一迁移到新 UStruct 路径
- 将“类型名常量”集中在一个映射表里,避免散落硬编码
- 给
add_solver返回值做统一断言与日志封装 - 在 CI/批处理脚本里增加最小自检(创建临时资产并测试添加 Solver)
# 总结
add_solver 的新旧版本差异,本质是 IKRig 架构从 UObject Solver 向 UStruct Solver 的演进。
在 UE5.6+(尤其 5.7)里,新增 Solver 请以 FIKRigSolverBase 派生结构体为准,最稳妥的 FBIK 调用是:
/Script/IKRig.IKRigFullBodyIKSolver
只要把“新增入口”统一切到新类型路径,绝大多数兼容问题都能一次性收敛。
