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,83 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public static class DiagnoseRockBallOrient
|
||||
{
|
||||
static string Fmt(Vector3 v) => $"({v.x:F3},{v.y:F3},{v.z:F3})";
|
||||
static string FmtE(Quaternion q) => $"({q.eulerAngles.x:F1},{q.eulerAngles.y:F1},{q.eulerAngles.z:F1})";
|
||||
|
||||
static Bounds MeshBounds(GameObject go)
|
||||
{
|
||||
var rs = go.GetComponentsInChildren<Renderer>()
|
||||
.Where(r => r.name != "ForwardMinusZ" && r.GetComponent<TextMesh>() == null)
|
||||
.ToArray();
|
||||
var b = rs[0].bounds;
|
||||
for (int i = 1; i < rs.Length; i++) b.Encapsulate(rs[i].bounds);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static string Run()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var staticP = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/Characters/Animal/RockBall/RockBall.prefab");
|
||||
var rigP = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/Characters/Animal/RockBall/RockBall_Rigged.prefab");
|
||||
|
||||
var a = (GameObject)PrefabUtility.InstantiatePrefab(staticP);
|
||||
a.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
var ba = MeshBounds(a);
|
||||
sb.AppendLine($"STATIC bounds min={Fmt(ba.min)} size={Fmt(ba.size)}");
|
||||
Object.DestroyImmediate(a);
|
||||
|
||||
var b = (GameObject)PrefabUtility.InstantiatePrefab(rigP);
|
||||
b.transform.SetPositionAndRotation(new Vector3(3, 0, 0), Quaternion.identity);
|
||||
var anim = b.GetComponentInChildren<Animator>();
|
||||
var bone0 = b.GetComponentsInChildren<Transform>().FirstOrDefault(t => t.name == "bone_0");
|
||||
var arm = b.GetComponentsInChildren<Transform>().FirstOrDefault(t => t.name == "Armature");
|
||||
|
||||
anim.Rebind();
|
||||
anim.Update(0f);
|
||||
var br = MeshBounds(b);
|
||||
sb.AppendLine($"RIGGED rebind bounds min={Fmt(br.min)} size={Fmt(br.size)}");
|
||||
if (arm != null) sb.AppendLine($" Armature up={Fmt(arm.up)} fwd={Fmt(arm.forward)} euler={FmtE(arm.rotation)}");
|
||||
if (bone0 != null) sb.AppendLine($" bone0 up={Fmt(bone0.up)} fwd={Fmt(bone0.forward)} euler={FmtE(bone0.rotation)}");
|
||||
|
||||
foreach (var motion in new[] { 0, 1, 2 })
|
||||
{
|
||||
anim.Rebind();
|
||||
anim.SetInteger("Motion", motion);
|
||||
anim.Update(0f);
|
||||
for (int i = 0; i < 15; i++) anim.Update(0.05f);
|
||||
var bm = MeshBounds(b);
|
||||
string name = motion == 0 ? "Idle" : motion == 1 ? "Walk" : "Attack";
|
||||
sb.AppendLine($"{name}: bounds min={Fmt(bm.min)} size={Fmt(bm.size)} extentY/X={(bm.size.y / Mathf.Max(0.001f, bm.size.x)):F2}");
|
||||
if (bone0 != null)
|
||||
sb.AppendLine($" bone0 up={Fmt(bone0.up)} euler={FmtE(bone0.rotation)}");
|
||||
}
|
||||
|
||||
// clip: does Armature/bone_0 leave bind orientation?
|
||||
foreach (var name in new[] { "Idle", "Walk", "Attack" })
|
||||
{
|
||||
var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>($"Assets/Bundles/Characters/Animal/RockBall/Clips/{name}.anim");
|
||||
if (clip == null) continue;
|
||||
sb.AppendLine($"clip {name}:");
|
||||
foreach (var path in new[] { "Armature", "Armature/bone_0" })
|
||||
{
|
||||
var qx = AnimationUtility.GetEditorCurve(clip, new EditorCurveBinding { path = path, propertyName = "m_LocalRotation.x", type = typeof(Transform) });
|
||||
var qy = AnimationUtility.GetEditorCurve(clip, new EditorCurveBinding { path = path, propertyName = "m_LocalRotation.y", type = typeof(Transform) });
|
||||
var qz = AnimationUtility.GetEditorCurve(clip, new EditorCurveBinding { path = path, propertyName = "m_LocalRotation.z", type = typeof(Transform) });
|
||||
var qw = AnimationUtility.GetEditorCurve(clip, new EditorCurveBinding { path = path, propertyName = "m_LocalRotation.w", type = typeof(Transform) });
|
||||
if (qx == null) continue;
|
||||
var q0 = new Quaternion(qx.Evaluate(0), qy.Evaluate(0), qz.Evaluate(0), qw.Evaluate(0));
|
||||
var q1 = new Quaternion(qx.Evaluate(clip.length * 0.5f), qy.Evaluate(clip.length * 0.5f), qz.Evaluate(clip.length * 0.5f), qw.Evaluate(clip.length * 0.5f));
|
||||
sb.AppendLine($" {path} t0 euler={FmtE(q0)} tMid euler={FmtE(q1)} angleDelta={Quaternion.Angle(q0, q1):F1}");
|
||||
}
|
||||
}
|
||||
|
||||
Object.DestroyImmediate(b);
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user