如何用Blender内置Python工具将髋骨位移动画复制到根骨
解决Blender中骨骼动画关键帧批量迁移问题
问题背景
原本计划将位移动画放在根骨骼_rootJoint,旋转动画放在其子级髋骨CG_02,但误将所有动画(包括位移)都集中在髋骨上,导致游戏引擎无法正常使用Root Motion。由于涉及近百个动画,需要通过Blender Python脚本批量处理,将髋骨的位移关键帧复制到根骨,并移除髋骨上的对应关键帧。
完整解决方案代码
import bpy # 获取骨骼所属的Armature对象 armature = bpy.data.objects["Armature"] # 目标骨骼名称(需与文件内骨骼名完全匹配) root_bone_name = "_rootJoint" hips_bone_name = "CG_02" # 遍历所有动作(若需仅处理选中动作,替换为bpy.context.selected_editable_actions) for action in bpy.data.actions: # 暂存需要删除的髋骨位置曲线 hips_location_curves = [] # 遍历动作内的所有动画曲线 for fcurve in action.fcurves: # 筛选出髋骨的位置属性曲线 if fcurve.data_path.startswith(f'pose.bones["{hips_bone_name}"].location'): hips_location_curves.append(fcurve) # 定位或创建根骨对应的位置曲线 root_data_path = f'pose.bones["{root_bone_name}"].location' root_fcurve = None for rf in action.fcurves: if rf.data_path == root_data_path and rf.array_index == fcurve.array_index: root_fcurve = rf break # 若根骨无对应曲线则新建 if not root_fcurve: root_fcurve = action.fcurves.new(data_path=root_data_path, index=fcurve.array_index) # 复制关键帧的所有属性(时间、数值、插值、手柄等) for keyframe in fcurve.keyframe_points: root_fcurve.keyframe_points.insert( frame=keyframe.co[0], value=keyframe.co[1], options={'FAST'} ) # 同步关键帧的插值与手柄设置 new_key = root_fcurve.keyframe_points[-1] new_key.interpolation = keyframe.interpolation new_key.easing = keyframe.easing new_key.handle_left_type = keyframe.handle_left_type new_key.handle_right_type = keyframe.handle_right_type new_key.handle_left = keyframe.handle_left new_key.handle_right = keyframe.handle_right # 删除髋骨的位置曲线 for curve in hips_location_curves: action.fcurves.remove(curve) # 刷新动作数据确保修改生效 action.update()
关键说明
- 骨骼对象定位:动画关键帧关联的是
pose.bones(姿态模式下的骨骼),而非编辑模式的data.bones,脚本中需通过动作的FCurve.data_path匹配目标骨骼。 - 关键帧完整复制:不仅复制关键帧的时间和数值,还同步了插值类型、手柄类型等属性,保证动画效果完全一致。
- 批量处理范围:默认遍历所有动作,若需仅处理选中动作,将
bpy.data.actions替换为bpy.context.selected_editable_actions即可。 - NLA动作处理:若动画存储在NLA轨道中,需先将NLA片段分离为独立动作(NLA编辑器中右键选择「分离动作」),再运行脚本。
内容的提问来源于stack exchange,提问作者Iceball 457
相关产品推荐
相关产品推荐

