Add prototype gameplay loop with character/battlefield assets and server game APIs.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public static class MeasureClipMotion
|
||||
{
|
||||
public static string Run()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var name in new[] { "Idle", "Walk", "Attack" })
|
||||
{
|
||||
var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>($"Assets/Bundles/Characters/Animal/RockBall/Clips/{name}.anim");
|
||||
if (clip == null) { sb.AppendLine(name + " missing"); continue; }
|
||||
var binds = AnimationUtility.GetCurveBindings(clip);
|
||||
float maxRange = 0f;
|
||||
string maxBind = "";
|
||||
int moving = 0;
|
||||
foreach (var b in binds)
|
||||
{
|
||||
var c = AnimationUtility.GetEditorCurve(clip, b);
|
||||
if (c == null || c.keys.Length == 0) continue;
|
||||
float mn = float.MaxValue, mx = float.MinValue;
|
||||
foreach (var k in c.keys) { if (k.value < mn) mn = k.value; if (k.value > mx) mx = k.value; }
|
||||
// also sample densely
|
||||
for (float t = 0; t <= clip.length; t += clip.length / 20f)
|
||||
{
|
||||
float v = c.Evaluate(t);
|
||||
if (v < mn) mn = v; if (v > mx) mx = v;
|
||||
}
|
||||
float range = mx - mn;
|
||||
if (range > 1e-4f) moving++;
|
||||
if (range > maxRange) { maxRange = range; maxBind = b.path + "/" + b.propertyName; }
|
||||
}
|
||||
sb.AppendLine($"{name}: len={clip.length:F3} binds={binds.Length} movingCurves={moving} maxRange={maxRange:F5} at {maxBind}");
|
||||
}
|
||||
|
||||
// Compare bone rest vs sampled pose at mid Walk on instantiated prefab
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/Characters/Animal/RockBall/RockBall_Rigged.prefab");
|
||||
var go = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
|
||||
var anim = go.GetComponentInChildren<Animator>();
|
||||
anim.SetInteger("Motion", 1);
|
||||
anim.Update(0f);
|
||||
// record bone rotations at t=0 and after scrubbing
|
||||
var bones = go.GetComponentsInChildren<Transform>().Where(t => t.name.StartsWith("bone_")).ToArray();
|
||||
var r0 = bones.Select(b => b.localRotation).ToArray();
|
||||
for (int i = 0; i < 30; i++) anim.Update(0.05f);
|
||||
float maxAng = 0f;
|
||||
string which = "";
|
||||
for (int i = 0; i < bones.Length; i++)
|
||||
{
|
||||
float ang = Quaternion.Angle(r0[i], bones[i].localRotation);
|
||||
if (ang > maxAng) { maxAng = ang; which = bones[i].name; }
|
||||
}
|
||||
sb.AppendLine($"prefab Walk scrub 1.5s maxBoneDeltaDeg={maxAng:F2} bone={which}");
|
||||
Object.DestroyImmediate(go);
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user