Project_WL/AgentScripts/WL887_Probe.cs

129 lines
7.5 KiB
C#

// WL887_Probe.cs — PD 지시 #887 검 + 방패 · 방패 치기 이펙트 교체 시험(Play 중)
// unity command run_script --file AgentScripts/WL887_Probe.cs --entry WL887_Probe.Weapons
using System.Collections;
using System.Text;
using UnityEngine;
public static class WL887_Probe
{
/// <summary>PC 직업 · 소켓별 무기(이름 · 월드 크기) · 지금 클립 · 이펙트 교체 카운터.</summary>
public static object Weapons()
{
var pc = MyValue.MyPC; if (pc == null) return "PC 없음";
var sb = new StringBuilder();
var mid = typeof(Actor).GetField("m_ID", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public).GetValue(pc);
sb.Append("class=").Append(mid);
var an = pc.m_animation;
if (an != null) { var ci = an.GetCurrentAnimatorClipInfo(0); sb.Append(" clip=").Append(ci.Length > 0 ? ci[0].clip.name : "?").Append(" ctrl=").Append(an.runtimeAnimatorController != null ? an.runtimeAnimatorController.name : "-"); }
float h = 0f; foreach (var r in pc.GetComponentsInChildren<SkinnedMeshRenderer>(true)) h = Mathf.Max(h, r.bounds.max.y - pc.transform.position.y);
sb.Append(" 키=").Append(h.ToString("F2"));
for (int i = 0; pc.tfs_weapon != null && i < pc.tfs_weapon.Length; i++)
{
var s = pc.tfs_weapon[i]; if (s == null || s.childCount == 0) continue;
for (int c = 0; c < s.childCount; c++)
{
var w = s.GetChild(c);
var b = new Bounds(w.position, Vector3.zero); bool has = false;
foreach (var r in w.GetComponentsInChildren<Renderer>(true)) { if (!has) { b = r.bounds; has = true; } else b.Encapsulate(r.bounds); }
sb.Append("\n 소켓").Append(i).Append(' ').Append(s.name).Append(" → ").Append(w.name).Append(" active=").Append(w.gameObject.activeInHierarchy)
.Append(" 월드크기=").Append(b.size.ToString("F2")).Append(" lscale=").Append(w.localScale.ToString("F2"));
}
}
sb.Append("\n vfx: swings=").Append(WL.Combat.Weapon.WLSkillVfx.Swings).Append(" hits=").Append(WL.Combat.Weapon.WLSkillVfx.Hits).Append(" hidden=").Append(WL.Combat.Weapon.WLSkillVfx.Hidden).Append(" errors=").Append(WL.Combat.Weapon.WLSkillVfx.Errors).Append(" last=").Append(WL.Combat.Weapon.WLSkillVfx.LastLog);
sb.Append("\n classes: ").Append(WL.Combat.Weapon.WLWeaponClasses.LastLog);
return sb.ToString();
}
/// <summary>임시 카메라로 PC 를 가까이 찍는다(게임 카메라 무접촉). yaws = "0|-90|180" (0 = 정면 · -90 = 왼쪽 = 방패 쪽) · 파일 = 접두 + yaw.png</summary>
public static object SideShot(string prefix, string yaws, float dist, float height, int size)
{
var pc = MyValue.MyPC; if (pc == null) return "PC 없음";
var sb = new StringBuilder();
var center = pc.Get_Center_position();
var go = new GameObject("WL887_SideCam");
try
{
var cam = go.AddComponent<Camera>();
cam.fieldOfView = 30f; cam.nearClipPlane = 0.05f; cam.farClipPlane = 60f;
cam.clearFlags = CameraClearFlags.SolidColor; cam.backgroundColor = new Color(0.32f, 0.36f, 0.42f);
var rt = new RenderTexture(size, size, 24, RenderTextureFormat.ARGB32);
cam.targetTexture = rt;
foreach (var ys in yaws.Split('|'))
{
float yaw = float.Parse(ys);
var dir = Quaternion.Euler(0f, yaw, 0f) * pc.transform.forward;
cam.transform.position = center + dir * dist + Vector3.up * height;
cam.transform.LookAt(center);
cam.Render();
var prev = RenderTexture.active; RenderTexture.active = rt;
var tex = new Texture2D(size, size, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0, 0, size, size), 0, 0); tex.Apply();
RenderTexture.active = prev;
System.IO.File.WriteAllBytes(prefix + ys + ".png", tex.EncodeToPNG());
Object.Destroy(tex);
sb.Append("저장 yaw ").Append(ys).Append(' ');
}
cam.targetTexture = null; rt.Release(); Object.Destroy(rt);
}
finally { Object.Destroy(go); }
return sb.ToString();
}
/// <summary>비교용 — 왼손 소켓 0 의 무기를 잠시 숨기고 path 프리팹을 붙인다(path 비우면 원래대로). 에디터 Play 전용.</summary>
public static object SwapLH(string path)
{
var pc = MyValue.MyPC; if (pc == null) return "PC 없음";
var s = pc.tfs_weapon[0];
var test = s.Find("WL887_Test");
if (test != null) Object.Destroy(test.gameObject);
for (int c = 0; c < s.childCount; c++) if (s.GetChild(c).name != "WL887_Test") s.GetChild(c).gameObject.SetActive(string.IsNullOrEmpty(path));
if (string.IsNullOrEmpty(path)) return "원래대로";
var p = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
if (p == null) return "없음 " + path;
var w = Object.Instantiate(p, s, false); w.name = "WL887_Test";
w.transform.localPosition = Vector3.zero; w.transform.localRotation = Quaternion.identity; w.transform.localScale = Vector3.one;
return "붙임 " + p.name;
}
/// <summary>비교용 — 지금 컨트롤러 위에 클립 바꿔치기(AnimatorOverrideController)를 씌운다(파일 무수정). map = "원래클립=FBX경로:클립이름|…" · 비우면 원래 컨트롤러로.</summary>
public static object TryClips(string map)
{
var pc = MyValue.MyPC; if (pc == null) return "PC 없음";
var an = pc.m_animation;
var cur = an.runtimeAnimatorController;
var baseCtrl = cur is AnimatorOverrideController ? ((AnimatorOverrideController)cur).runtimeAnimatorController : cur;
if (string.IsNullOrEmpty(map)) { an.runtimeAnimatorController = baseCtrl; return "원래대로 " + baseCtrl.name; }
var ov = new AnimatorOverrideController(baseCtrl) { name = baseCtrl.name + "_WL887test" };
var sb = new StringBuilder();
foreach (var pair in map.Split('|'))
{
var kv = pair.Split('='); if (kv.Length != 2) continue;
var src = kv[1].Split(':');
AnimationClip clip = null;
foreach (var o in UnityEditor.AssetDatabase.LoadAllAssetsAtPath(src[0])) { var c = o as AnimationClip; if (c != null && c.name == src[1]) { clip = c; break; } }
if (clip == null) { sb.Append("클립 없음 ").Append(kv[1]).Append(' '); continue; }
ov[kv[0]] = clip; sb.Append(kv[0]).Append("→").Append(clip.name).Append(' ');
}
an.runtimeAnimatorController = ov;
return sb.ToString();
}
/// <summary>섬 조이스틱(SimpleInput 축) 입력을 seconds 동안 넣는다(달리기 캡처용).</summary>
public static object Steer(float dx, float dz, float seconds)
{
var pc = MyValue.MyPC; if (pc == null) return "PC 없음";
pc.StartCoroutine(Co(dx, dz, seconds));
return "입력 " + seconds + "s";
}
static IEnumerator Co(float dx, float dz, float seconds)
{
var h = new SimpleInput.AxisInput("Horizontal") { value = dx };
var v = new SimpleInput.AxisInput("Vertical") { value = dz };
h.StartTracking(); v.StartTracking();
float t = 0f;
while (t < seconds) { t += Time.deltaTime; yield return null; }
h.StopTracking(); v.StopTracking();
}
}