如何用Python修改Maya播放栏关键帧旋转值并映射角度至0-360度
解决方案
先实现角度映射函数,把任意角度转成0 < angle < 360的范围:
def map_angle_to_360(angle): # 取模运算自动处理正负角度,负数会转为等效正角度 mapped = angle % 360 # 满足0 < angle < 360的要求,将刚好为0的角度转为360 return 360.0 if mapped == 0 else mapped
以下是修正并完善后的完整代码,解决原代码的关键帧访问问题,同时优化对象获取逻辑:
import maya.cmds as cmds def map_angle_to_360(angle): mapped = angle % 360 return 360.0 if mapped == 0 else mapped # 获取选中的、名称包含_SET的组 selected_grps = [grp for grp in cmds.ls(selection=True, type='transform') if "_SET" in grp] objs = [] for grp in selected_grps: # 递归获取组下所有网格对象(如果只需要直接子级,去掉allDescendents=True) descendants = cmds.listRelatives(grp, allDescendents=True, type='mesh', fullPath=True) if descendants: # 关键帧存储在网格的transform父节点上,所以取对应transform obj_transforms = [cmds.listRelatives(mesh, parent=True, fullPath=True)[0] for mesh in descendants] objs.extend(obj_transforms) # 去重,避免重复处理同一对象 objs = list(set(objs)) attributes = ['rotateX', 'rotateY', 'rotateZ'] for obj in objs: for attr in attributes: # 获取当前属性的所有关键帧时间点 key_times = cmds.keyframe(obj, attribute=attr, query=True, timeChange=True) if not key_times: continue # 该属性无关键帧,直接跳过 for time in key_times: # 读取当前时间点的旋转值 current_angle = cmds.getAttr(f"{obj}.{attr}", time=time) # 映射到目标范围 new_angle = map_angle_to_360(current_angle) # 重新设置关键帧值 cmds.setKeyframe(obj, attribute=attr, time=time, value=new_angle) print("关键帧旋转角度映射完成")
关键修正与说明
- 针对你提到的选中组需求,改为从选中列表里筛选带
_SET的组,更贴合实际操作场景 - 增加了
listRelatives返回空值的判断,避免运行报错 - 明确获取网格对应的transform节点(关键帧数据存储在transform上,而非mesh对象本身)
- 逐个遍历对象的每个旋转属性,直接访问每个关键帧的时间点,读取值、映射后重新设置关键帧
- 角度映射用取模运算自动处理正负角度,再调整0值的情况,严格满足
0 < angle < 360的要求
内容的提问来源于stack exchange,提问作者Kartikey Sinha
相关产品推荐
相关产品推荐

