diff --git a/AgentScripts/WL811def_Probe.cs b/AgentScripts/WL811def_Probe.cs index 061993c6b..2aa4e412b 100644 --- a/AgentScripts/WL811def_Probe.cs +++ b/AgentScripts/WL811def_Probe.cs @@ -172,9 +172,17 @@ public static class WL811def_Probe var mob = go.AddComponent(); mob.enabled = false; mob.m_SubRole = sub; go.SetActive(true); + InitCC(mob); return mob; } + /// 실 액터는 Set/On_Regen 이 Init_CC 로 dic_ccData 를 채운다 — 가짜는 리플렉션으로 같은 메서드를 1회 호출(Get_MoveSpeed 의 KeyNotFound 방지 · 1차 실측 76건). + static void InitCC(Actor a) + { + var m = typeof(Actor).GetMethod("Init_CC", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public); + if (m != null) m.Invoke(a, null); else Debug.LogWarning("[WL811def] Init_CC 미발견"); + } + static PCActor MakePC(string name, Vector3 pos) { var go = new GameObject(name); @@ -189,6 +197,7 @@ public static class WL811def_Probe UnityEngine.Object.Destroy(cube.GetComponent()); var pc = go.AddComponent(); pc.enabled = false; go.SetActive(true); + InitCC(pc); return pc; } @@ -519,6 +528,9 @@ public static class WL811def_Probe _sb.AppendLine("blink Spawned×100(정리): " + GcOf(() => CombatEvents.RaiseSpawned(elite), 100)); yield return null; + set(false, false, false); + _sb.AppendLine("core-only(3 SO off) Killed×100: " + GcOf(() => CombatEvents.RaiseKilled(elite), 100) + " ← CombatEvents.RaiseKilled 의 Log(문자열 결합 · victim.name) 몫"); + _sb.AppendLine("core-only(3 SO off) HitConfirmed×100: " + GcOf(() => CombatEvents.RaiseHitConfirmed(elite, dmg), 100)); set(true, true, true); CombatCameraDirector.ResetRun(); _sb.AppendLine("all3 Killed×100: " + GcOf(() => CombatEvents.RaiseKilled(elite), 100)); _sb.AppendLine("all3 HitConfirmed×100: " + GcOf(() => CombatEvents.RaiseHitConfirmed(elite, dmg), 100)); diff --git a/Assets/WL/Combat/Reaction/MobHitFlash.cs b/Assets/WL/Combat/Reaction/MobHitFlash.cs index 6e44abb3a..911ed359d 100644 --- a/Assets/WL/Combat/Reaction/MobHitFlash.cs +++ b/Assets/WL/Combat/Reaction/MobHitFlash.cs @@ -221,7 +221,7 @@ namespace WL.Combat.Reaction if (Verbose) Log("디졸브 셰이더 실측 " + sh.name + " hdr=" + s_dissolveHasHdr + " range=" + s_dissolveHasRange); } - /// 상태(blinkOn · tint)로 렌더러별 MPB 를 다시 구성해 쓴다. 둘 다 꺼져 있으면 빈 블록 = 오버라이드 0. + /// 상태(blinkOn · tint)로 렌더러별 MPB 를 다시 구성해 쓴다. 둘 다 꺼져 있으면 블록을 떼어(null) 오버라이드 0 · SRP Batcher 복귀. static void Apply(State s, WLHitBlinkSettings st) { for (int i = 0; i < s.renderers.Length; i++) @@ -241,7 +241,8 @@ namespace WL.Combat.Reaction if (s_dissolveHasHdr && s.tintHdr >= 0f) mpb.SetFloat(s_edgeHdrId, s.tintHdr); if (s_dissolveHasRange && s.tintRange >= 0f) mpb.SetFloat(s_edgeRangeId, s.tintRange); } - r.SetPropertyBlock(mpb); + // 빈 블록을 써도 HasPropertyBlock 은 true 로 남는다(2026-09-09 Title Play 실측) → 오버라이드가 없으면 null 로 블록을 떼어 SRP Batcher 로 복귀 + if (mpb.isEmpty) r.SetPropertyBlock(null); else r.SetPropertyBlock(mpb); } } @@ -293,7 +294,7 @@ namespace WL.Combat.Reaction if (!s.blinkOn && !s.tint) continue; s.blinkOn = false; s.tint = false; if (st != null) Apply(s, st); - else for (int i = 0; i < s.renderers.Length; i++) if (s.renderers[i] != null) { s.blocks[i].Clear(); s.renderers[i].SetPropertyBlock(s.blocks[i]); } + else for (int i = 0; i < s.renderers.Length; i++) if (s.renderers[i] != null) { s.blocks[i].Clear(); s.renderers[i].SetPropertyBlock(null); } } for (int i = 0; i < s_activeCount; i++) { s_active[i].activeIndex = -1; s_active[i] = null; } s_activeCount = 0;