65 lines
4.0 KiB
C#
65 lines
4.0 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
||
// WLActorScale.cs — 몹 「쉬는 크기」 기준 하나 (#918 · 2026-10-17)
|
||
//
|
||
// PD 원문: 「방패치기 및 검 궁극기 등을 사용할 때 적의 크기가 자꾸 커지는데 확인해보고 수정해줘」
|
||
// ■ 원인(코드 확인) — 잠깐 크기를 바꾸는 효과 둘이 저마다 「지금 크기」를 기준으로 잡았다:
|
||
// · 피격 스케일 펀치(WLHitFeelRunner.CoScalePunch · 맞을 때 커졌다 돌아옴)
|
||
// · 공격 예고 부풀기(Telegraph · 공격 직전 커짐)
|
||
// 연타(다단 히트 0.1 초 간격)로 펀치가 겹치면 새 펀치가 앞 펀치로 커진 크기를 기준으로 잡아 그 크기로 되돌리고,
|
||
// 앞 펀치는 「남이 바꿨다」고 보고 복원을 포기 → 칠 때마다 조금씩 커졌다(예고 부풀기와 겹쳐도 같다).
|
||
// ■ 처리 — 효과가 시작할 때 Begin(진행 중인 효과가 없을 때만 지금 크기를 쉬는 크기로 기억 · 있으면 그 기억을 그대로) ·
|
||
// 효과는 쉬는 크기 × 배율만 쓴다 · End 에서 마지막 효과가 끝나면 쉬는 크기로 되돌린다.
|
||
// 오래(staleSeconds) 안 끝난 기록(풀 반환으로 코루틴이 끊긴 경우)은 버리고 새로 잡는다 · 스폰(풀 재사용)되면 기록을 지운다.
|
||
// 🔴 Debug.LogError 금지(원본 팝업).
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using WL.Combat.Core;
|
||
|
||
namespace WL.Combat.Reaction
|
||
{
|
||
public static class WLActorScale
|
||
{
|
||
const float StaleSeconds = 5f;
|
||
sealed class Entry { public Vector3 rest; public int count; public float touched; }
|
||
static readonly Dictionary<Transform, Entry> s_map = new Dictionary<Transform, Entry>(32);
|
||
public static int Begins, Ends, StaleReset;
|
||
|
||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
|
||
static void Register() { CombatEvents.Spawned.Add(OnSpawned); }
|
||
|
||
static void OnSpawned(in SpawnedEvent e) { if (e.actor != null) s_map.Remove(e.actor.transform); }
|
||
|
||
/// <summary>효과 시작 — 쉬는 크기(진행 중인 효과가 있으면 그 기억) 반환.</summary>
|
||
public static Vector3 Begin(Transform tf)
|
||
{
|
||
if (tf == null) return Vector3.one;
|
||
Entry e;
|
||
if (!s_map.TryGetValue(tf, out e)) { e = new Entry { rest = tf.localScale }; s_map[tf] = e; }
|
||
else if (e.count <= 0 || Time.unscaledTime - e.touched > StaleSeconds) { e.rest = e.count <= 0 ? tf.localScale : e.rest; if (e.count > 0) StaleReset++; e.count = 0; }
|
||
e.count++; e.touched = Time.unscaledTime; Begins++;
|
||
return e.rest;
|
||
}
|
||
|
||
/// <summary>진행 중인 효과가 있으면 쉬는 크기, 없으면 지금 크기.</summary>
|
||
public static Vector3 Rest(Transform tf)
|
||
{
|
||
Entry e;
|
||
return tf != null && s_map.TryGetValue(tf, out e) && e.count > 0 ? e.rest : (tf != null ? tf.localScale : Vector3.one);
|
||
}
|
||
|
||
public static bool Active(Transform tf) { Entry e; return tf != null && s_map.TryGetValue(tf, out e) && e.count > 0; }
|
||
|
||
/// <summary>효과 끝 — 마지막 효과면 쉬는 크기로 되돌린다.</summary>
|
||
public static void End(Transform tf)
|
||
{
|
||
Entry e;
|
||
if (tf == null || !s_map.TryGetValue(tf, out e)) return;
|
||
e.count--; e.touched = Time.unscaledTime; Ends++;
|
||
if (e.count <= 0) { tf.localScale = e.rest; s_map.Remove(tf); }
|
||
}
|
||
|
||
public static void Clear() { s_map.Clear(); }
|
||
}
|
||
}
|