Project_WL/Assets/WL/Combat/Reaction/WLActorScale.cs

65 lines
4.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ─────────────────────────────────────────────────────────────────────────────
// 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(); }
}
}