Files
DreadScripts-Archive/ResetHumanoid/Editor/ResetHumanoid.cs
2025-07-19 01:03:02 +02:00

121 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace DreadScripts.ResetHumanoid
{
public class ResetHumanoid : EditorWindow
{
private static Animator ani;
private static bool full;
private static bool pos = true, rot = true, scale = true;
[MenuItem("DreadTools/Utility/Reset Humanoid")]
private static void showWindow()
{
GetWindow<ResetHumanoid>(false, "Reset Humanoid", true);
if (ani == null) ani = FindObjectOfType<Animator>();
}
private void OnGUI()
{
EditorGUIUtility.labelWidth = 60;
ani = (Animator) EditorGUILayout.ObjectField("Avatar", ani, typeof(Animator), true);
EditorGUILayout.BeginHorizontal();
pos = EditorGUILayout.Toggle("Position", pos);
rot = EditorGUILayout.Toggle("Rotation", rot);
scale = EditorGUILayout.Toggle("Scale", scale);
EditorGUIUtility.labelWidth = 0;
EditorGUILayout.EndHorizontal();
full = EditorGUILayout.Toggle(new GUIContent("Full Reset", "Reset includes the objects that the Model was imported with"), full);
if (GUILayout.Button("Reset"))
ResetPose(ani, full, pos, rot, scale);
}
public static void ResetPose(Animator ani, bool fullReset = false, bool position = true, bool rotation = true, bool scale = true)
{
if (!ani.avatar)
{
Debug.LogWarning("Avatar is required to reset pose!");
return;
}
// Humans IDs if not full reset, otherwise All Ids
// ID > Path
// ID > Element > Transform Data
Undo.RegisterFullObjectHierarchyUndo(ani.gameObject, "HierarchyReset");
SerializedObject sAvi = new SerializedObject(ani.avatar);
SerializedProperty humanIds = sAvi.FindProperty("m_Avatar.m_Human.data.m_Skeleton.data.m_ID");
SerializedProperty allIds = sAvi.FindProperty("m_Avatar.m_AvatarSkeleton.data.m_ID");
SerializedProperty defaultPose = sAvi.FindProperty("m_Avatar.m_DefaultPose.data.m_X");
SerializedProperty tos = sAvi.FindProperty("m_TOS");
Dictionary<long, int> idToElem = new Dictionary<long, int>();
Dictionary<int, TransformData> elemToTransform = new Dictionary<int, TransformData>();
Dictionary<long, string> IdToPath = new Dictionary<long, string>();
for (int i = 0; i < allIds.arraySize; i++)
idToElem.Add(allIds.GetArrayElementAtIndex(i).longValue, i);
for (int i = 0; i < defaultPose.arraySize; i++)
elemToTransform.Add(i, new TransformData(defaultPose.GetArrayElementAtIndex(i)));
for (int i = 0; i < tos.arraySize; i++)
{
SerializedProperty currProp = tos.GetArrayElementAtIndex(i);
IdToPath.Add(currProp.FindPropertyRelative("first").longValue, currProp.FindPropertyRelative("second").stringValue);
}
Action<Transform, TransformData> applyTransform = (transform, data) =>
{
if (transform)
{
if (position)
transform.localPosition = data.pos;
if (rotation)
transform.localRotation = data.rot;
if (scale)
transform.localScale = data.scale;
}
};
if (!fullReset)
{
for (int i = 0; i < humanIds.arraySize; i++)
{
Transform myBone = ani.transform.Find(IdToPath[humanIds.GetArrayElementAtIndex(i).longValue]);
TransformData data = elemToTransform[idToElem[humanIds.GetArrayElementAtIndex(i).longValue]];
applyTransform(myBone, data);
}
}
else
{
for (int i = 0; i < allIds.arraySize; i++)
{
Transform myBone = ani.transform.Find(IdToPath[allIds.GetArrayElementAtIndex(i).longValue]);
TransformData data = elemToTransform[idToElem[allIds.GetArrayElementAtIndex(i).longValue]];
applyTransform(myBone, data);
}
}
}
struct TransformData
{
public Vector3 pos;
public Quaternion rot;
public Vector3 scale;
public TransformData(SerializedProperty t)
{
SerializedProperty tProp = t.FindPropertyRelative("t");
SerializedProperty qProp = t.FindPropertyRelative("q");
SerializedProperty sProp = t.FindPropertyRelative("s");
pos = new Vector3(tProp.FindPropertyRelative("x").floatValue, tProp.FindPropertyRelative("y").floatValue, tProp.FindPropertyRelative("z").floatValue);
rot = new Quaternion(qProp.FindPropertyRelative("x").floatValue, qProp.FindPropertyRelative("y").floatValue, qProp.FindPropertyRelative("z").floatValue, qProp.FindPropertyRelative("w").floatValue);
scale = new Vector3(sProp.FindPropertyRelative("x").floatValue, sProp.FindPropertyRelative("y").floatValue, sProp.FindPropertyRelative("z").floatValue);
}
}
}
}