116 lines
6.5 KiB
C#
116 lines
6.5 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
|
// WLCharacterSwapSettings.cs — 플레이어 캐릭터(PC) 프리팹 교체의 단일 출처(SOT · C45)
|
|
//
|
|
// PD 결정 #814 (2026-09-12) 「1. 바꿔. 2. 붉은 기사 M05로 해」
|
|
// 발주서 WL-814n · 조사서 `도트_아트풍_달성안_v1.md` §C① (실측 근거 전부)
|
|
//
|
|
// ■ 왜 (전부 실측 · `AgentScripts/staging/WL814n/PROBE1.txt`)
|
|
// 현 PC `Ai01` = 높이 1.7017 m · 턱(Neck_M) 1.2783 → 머리 0.3098 m → **머리:키 5.49**
|
|
// `M05`(RedKnight) = 높이 1.1316 m · 턱 0.6560 → 머리 0.4439 m → **머리:키 2.55**
|
|
// 도트A(픽셀 높이 240)에서 머리 픽셀 **7.7 px → 16.5 px (+116 %)** = PD 참고(2D 도트 RPG)의 16~24 px 대역.
|
|
//
|
|
// ■ 어떻게 (원본 수정 = PCInfo.cs 1줄이 상한 · 조사서 §C① ⓒ안)
|
|
// 인게임 PC 생성 지점은 단 한 곳 `Assets/Script/Info/PCInfo.cs:16`
|
|
// LoadObject<GameObject>($"Assets/Res_Addr/PC/{costumetable.s_Prefab}.prefab", …)
|
|
// 여기서 프리팹 **이름만** 이 클래스가 갈아끼운다. Addressables 그룹 `PC.asset` 엔트리가
|
|
// 폴더 1개(주소 = 경로)라 같은 폴더에 프리팹을 두면 주소가 생긴다 → **Addressables 수정 0**.
|
|
//
|
|
// ■ 크기는 왜 테이블(ClassConfig.f_Scale)이 아니라 프리팹인가 — 🔴 되돌리기(C8) 때문이다
|
|
// `PCActor.cs:324` 가 `transform.localScale = m_ClassData.f_Scale`(12행 전부 0.7)를 대입한다.
|
|
// f_Scale 을 1.0525 로 바꾸면 M05 는 1.191 m 로 맞지만 **스위치를 꺼서 Ai01 로 돌아갔을 때
|
|
// Ai01 이 1.79 m 가 되어 원본 100 % 가 깨진다**(그리고 테이블은 xlsm 재익스포트로 날아간다).
|
|
// 그래서 보정은 **새 프리팹에만 붙는 `WLPcScaleCompensator`** 가 한다 → 테이블 수정 0 ·
|
|
// 스위치를 끄면 Ai01 은 손도 대지 않은 원본 그대로다.
|
|
//
|
|
// 에셋 경로(고정): Assets/WL/Settings/Resources/WL/WLCharacterSwapSettings.asset
|
|
// C8 롤백: 에셋이 없거나 enabled = false → `Resolve` 가 원본 문자열을 그대로 돌려준다 = 무동작.
|
|
//
|
|
// 🔴 원본 프리팹 `Ai01` · `Assets/Suriyun/**` 은 고치지 않는다(발주서 §2 금지 · 참조만).
|
|
// 🔴 어셈블리 주의: Assets/WL/Character/ 에 .asmdef 를 만들지 말 것.
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
using UnityEngine;
|
|
|
|
namespace WL.Character
|
|
{
|
|
[CreateAssetMenu(fileName = "WLCharacterSwapSettings", menuName = "WL/Character Swap Settings", order = 331)]
|
|
public sealed class WLCharacterSwapSettings : ScriptableObject
|
|
{
|
|
public const string ResourcesPath = "WL/WLCharacterSwapSettings";
|
|
|
|
static WLCharacterSwapSettings s_cached;
|
|
static bool s_lookupDone;
|
|
|
|
/// <summary>설정 에셋(1회 로드 후 캐시). 없으면 null = 무동작.</summary>
|
|
public static WLCharacterSwapSettings Instance
|
|
{
|
|
get
|
|
{
|
|
if (!s_lookupDone) { s_cached = Resources.Load<WLCharacterSwapSettings>(ResourcesPath); s_lookupDone = true; }
|
|
return s_cached;
|
|
}
|
|
}
|
|
|
|
/// <summary>QA·A/B 전용 런타임 스위치. 0 = 에셋의 enabled · 1 = 강제 on · -1 = 강제 off.</summary>
|
|
public static int RuntimeOverride;
|
|
|
|
/// <summary>교체가 살아 있는가. false 면 원본 프리팹 이름이 그대로 나간다(C8).</summary>
|
|
public static bool Enabled
|
|
{
|
|
get
|
|
{
|
|
var i = Instance;
|
|
if (i == null || RuntimeOverride < 0) return false;
|
|
return RuntimeOverride > 0 || i.enabled;
|
|
}
|
|
}
|
|
|
|
/// <summary>테스트용: 캐시를 비운다.</summary>
|
|
public static void ClearCache() { s_cached = null; s_lookupDone = false; }
|
|
|
|
[Header("전체 스위치 (PD 되돌리기 1순위)")]
|
|
[Tooltip("끄면 원본 코스튬 프리팹 이름이 그대로 나간다 = 원본 100 %. 에셋을 지워도 같다.")]
|
|
public bool enabled = true;
|
|
|
|
[Tooltip("교체·보정이 일어날 때 Debug.Log 를 남긴다(A/B 확인용). 기본 끔.")]
|
|
public bool verboseLog;
|
|
|
|
[Header("교체 대상")]
|
|
[Tooltip("이 이름의 코스튬 프리팹만 교체한다. 비우면 모든 코스튬을 교체한다. 기본 코스튬 110001 = \"Ai01\".")]
|
|
public string sourcePrefabName = "Ai01";
|
|
|
|
[Tooltip("대신 쓸 프리팹 이름(Assets/Res_Addr/PC/<이름>.prefab). 기본 \"LH_M05\"(Little Heroes RedKnight).")]
|
|
public string pcPrefabName = "LH_M05";
|
|
|
|
[Header("크기 보정 (WLPcScaleCompensator 가 읽는다)")]
|
|
[Tooltip("새 프리팹 루트 스케일에 곱하는 값. M05 원 높이 1.1316 m 를 Ai01 원 높이 1.7017 m 로 맞춘다 → 1.7017/1.1316 = 1.5038.\n" +
|
|
"그러면 인게임(f_Scale 0.7) 1.1912 m · 로비(scale 1) 1.7017 m 로 Ai01 과 완전히 같아진다 = 카메라·콜라이더·NavMesh·도트 픽셀 수 전부 유지.")]
|
|
public float heightCompensation = 1.5038f;
|
|
|
|
/// <summary>
|
|
/// 인게임 PC 코스튬 프리팹 이름을 결정한다. 스위치가 꺼져 있으면 <paramref name="original"/> 를 그대로 돌려준다.
|
|
/// 원본 `PCInfo.cs:16` 이 부르는 유일한 진입점.
|
|
/// </summary>
|
|
public static string Resolve(string original)
|
|
{
|
|
if (!Enabled) return original;
|
|
var i = Instance;
|
|
if (i == null || string.IsNullOrEmpty(i.pcPrefabName)) return original;
|
|
if (!string.IsNullOrEmpty(i.sourcePrefabName) && original != i.sourcePrefabName) return original;
|
|
if (i.verboseLog) Debug.Log("[WL-814n] PC 프리팹 교체: " + original + " → " + i.pcPrefabName);
|
|
return i.pcPrefabName;
|
|
}
|
|
|
|
/// <summary>크기 보정 배수(스위치가 꺼져 있으면 1 = 무보정).</summary>
|
|
public static float HeightCompensation
|
|
{
|
|
get
|
|
{
|
|
var i = Instance;
|
|
if (!Enabled || i == null || i.heightCompensation <= 0f) return 1f;
|
|
return i.heightCompensation;
|
|
}
|
|
}
|
|
}
|
|
}
|