Project_WL/Assets/WL/Character/WLPcScaleCompensator.cs

74 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.

// ─────────────────────────────────────────────────────────────────────────────
// WLPcScaleCompensator.cs — 치비 PC 프리팹의 월드 높이를 Ai01 과 똑같이 유지한다
//
// 발주서 WL-814n §1-4 「f_Scale 재계산으로 월드 높이 1.191 m 유지」
//
// ■ 문제
// 원본 `PCActor.Set_Obj()` 가 루트 스케일을 **대입**한다(원본 `PCActor.cs:318-325` 실측):
// 로비 : transform.localScale = Vector3.one → 1.0
// 인게임 : transform.localScale = m_ClassData.f_Scale → 0.7 (ClassConfig 12행 전부)
// M05 원 높이는 1.1316 m 라 그대로 두면 인게임 0.792 m · 로비 1.132 m 로 작아진다.
//
// ■ 왜 여기(프리팹 컴포넌트)에서 고치나 — 되돌리기(C8)와 원본 1줄 상한 때문이다
// · 테이블 `ClassConfig.f_Scale` 을 바꾸면 스위치를 껐을 때 Ai01 까지 1.79 m 가 된다(원본 100 % 깨짐).
// · `PCActor.cs:324` 에 훅을 하나 더 넣으면 원본 수정이 2줄이 되어 발주서 상한(1줄)을 넘는다.
// · 이 컴포넌트는 **새 프리팹 `LH_M05` 에만** 붙는다 → Ai01 경로는 코드·데이터 모두 무변경.
//
// ■ 어떻게 (멱등 · 누적 곱 아님)
// 원본이 루트 스케일에 새 값을 대입하면(로비 1.0 / 인게임 0.7) LateUpdate 가 그것을 **원 값**으로 보고
// `원 값 × heightCompensation` 을 다시 대입한다. 자기가 쓴 값은 기억해 두고 건너뛰므로 매 프레임 곱해지지 않는다.
// 스케일은 애니메이션이 건드리지 않으므로(Humanoid 는 위치·회전만 쓴다) LateUpdate 대입으로 충분하다.
//
// ■ 실측 결과 (AgentScripts/staging/WL814n/)
// 1.1316 m × 1.5038 = 1.7017 m(= Ai01 원 높이) → × 0.7 = **1.1912 m**(811s 실측 PC 키와 동일)
//
// 🔴 루트 스케일을 쓰는 이유: Hips 가 `Root_M` = 루트의 직속 자식이라, Hips 이하를 스케일하면
// Humanoid 리타깃이 매 프레임 쓰는 Hips 위치와 어긋나 발이 땅을 뚫는다(PROBE2 실측).
// ─────────────────────────────────────────────────────────────────────────────
using UnityEngine;
namespace WL.Character
{
[DisallowMultipleComponent]
public sealed class WLPcScaleCompensator : MonoBehaviour
{
[Tooltip("비워 두면 WLCharacterSwapSettings.heightCompensation 을 쓴다. 0 보다 크면 이 값이 우선(프리팹 단위 예외용).")]
public float overrideCompensation;
float _lastWritten = float.NaN;
/// <summary>지금 적용 중인 보정 배수. 스위치가 꺼져 있으면 1.</summary>
public float Compensation
{
get
{
if (overrideCompensation > 0f) return overrideCompensation;
return WLCharacterSwapSettings.HeightCompensation;
}
}
void OnEnable() { _lastWritten = float.NaN; Apply(); }
void LateUpdate() { Apply(); }
void Apply()
{
float k = Compensation;
if (k <= 0f) return;
float cur = transform.localScale.x;
// 자기가 마지막으로 쓴 값이면 원본이 아직 안 건드린 것 = 할 일 없음(멱등).
if (!float.IsNaN(_lastWritten) && Mathf.Abs(cur - _lastWritten) <= 1e-5f) return;
float target = cur * k;
_lastWritten = target;
transform.localScale = new Vector3(target, target, target);
var s = WLCharacterSwapSettings.Instance;
if (s != null && s.verboseLog)
Debug.Log(string.Format("[WL-814n] PC 크기 보정: {0:F4} × {1:F4} = {2:F4} ({3})", cur, k, target, name));
}
}
}