Unityのエディタでシーンビュー内でつけたポーズをBlenderにもっていく方法
1. Unity側のスクリプトをポーズを付けたFBXにアタッチしてレストポーズにしたFBXを
referenceModelとして設定する。
ポーズを付けたFBXのrootBoneと出力先のパスを設定する。
2. インスペクター上で右クリックでExportBoneData
3. Blender側のスクリプトでアーマチュアの名前と読み込むポーズのファイルのパスを設定して RunScript
↓Unity側
using System.Collections.Generic;
using UnityEngine;
using System.IO;
[System.Serializable]
public class BoneData
{
public string name;
public Vector3 position;
public Vector3 scale;
public Quaternion rotation; // This will be Q_relative
}
[System.Serializable]
public class BoneDataList
{
public List<BoneData> bones = new List<BoneData>();
}
public class BoneDataExporter : MonoBehaviour
{
public Transform rootBone;
public GameObject referenceModel; // Add a field for the reference model
public string boneDataPath = "Assets/boneData.json";
[ContextMenu("Export Bone Data")]
void ExportBoneData()
{
BoneDataList boneDataList = new BoneDataList();
CollectBoneData(rootBone, boneDataList.bones, referenceModel.transform);
string json = JsonUtility.ToJson(boneDataList, true);
File.WriteAllText(boneDataPath, json);
Debug.Log("Bone data exported!");
}
void CollectBoneData(Transform bone, List<BoneData> boneData, Transform reference)
{
// Find the same bone in the reference model by name
Transform referenceBone = reference.FindChildRecursive(bone.name);
Quaternion Q0 = referenceBone != null ? referenceBone.localRotation : Quaternion.identity;
Quaternion Q = bone.localRotation;
Quaternion Q0_inv= Quaternion.Inverse(Q0);
Quaternion Q_relative =Q0_inv*Q;
Quaternion Q_final = new Quaternion(Q_relative.x, -Q_relative.y, -Q_relative.z, Q_relative.w);
boneData.Add(new BoneData
{
name = bone.name,
position = bone.localPosition,
scale = bone.localScale,
rotation = Q_final // Store the relative rotation
});
foreach (Transform child in bone)
{
CollectBoneData(child, boneData, reference);
}
}
}
↓Blender側
import bpy
import json
def apply_pose(armature_name, json_path):
with open(json_path, 'r') as f:
data = json.load(f)
armature = bpy.data.objects[armature_name]
bpy.context.view_layer.objects.active = armature
bpy.ops.object.mode_set(mode='POSE')
for bone_data in data['bones']:
bone = armature.pose.bones.get(bone_data['name'])
if bone:
bone.location = (bone_data['position']['x'], bone_data['position']['y'], bone_data['position']['z'])
bone.scale = (bone_data['scale']['x'], bone_data['scale']['y'], bone_data['scale']['z'])
# 注意:四元数は (w, x, y, z) の順で設定
bone.rotation_quaternion = (bone_data['rotation']['w'], bone_data['rotation']['x'], bone_data['rotation']['y'], bone_data['rotation']['z'])
# Save the pose
bpy.ops.object.posemode_toggle()
bpy.ops.wm.save_mainfile()
# ファイルパスは適宜設定してください
apply_pose('RobinArmature', 'C:boneData.json')