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,82 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 把 CaoCao Prefab 摆到当前场景广场中心,Y 取地表碰撞高度。不保存进 TownSquare.prefab。
|
||||
/// </summary>
|
||||
public static class PlaceCaoCao
|
||||
{
|
||||
const string PrefabPath = "Assets/Bundles/Characters/Human/CaoCao/CaoCao.prefab";
|
||||
|
||||
public static string Run()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(PrefabPath);
|
||||
if (prefab == null)
|
||||
return "missing " + PrefabPath;
|
||||
|
||||
var existing = GameObject.Find("CaoCao_Preview");
|
||||
if (existing != null)
|
||||
Object.DestroyImmediate(existing);
|
||||
|
||||
var go = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
|
||||
go.name = "CaoCao_Preview";
|
||||
|
||||
Physics.SyncTransforms();
|
||||
var y = SampleGroundY(0f, 0f, out var sitInfo);
|
||||
go.transform.position = new Vector3(0f, y, 0f);
|
||||
go.transform.rotation = Quaternion.identity;
|
||||
|
||||
var bounds = default(Bounds);
|
||||
var has = false;
|
||||
foreach (var r in go.GetComponentsInChildren<Renderer>())
|
||||
{
|
||||
if (!has) { bounds = r.bounds; has = true; }
|
||||
else bounds.Encapsulate(r.bounds);
|
||||
}
|
||||
return $"pos={go.transform.position} h={(has ? bounds.size.y : 0f):F3} groundY={y:F3} {sitInfo}";
|
||||
}
|
||||
|
||||
static float SampleGroundY(float x, float z, out string info)
|
||||
{
|
||||
var plaza = GameObject.Find("TownSquare");
|
||||
var cols = plaza != null
|
||||
? plaza.GetComponentsInChildren<MeshCollider>()
|
||||
: Object.FindObjectsByType<MeshCollider>(FindObjectsSortMode.None);
|
||||
var y = 0f;
|
||||
var hitAny = false;
|
||||
var best = float.MaxValue;
|
||||
var meshName = "";
|
||||
var boundsTop = 0f;
|
||||
foreach (var col in cols)
|
||||
{
|
||||
if (col == null || !col.enabled) continue;
|
||||
meshName = col.sharedMesh != null ? col.sharedMesh.name : "null";
|
||||
boundsTop = col.bounds.max.y;
|
||||
var origins = new[]
|
||||
{
|
||||
new Vector3(x, 80f, z),
|
||||
new Vector3(col.bounds.center.x, col.bounds.max.y + 8f, col.bounds.center.z),
|
||||
new Vector3(x + 0.35f, 80f, z + 0.35f),
|
||||
};
|
||||
foreach (var origin in origins)
|
||||
{
|
||||
var ray = new Ray(origin, Vector3.down);
|
||||
if (!col.Raycast(ray, out var hit, 160f)) continue;
|
||||
if (hit.distance >= best) continue;
|
||||
best = hit.distance;
|
||||
y = hit.point.y;
|
||||
hitAny = true;
|
||||
}
|
||||
}
|
||||
if (!hitAny && boundsTop > 0.01f)
|
||||
{
|
||||
y = boundsTop;
|
||||
info = $"fallbackBoundsTop={y:F3} mesh={meshName} cols={cols.Length}";
|
||||
return y;
|
||||
}
|
||||
info = $"plaza={(plaza != null ? plaza.name : "null")} cols={cols.Length} mesh={meshName} meshHit={hitAny}";
|
||||
return hitAny ? y : 0f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user