78 lines
4.4 KiB
C#
78 lines
4.4 KiB
C#
#if UNITY_EDITOR
|
|
using System.Linq;
|
|
using System.Text;
|
|
using UnityEditor;
|
|
using UnityEditor.Animations;
|
|
using UnityEngine;
|
|
|
|
public static class DiagnoseRockBallAnim
|
|
{
|
|
public static string Run()
|
|
{
|
|
var sb = new StringBuilder();
|
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/Characters/Animal/RockBall/RockBall_Rigged.prefab");
|
|
if (prefab == null) return "missing prefab";
|
|
var inst = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
|
|
var anim = inst.GetComponentInChildren<Animator>(true);
|
|
sb.AppendLine("animator=" + (anim != null) + " ctrl=" + (anim != null && anim.runtimeAnimatorController != null));
|
|
if (anim != null)
|
|
{
|
|
sb.AppendLine("avatar=" + (anim.avatar != null ? anim.avatar.name + " isValid=" + anim.avatar.isValid + " isHuman=" + anim.avatar.isHuman : "null"));
|
|
sb.AppendLine("applyRootMotion=" + anim.applyRootMotion + " culling=" + anim.cullingMode);
|
|
foreach (var p in anim.parameters) sb.AppendLine("param " + p.name + " " + p.type);
|
|
var ctrl = anim.runtimeAnimatorController as AnimatorController;
|
|
if (ctrl != null)
|
|
{
|
|
foreach (var s in ctrl.layers[0].stateMachine.states)
|
|
{
|
|
var clip = s.state.motion as AnimationClip;
|
|
sb.AppendLine("state " + s.state.name + " clip=" + (clip != null ? clip.name + " len=" + clip.length + " empty=" + clip.empty + " curves=" + AnimationUtility.GetCurveBindings(clip).Length + " objBindings=" + AnimationUtility.GetObjectReferenceCurveBindings(clip).Length : "null"));
|
|
if (clip != null)
|
|
{
|
|
var binds = AnimationUtility.GetCurveBindings(clip);
|
|
foreach (var b in binds.Take(12))
|
|
sb.AppendLine(" bind " + b.path + " / " + b.propertyName);
|
|
// sample a few key values
|
|
if (binds.Length > 0)
|
|
{
|
|
var c = AnimationUtility.GetEditorCurve(clip, binds[0]);
|
|
if (c != null && c.keys.Length > 0)
|
|
sb.AppendLine(" firstCurve keys=" + c.keys.Length + " t0=" + c.keys[0].value + " tmid=" + c.Evaluate(clip.length * 0.5f));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// bone names under model
|
|
var bones = inst.GetComponentsInChildren<Transform>(true).Select(t => t.name).Where(n => n.StartsWith("bone") || n.Contains("Armature") || n.Contains("Root")).Take(30);
|
|
sb.AppendLine("bones: " + string.Join(", ", bones));
|
|
var skins = inst.GetComponentsInChildren<SkinnedMeshRenderer>(true);
|
|
foreach (var sk in skins)
|
|
sb.AppendLine("skin " + sk.name + " bones=" + (sk.bones != null ? sk.bones.Length : 0) + " root=" + (sk.rootBone != null ? sk.rootBone.name : "null") + " mesh=" + (sk.sharedMesh != null ? sk.sharedMesh.name + " v=" + sk.sharedMesh.vertexCount : "null"));
|
|
}
|
|
Object.DestroyImmediate(inst);
|
|
|
|
// also inspect anim fbx clips directly
|
|
foreach (var clipName in new[] { "Idle", "Walk", "Attack" })
|
|
{
|
|
var path = "Assets/Bundles/Characters/Animal/RockBall/Anims/RockBall_" + clipName + ".fbx";
|
|
var clips = AssetDatabase.LoadAllAssetsAtPath(path).OfType<AnimationClip>().Where(c => !c.name.StartsWith("__preview__")).ToArray();
|
|
sb.AppendLine("fbx " + clipName + " clips=" + clips.Length);
|
|
foreach (var clip in clips)
|
|
{
|
|
var binds = AnimationUtility.GetCurveBindings(clip);
|
|
sb.AppendLine(" " + clip.name + " len=" + clip.length + " binds=" + binds.Length + " empty=" + clip.empty);
|
|
foreach (var b in binds.Take(8)) sb.AppendLine(" " + b.path + " / " + b.propertyName);
|
|
}
|
|
var named = "Assets/Bundles/Characters/Animal/RockBall/Clips/" + clipName + ".anim";
|
|
var namedClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(named);
|
|
if (namedClip != null)
|
|
{
|
|
var binds = AnimationUtility.GetCurveBindings(namedClip);
|
|
sb.AppendLine(" named.anim binds=" + binds.Length + " len=" + namedClip.length);
|
|
}
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
#endif
|