187 lines
13 KiB
C#
187 lines
13 KiB
C#
|
|
// WL925_Probe.cs — PD 지시 #925 시험(Play 중 · 섬)
|
||
|
|
// Wave(seconds, pauseAt) : 대검 주력(1 칸) 발동 — 0.05 초마다 동작 · 상태 · 검기 앞머리 · 크기 · 명중 · 밀기 · 몹별 피격 시각 · 이동 거리 · pauseAt > 0 = 시전 뒤 그 초에 일시 정지
|
||
|
|
// Line(d0, step, count, side) : 몹 count 마리를 PC 정면 d0 m 부터 step m 간격(side = 좌우 엇갈림 m)으로 세운다(멈춤)
|
||
|
|
// Body() : PC 몸 렌더러 켜짐 / 전체
|
||
|
|
// Storm(seconds) : 대검 각성(2 칸) 발동 — 끝난 시각 · 몸 켜짐 최솟값
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Text;
|
||
|
|
using UnityEngine;
|
||
|
|
using WL.Combat.Weapon;
|
||
|
|
|
||
|
|
public static class WL925_Probe
|
||
|
|
{
|
||
|
|
const string Key = "wl925log";
|
||
|
|
static StringBuilder Buf()
|
||
|
|
{
|
||
|
|
var sb = System.AppDomain.CurrentDomain.GetData(Key) as StringBuilder;
|
||
|
|
if (sb == null) { sb = new StringBuilder(); System.AppDomain.CurrentDomain.SetData(Key, sb); }
|
||
|
|
return sb;
|
||
|
|
}
|
||
|
|
public static object Log() { return Buf().ToString(); }
|
||
|
|
|
||
|
|
static List<MobActor> Mobs(PCActor pc, float within)
|
||
|
|
{
|
||
|
|
var l = new List<MobActor>();
|
||
|
|
foreach (var m in Object.FindObjectsByType<MobActor>(FindObjectsInactive.Exclude, FindObjectsSortMode.None))
|
||
|
|
if (m != null && !m.IsDead() && Vector3.Distance(m.Get_position(), pc.Get_position()) <= within) l.Add(m);
|
||
|
|
l.Sort((a, b) => Vector3.Distance(a.Get_position(), pc.Get_position()).CompareTo(Vector3.Distance(b.Get_position(), pc.Get_position())));
|
||
|
|
return l;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static object Line(float d0, float step, int count, float side)
|
||
|
|
{
|
||
|
|
var pc = MyValue.MyPC as PCActor; if (pc == null) return "PC 없음";
|
||
|
|
var f = pc.transform.forward; f.y = 0f; if (f.sqrMagnitude < 1e-4f) f = Vector3.forward; f.Normalize();
|
||
|
|
var r = Vector3.Cross(Vector3.up, f);
|
||
|
|
var mobs = Mobs(pc, 40f); var sb = new StringBuilder();
|
||
|
|
for (int i = 0; i < mobs.Count && i < count; i++)
|
||
|
|
{
|
||
|
|
var want = pc.Get_position() + f * (d0 + step * i) + r * ((i % 2 == 0 ? 1f : -1f) * side * (i > 0 ? 1f : 0f));
|
||
|
|
UnityEngine.AI.NavMeshHit hit;
|
||
|
|
if (UnityEngine.AI.NavMesh.SamplePosition(want, out hit, 1.5f, UnityEngine.AI.NavMesh.AllAreas)) want = hit.position;
|
||
|
|
mobs[i].Stop(true); mobs[i].Set_Warp(want);
|
||
|
|
sb.Append(mobs[i].name).Append(' ').Append(Vector3.Distance(pc.Get_position(), mobs[i].Get_position()).ToString("F1")).Append("m · ");
|
||
|
|
}
|
||
|
|
return "세움 " + Mathf.Min(count, mobs.Count) + " / " + mobs.Count + " · " + sb;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>콤보 단계 stage 가 시작되고 delay 초 뒤 — 궤적 교체 로그(WLImpactFx.LastSwing) · 켜진 WL_Impact_Swing_Ink 들의 PC 기준 위치 · 회전 · 크기 · 입자 수.</summary>
|
||
|
|
public static object SwingInfo(int stage, float delay, float maxSeconds)
|
||
|
|
{
|
||
|
|
var pc = MyValue.MyPC as PCActor; if (pc == null) return "PC 없음";
|
||
|
|
var sb = Buf(); sb.Length = 0; float t0 = Time.time, at = -1f; int shown0 = WL.Combat.Impact.WLImpactFx.SwingShown;
|
||
|
|
WL.Combat.Core.CombatHandler<WL.Combat.Core.ComboStageEvent> on = null;
|
||
|
|
on = (in WL.Combat.Core.ComboStageEvent e) => { if (at < 0f && ReferenceEquals(e.actor, pc) && e.stage == stage) at = Time.time + delay; };
|
||
|
|
WL.Combat.Core.CombatEvents.ComboStage.Add(on);
|
||
|
|
UnityEngine.Events.UnityAction act = null;
|
||
|
|
act = () =>
|
||
|
|
{
|
||
|
|
if ((at > 0f && Time.time >= at) || Time.time - t0 > maxSeconds)
|
||
|
|
{
|
||
|
|
Application.onBeforeRender -= act; WL.Combat.Core.CombatEvents.ComboStage.Remove(on);
|
||
|
|
sb.Append(at > 0f ? "단계 " + stage + " +" + delay : "못 찾음").Append(" · 궤적 교체 +").Append(WL.Combat.Impact.WLImpactFx.SwingShown - shown0).Append(" · ").Append(WL.Combat.Impact.WLImpactFx.LastSwing).Append('\n');
|
||
|
|
var root = GameObject.Find("WL_ImpactFx");
|
||
|
|
if (root != null)
|
||
|
|
foreach (Transform ch in root.transform)
|
||
|
|
{
|
||
|
|
if (!ch.gameObject.activeSelf) continue;
|
||
|
|
int n = 0; foreach (var ps in ch.GetComponentsInChildren<ParticleSystem>(false)) n += ps.particleCount;
|
||
|
|
var rel = Quaternion.Inverse(pc.transform.rotation) * (ch.position - pc.Get_position());
|
||
|
|
sb.Append(" ").Append(ch.name).Append(" · PC 기준 ").Append(rel.ToString("F2")).Append(" · 회전 ").Append((Quaternion.Inverse(pc.transform.rotation) * ch.rotation).eulerAngles.ToString("F0")).Append(" · 크기 ").Append(ch.localScale.x.ToString("F2")).Append(" · 입자 ").Append(n).Append('\n');
|
||
|
|
}
|
||
|
|
sb.Append(" 지면 ").Append(WL.Combat.Impact.WLImpactFx.LastGround).Append('\n');
|
||
|
|
}
|
||
|
|
};
|
||
|
|
Application.onBeforeRender += act;
|
||
|
|
return "단계 " + stage + " 대기";
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>#927 대상 바라보기 — PC 를 더미 방향에서 awayDeg 만큼 돌려 놓고 대검 주력 발동 → 0.05 초마다 PC 정면과 더미 방향 사이 각 · 발사 순간 각.</summary>
|
||
|
|
public static object Facing(float awayDeg, float seconds)
|
||
|
|
{
|
||
|
|
var pc = MyValue.MyPC as PCActor; var d = WL.IslandMob.WLTrailTest.Dummy; if (pc == null || d == null) return "PC/더미 없음";
|
||
|
|
var sb = Buf(); sb.Length = 0; float t0 = Time.time, tl = -1f; int f0 = WLGreatWave.Fired; float fireAng = -1f;
|
||
|
|
var to0 = d.Get_position() - pc.Get_position(); to0.y = 0f;
|
||
|
|
pc.transform.rotation = Quaternion.LookRotation(to0) * Quaternion.Euler(0f, awayDeg, 0f);
|
||
|
|
string res = WLSkillHotkey.Fire(1);
|
||
|
|
UnityEngine.Events.UnityAction act = null;
|
||
|
|
act = () =>
|
||
|
|
{
|
||
|
|
float t = Time.time - t0;
|
||
|
|
var to = d.Get_position() - pc.Get_position(); to.y = 0f; var f = pc.transform.forward; f.y = 0f;
|
||
|
|
float ang = Vector3.Angle(f, to);
|
||
|
|
if (fireAng < 0f && WLGreatWave.Fired > f0) fireAng = ang;
|
||
|
|
if (t - tl >= 0.1f || t > seconds) { tl = t; sb.AppendFormat("{0:F2} {1} 각 {2:F0}°", t, pc.Get_CurAnim(), ang).Append('\n'); }
|
||
|
|
if (t > seconds) { Application.onBeforeRender -= act; sb.AppendFormat("끝 · 처음 돌려 둔 각 {0:F0}° · 발사 순간 각 {1:F0}° · {2}", awayDeg, fireAng, res).Append('\n'); }
|
||
|
|
};
|
||
|
|
Application.onBeforeRender += act;
|
||
|
|
return "바라보기 시험 · " + res;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static object Body()
|
||
|
|
{
|
||
|
|
var pc = MyValue.MyPC as PCActor; if (pc == null) return "PC 없음";
|
||
|
|
int on = 0, all = 0;
|
||
|
|
foreach (var r in pc.GetComponentsInChildren<SkinnedMeshRenderer>(true)) { all++; if (r.enabled && r.gameObject.activeInHierarchy) on++; }
|
||
|
|
return "몸 " + on + "/" + all + " · 동작 " + pc.Get_CurAnim();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>대검 주력 발동 뒤 moveAt 초부터 moveSec 초 동안 옆으로 이동 입력 — 끊김 · 발사 · 검기 · 애니메이터(속도 · 이벤트) · 검 빛 자식 수.</summary>
|
||
|
|
public static object WaveMove(float moveAt, float moveSec, float seconds)
|
||
|
|
{
|
||
|
|
var pc = MyValue.MyPC as PCActor; if (pc == null) return "PC 없음";
|
||
|
|
var sb = Buf(); sb.Length = 0; float t0 = Time.time; bool moving = false;
|
||
|
|
int f0 = WLGreatWave.Fired, s0 = WLGreatWave.Shots, a0 = WLGreatWave.Aborts, h0 = WLGreatWave.Hits;
|
||
|
|
var right = pc.transform.right; right.y = 0f; right.Normalize();
|
||
|
|
string res = WLSkillHotkey.Fire(1);
|
||
|
|
UnityEngine.Events.UnityAction act = null;
|
||
|
|
act = () =>
|
||
|
|
{
|
||
|
|
float t = Time.time - t0;
|
||
|
|
if (t >= moveAt && t < moveAt + moveSec) { if (!moving) { moving = true; sb.AppendFormat("{0:F2} 이동 시작 · 동작 {1} · 발사 {2}", t, pc.Get_CurAnim(), WLGreatWave.Fired - f0).Append('\n'); } pc.Run_byJoystick(right); }
|
||
|
|
else if (moving && t >= moveAt + moveSec) { moving = false; pc.Set_AutoBraking(true); sb.AppendFormat("{0:F2} 이동 끝 · 동작 {1}", t, pc.Get_CurAnim()).Append('\n'); }
|
||
|
|
if (t > seconds)
|
||
|
|
{
|
||
|
|
Application.onBeforeRender -= act;
|
||
|
|
int glow = 0; foreach (var tr in pc.GetComponentsInChildren<Transform>(true)) if (tr.name == "[WL] Glow") glow++;
|
||
|
|
var an = pc.m_animation;
|
||
|
|
sb.AppendFormat("끝 · 발사 +{0} · 검기 +{1} · 끊김 +{2} · 명중 +{3} · 검기 {4:F2} 초 · 애니 속도 {5:F2} 이벤트 {6} · 검 빛 자식 {7} · 동작 {8} · {9} · {10}", WLGreatWave.Fired - f0, WLGreatWave.Shots - s0, WLGreatWave.Aborts - a0, WLGreatWave.Hits - h0,
|
||
|
|
WLGreatWave.LastShotSeconds, an.speed, an.fireEvents, glow, pc.Get_CurAnim(), WLGreatWave.LastLog, res).Append('\n');
|
||
|
|
}
|
||
|
|
};
|
||
|
|
Application.onBeforeRender += act;
|
||
|
|
return "이동 끊기 시험 · " + res;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static object Wave(float seconds, float pauseAt)
|
||
|
|
{
|
||
|
|
var pc = MyValue.MyPC as PCActor; if (pc == null) return "PC 없음";
|
||
|
|
var sb = Buf(); sb.Length = 0; float t0 = Time.time, tl = -1f; bool paused = false;
|
||
|
|
int h0 = WLGreatWave.Hits, f0 = WLGreatWave.Fired, s0 = WLGreatWave.Shots, a0 = WLGreatWave.Aborts, k0 = WLGreatWave.Takeovers;
|
||
|
|
WLGreatWave.MaxHitsOnOne = 0; WLGreatWave.PushDistance = 0f;
|
||
|
|
var mobs = Mobs(pc, 15f); var start = new Dictionary<MobActor, Vector3>(); foreach (var m in mobs) start[m] = m.Get_position();
|
||
|
|
var times = new Dictionary<Actor, StringBuilder>();
|
||
|
|
WL.Combat.Core.CombatHandler<WL.Combat.Core.DamagedEvent> onDmg = null;
|
||
|
|
onDmg = (in WL.Combat.Core.DamagedEvent e) =>
|
||
|
|
{
|
||
|
|
if (!ReferenceEquals(e.attacker, pc) || e.victim == null) return;
|
||
|
|
StringBuilder s; if (!times.TryGetValue(e.victim, out s)) { s = new StringBuilder(); times[e.victim] = s; }
|
||
|
|
s.Append((Time.time - t0).ToString("F2")).Append(' ');
|
||
|
|
};
|
||
|
|
WL.Combat.Core.CombatEvents.Damaged.Add(onDmg);
|
||
|
|
float fireAt = -1f;
|
||
|
|
Transform hips = null, toeL = null, toeR = null;
|
||
|
|
foreach (var tr in pc.GetComponentsInChildren<Transform>(true)) { if (tr.name == "Root_M") hips = tr; else if (tr.name == "ToesEnd_L") toeL = tr; else if (tr.name == "ToesEnd_R") toeR = tr; }
|
||
|
|
WLGreatWave.MaxLower = 0f; WLGreatWave.LastHoldSeconds = 0f;
|
||
|
|
string res = WLSkillHotkey.Fire(1);
|
||
|
|
UnityEngine.Events.UnityAction act = null;
|
||
|
|
act = () =>
|
||
|
|
{
|
||
|
|
float t = Time.time - t0; var an = pc.m_animation; var si = an.GetCurrentAnimatorStateInfo(0); float gy = pc.Get_position().y;
|
||
|
|
float hy = hips != null ? hips.position.y - gy : -9f, fy = toeL != null && toeR != null ? Mathf.Min(toeL.position.y, toeR.position.y) - gy : -9f;
|
||
|
|
if (fireAt < 0f && WLGreatWave.Fired > f0) fireAt = t;
|
||
|
|
if (!paused && pauseAt > 0f && t >= pauseAt) { paused = true; UnityEditor.EditorApplication.isPaused = true; sb.AppendFormat("■ 일시 정지 t {0:F2}", t).Append('\n'); }
|
||
|
|
if (t - tl >= 0.05f || t > seconds)
|
||
|
|
{
|
||
|
|
tl = t;
|
||
|
|
sb.AppendFormat("{0:F2} {1} {2} n={3:F2} sp {4:F2} · 엉덩이 {11:F2} 발끝 {12:F2} · 발사 {5} 검기 {6} · 앞머리 {7:F1} 크기 {8:F2} · 명중 {9} 밀기 {10:F1}m", t, pc.Get_CurAnim(), si.IsName("Attack4") ? "Attack4" : si.IsName("fatalblow") ? "fatalblow" : si.IsName("idle") ? "idle" : si.shortNameHash.ToString(), si.normalizedTime, an.speed,
|
||
|
|
WLGreatWave.Fired - f0, WLGreatWave.Shots - s0, WLGreatWave.LastFront, WLGreatWave.LastScaleEnd, WLGreatWave.Hits - h0, WLGreatWave.PushDistance, hy, fy).Append('\n');
|
||
|
|
}
|
||
|
|
if (t > seconds)
|
||
|
|
{
|
||
|
|
Application.onBeforeRender -= act; WL.Combat.Core.CombatEvents.Damaged.Remove(onDmg);
|
||
|
|
sb.AppendFormat("끝 · 넘겨받음 +{0} · 발사 +{1} (t {2:F2}) · 검기 +{3} · 명중 +{4} · 한 적 최대 {5} · 끊김 +{6} · 검기 {7:F2} 초 · 내린 최대 {10:F2} m · 멈춤 {11:F2} 초 · 결과 {8} · {9}", WLGreatWave.Takeovers - k0, WLGreatWave.Fired - f0, fireAt, WLGreatWave.Shots - s0, WLGreatWave.Hits - h0, WLGreatWave.MaxHitsOnOne, WLGreatWave.Aborts - a0, WLGreatWave.LastShotSeconds, res, WLGreatWave.LastLog, WLGreatWave.MaxLower, WLGreatWave.LastHoldSeconds).Append('\n');
|
||
|
|
foreach (var m in mobs)
|
||
|
|
{
|
||
|
|
if (m == null) continue; StringBuilder s; times.TryGetValue(m, out s);
|
||
|
|
var mv = m.Get_position() - start[m]; mv.y = 0f;
|
||
|
|
var rel = m.Get_position() - pc.Get_position(); rel.y = 0f;
|
||
|
|
sb.AppendFormat(" {0} · 피격 {1} · 이동 {2:F2} m · 지금 PC 앞 {3:F1} m{4}", m.name, s != null ? s.ToString() : "-", mv.magnitude, rel.magnitude, m.IsDead() ? " (죽음)" : "").Append('\n');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
Application.onBeforeRender += act;
|
||
|
|
return "대검 주력 관찰 " + seconds + " 초 · " + res;
|
||
|
|
}
|
||
|
|
}
|