Skip to content

Instantly share code, notes, and snippets.

@Keshigom
Last active November 11, 2022 13:45
Show Gist options
  • Save Keshigom/d450469b8b2de1a2b716d892fddac24b to your computer and use it in GitHub Desktop.
Save Keshigom/d450469b8b2de1a2b716d892fddac24b to your computer and use it in GitHub Desktop.
/*
* This code (VRMPoseImporter.cs) is licensed under CC0.
* http://creativecommons.org/publicdomain/zero/1.0/deed.ja
*/
using UnityEngine;
using System;
using System.IO;
using System.Reflection;
public class VRMPoseImporter : MonoBehaviour
{
public string filePath;
public void loadJson(string path)
{
string json = File.ReadAllText(path);
PoseItem poseItem = JsonUtility.FromJson<PoseItem>(json);
applyPose(poseItem);
}
[ContextMenu("load json")]
public void reload()
{
string json = File.ReadAllText(filePath);
PoseItem poseItem = JsonUtility.FromJson<PoseItem>(json);
applyPose(poseItem);
}
private Animator humanoidAnimator;
private void applyPose(PoseItem poseItem)
{
humanoidAnimator = GetComponent<Animator>();
Type type = poseItem.GetType();
foreach (FieldInfo field in type.GetFields())
{
BoneItem boneItem = (BoneItem)field.GetValue(poseItem);
if (boneItem.rotation != null)
{
applyBoneRotaiton(field.Name, boneItem.rotation);
}
}
}
private void applyBoneRotaiton(string name, float[] rotation)
{
if (humanoidAnimator != null)
{
string boneName = Char.ToUpper(name[0]) + name.Substring(1);
HumanBodyBones bone = (HumanBodyBones)Enum.Parse(typeof(HumanBodyBones), boneName);
var boneTrans = humanoidAnimator.GetBoneTransform(bone);
if (boneTrans != null)
{
boneTrans.localRotation = new Quaternion(-rotation[0], -rotation[1], rotation[2], rotation[3]);
}
}
}
[System.Serializable]
public class PoseItem
{
public BoneItem chest;
public BoneItem head;
public BoneItem hips;
public BoneItem jaw;
public BoneItem leftEye;
public BoneItem leftFoot;
public BoneItem leftHand;
public BoneItem leftIndexDistal;
public BoneItem leftIndexIntermediate;
public BoneItem leftIndexProximal;
public BoneItem leftLittleDistal;
public BoneItem leftLittleIntermediate;
public BoneItem leftLittleProximal;
public BoneItem leftLowerArm;
public BoneItem leftLowerLeg;
public BoneItem leftMiddleDistal;
public BoneItem leftMiddleIntermediate;
public BoneItem leftMiddleProximal;
public BoneItem leftRingDistal;
public BoneItem leftRingIntermediate;
public BoneItem leftRingProximal;
public BoneItem leftShoulder;
public BoneItem leftThumbDistal;
public BoneItem leftThumbIntermediate;
public BoneItem leftThumbProximal;
public BoneItem leftToes;
public BoneItem leftUpperArm;
public BoneItem leftUpperLeg;
public BoneItem neck;
public BoneItem rightEye;
public BoneItem rightFoot;
public BoneItem rightHand;
public BoneItem rightIndexDistal;
public BoneItem rightIndexIntermediate;
public BoneItem rightIndexProximal;
public BoneItem rightLittleDistal;
public BoneItem rightLittleIntermediate;
public BoneItem rightLittleProximal;
public BoneItem rightLowerArm;
public BoneItem rightLowerLeg;
public BoneItem rightMiddleDistal;
public BoneItem rightMiddleIntermediate;
public BoneItem rightMiddleProximal;
public BoneItem rightRingDistal;
public BoneItem rightRingIntermediate;
public BoneItem rightRingProximal;
public BoneItem rightShoulder;
public BoneItem rightThumbDistal;
public BoneItem rightThumbIntermediate;
public BoneItem rightThumbProximal;
public BoneItem rightToes;
public BoneItem rightUpperArm;
public BoneItem rightUpperLeg;
public BoneItem spine;
public BoneItem upperChest;
}
[System.Serializable]
public class BoneItem
{
// positionは必須でない
// public double[] position;
// 関節角度の四元数
public float[] rotation;
}
}
// https://warapuri.com/post/24185933889/unity-inspector-editor%E4%B8%8A%E3%81%ABdragdrop%E3%81%97%E3%81%9F%E3%81%84
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
[CustomEditor(typeof(VRMPoseImporter))]
public class VRMPoseImporterEditor : Editor
{
private SerializedObject m_Object;
private SerializedProperty m_FilePath;
public void OnEnable()
{
m_Object = new SerializedObject(target);
m_FilePath = m_Object.FindProperty("filePath");
}
public override void OnInspectorGUI()
{
m_Object.Update();
GUILayout.Label("Soldier Properties", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_FilePath);
var evt = Event.current;
var dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
GUI.Box(dropArea, "Drag & Drop");
int id = GUIUtility.GetControlID(FocusType.Passive);
switch (evt.type)
{
case EventType.DragUpdated:
case EventType.DragPerform:
if (!dropArea.Contains(evt.mousePosition)) break;
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
DragAndDrop.activeControlID = id;
if (evt.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
foreach (var draggedObject in DragAndDrop.objectReferences)
{
Debug.Log("Drag Object:" + AssetDatabase.GetAssetPath(draggedObject));
m_FilePath.stringValue = AssetDatabase.GetAssetPath(draggedObject);
VRMPoseImporter targetComp = target as VRMPoseImporter;
targetComp.loadJson(AssetDatabase.GetAssetPath(draggedObject));
}
DragAndDrop.activeControlID = 0;
}
Event.current.Use();
break;
}
m_Object.ApplyModifiedProperties();
}
}
https://scrapbox.io/ke456memo/YATTA!駆動開発_No.07_「VRMお手軽ポーズのjsonをUnityで読み込む」
のプログラム
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment