unreal导出MH关键帧


原文地址 :https://blog.l0v0.com/posts/1b238b83.html

思路:用 unreal python 读取关键帧数据导出 json,Maya 再读取数据设置关键帧到控制器上。

# Import built-in modules
from collections import defaultdict
import json
import os

# Import local modules
import unreal

DIR = os.path.dirname(os.path.abspath(__file__))

def unreal_progress(tasks, label="进度", total=None):
    total = total if total else len(tasks)
    with unreal.ScopedSlowTask(total, label) as task:
        task.make_dialog(True)
        for i, item in enumerate(tasks):
            if task.should_cancel():
                break
            task.enter_progress_frame(1, "%s %s/%s" % (label, i, total))
            yield item


def main():
    # NOTE: 读取 sequence
    sequence = unreal.load_asset('/Game/Sequencer/MetaHumanSample_Sequence.MetaHumanSample_Sequence')
    # NOTE: 收集 sequence 里面所有的 binding
    binding_dict = defaultdict(list)
    for binding in sequence.get_bindings():
        binding_dict[binding.get_name()].append(binding)

    # NOTE: 遍历命名为 Face 的 binding
    for binding in unreal_progress(binding_dict.get("Face", []), "导出 Face 数据"):
        # NOTE: 获取关键帧 channel 数据
        keys_dict = {}
        for track in binding.get_tracks():
            for section in track.get_sections():
                for channel in unreal_progress(section.get_channels(), "导出关键帧"):
                    if not channel.get_num_keys():
                        continue
                    keys = []
                    for key in channel.get_keys():
                        frame_time = key.get_time()
                        frame = frame_time.frame_number.value + frame_time.sub_frame
                        keys.append({"frame": frame, "value": key.get_value()})

                    keys_dict[channel.get_name()] = keys

        # NOTE: 导出 json
        name = binding.get_parent().get_name()
        export_path = os.path.join(DIR, "{0}.json".format(name))
        with open(export_path, "w") as wf:
            json.dump(keys_dict, wf, indent=4)

上面的脚本会定位 MetaHuman 的 sequence 资源,然后导出关键帧的信息为 json

# Import built-in modules
import json
import os
import traceback

# Import third-party modules
import pymel.core as pm

DIR = os.path.dirname(os.path.abspath(__file__))


def progress(seq, status="", title=""):
    pm.progressWindow(status=status, title=title, progress=0.0, isInterruptable=True)
    total = len(seq)
    for i, item in enumerate(seq):
        try:
            if pm.progressWindow(query=True, isCancelled=True):
                break
            pm.progressWindow(e=True, progress=float(i) / total * 100)
            yield item  # with body executes here
        except:
            traceback.print_exc()
            pm.progressWindow(ep=1)
    pm.progressWindow(ep=1)


def main():

    # NOTE: 读取数据
    with open(os.path.join(DIR, "BP_metahuman_001.json"), "r") as rf:
        data = json.load(rf)

    attr_map = {"location": "t", "rotation": "r"}
    status = "Import Keyframe to metahuman controller"
    
    # NOTE: undo 支持
    pm.undoInfo(ock=1)
    for channel, frame_list in progress(data.items(), status=status):
        # NOTE: 解析 channel_name
        has_attr = channel.count(".")
        
        if not has_attr:
            # NOTE: 处理 `CTRL_C_eye_parallelLook_4311` 格式
            ctrl_name = channel.rsplit("_", 1)[0]
            attr = "ty"
        else:
            parts = iter(channel.split("."))
            ctrl_name = next(parts, "")
            param = next(parts, "")
            axis = next(parts, "")
            if not axis:
                # NOTE: 处理 `CTRL_C_teethD.Y_4330` 格式
                attr = "t"
                axis = param
            else:
                # NOTE: 处理 `CTRL_L_eyeAim.Rotation.Y_4387` 格式
                attr = attr_map.get(param.lower())
            attr += axis.split("_")[0].lower()

        # NOTE: 解析出控制器属性设置关键帧
        attribute = pm.PyNode(".".join([ctrl_name, attr]))
        for frame_data in frame_list:
            frame = frame_data.get("frame")
            value = frame_data.get("value")
            attribute.setKey(t=frame, v=value)

    pm.undoInfo(cck=1)

maya中加载json数据


评论
  目录