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

103 lines
6.4 KiB
C#
Raw Permalink Normal View History

[WL-813s] 엘리트 몹: 존별 배치 · 마커 · 드랍 (#813) MonsterAppear.json 에 엘리트 스포너 새 행 4개(813021~813024) 추가 — 기존 52행 바이트 무변경 (813u 가 같은 파일의 존 행을 고치므로 「기존 행 값 수정 0」 · 단일 라인 JSON 이라 rebase 에서 전체 충돌 1회 → main(813u) 값을 기준으로 새 행만 재부착). 존1~4 에 Elite 1종씩 · 동시 1마리 · 리젠 25 s. 🔴 HP 는 발주서 제안값(120~180 · Q3 보스 단일표적 DPS 15/s 기준)이 아니라 **470/540/610/680** 이다. 발주 시점 뒤에 813u 가 존 잡몹 HP 를 300/450/600/800 → 190/270/350/430 으로 내려서, 120~180 이면 엘리트가 같은 존 잡몹보다 약해진다. 813u 실측 존 총 DPS 171.8 HP/s 를 기준서 §E 3-2 규격(1발 명중 ≥3마리)으로 나눈 단일 표적 57.3 HP/s 기준 → 8.2/9.4/10.6/11.9 s = 기준서 「엘리트 8~12 s」. 잡몹 대비 2.47/2.00/1.74/1.58배. ATK 는 813u 존 값과 동률 (6/8/10/12 · Q4-a D-1 사망 이슈 · ATK 밸런스는 813u 소유). WL_Nature.prefab: maplv/e1~e4 스포너 노드 4기 신규(존 스포너와 같은 좌표 · MobGenRange 6 · Lv 라벨 렌더러 끔) — 기존 노드·좌표 무변경(+924 / −0). EliteMarker.cs(신규 · 정적 · 러너 0 · GC 0): Spawned(isElite) → localScale = 테이블 기본 스케일 × 1.3(멱등 · NavMesh 반경 무변경) + 상시 색 등록, Killed(Elite) → 색 해제 + 처치 시간(TTK) 로그. 아웃라인은 QuickOutline 이 프로젝트에 없고 MK Toon 의 _RimColor 가 _MK_RIM_* shader_feature 게이팅이라 MPB 로 못 켠다 → 발주서 대체안대로 MPB 상시 색 (_EmissionColor 주 · _AlbedoColor 보조 · 새 셰이더/머티리얼 0). MobHitFlash 가 렌더러 MPB 의 단일 소유자라 합성 지점(SetEliteTint/ClearEliteTint)만 그 파일에 더했다(우선순위 = 점멸 > 상시). 킬캠(811d)·임팩트 티어(811gh)는 이미 Elite 분기가 열려 있어 코드 0(killCamOnElite=1 · bossKillIncludesElite=1 실측). 드랍은 WLLootSettings.asset 값만 eliteBurst 1~2 → 2~3. 검증: 게이트 PASS(oneshot · error CS 0줄) · 프로브 AgentScripts/WL813s_Probe.cs (새 행 4/4 · 스포너 노드 4/4 · 크기 2.30→2.99 멱등 · 상시 색 O · 일반 몹 미적용 · 킬캠 Elite 1 / 일반 0 · 드랍 버스트 2~3 · 0건 0회 · GC 0 B · C8 PASS · 원본 문자열 0). Play 실측(인게임 화면)은 미확인 — 로그인 금지라 병합 후 QA. xlsm 동기화 안 함(백로그). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 00:25:41 +00:00
// ─────────────────────────────────────────────────────────────────────────────
// WLEliteSettings.cs — 엘리트 몹 마커(크기 · 상시 색 · 처치 시간 로그) 값의 단일 출처(SOT · C45)
//
// PD 지시 #813 · 발주서 WL-813s §1-2 · 기준서 v1 §B 요소 1 「엘리트 = 8~12 s」 · §D-2 813s 행 (2026-09-09)
//
// 에셋 경로(고정): Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset
// → Resources.Load<WLEliteSettings>("WL/WLEliteSettings") 로 1회 로드 후 캐시.
// 에셋이 없거나 enabled = false 또는 RuntimeDisabled 면 EliteMarker 가 아무 것도 하지 않는다
// (C8 · 원본 = 테이블 f_DefaultScale 그대로 · MPB 0 · 813e 배치 동작 100 %).
//
// 【아웃라인 실측 · 2026-09-09】
// · 기준서가 적은 `QuickOutline` 컴포넌트는 **이 프로젝트에 없다**(Assets 전수 검색 결과 Outline 이름 자산은
// TMP 아웃라인 피드백 · VFX 링 머티리얼뿐 · 메시 아웃라인 컴포넌트 0).
// · 몹 셰이더는 MK Toon URP Standard Simple 1종(811def 실측 299 프리팹 중 312 머티리얼).
// 림라이트 프로퍼티(`_RimColor`/`_RimSize`)는 **있으나** `#pragma shader_feature_local __ _MK_RIM_DEFAULT _MK_RIM_SPLIT`
// 키워드 게이팅이라 MaterialPropertyBlock 으로는 켤 수 없고, 이미 켜진 머티리얼에 쓰면 **아트 색을 덮어쓴다**
// → `_RimColor` 는 건드리지 않는다(811gh 교훈 「프로퍼티가 있다고 효과가 있는 게 아니다」).
// · 그래서 발주서가 지정한 대체안 = 811gh PcHitReaction 방식의 **MPB 상시 색**.
// `_EmissionColor`(MK Toon Config.hlsl 이 MK_EMISSION 을 항상 정의 → 키워드 없이 가산 · 확실히 보인다) 가 주 성분,
// `_AlbedoColor`([MainColor] · 게이팅 없음) 가 보조. 새 셰이더/머티리얼 에셋 0 · 머티리얼 인스턴스 0 · 드로우 +0.
//
// 🔴 어셈블리 주의: Assets/WL/Combat/ 에 .asmdef 를 만들지 말 것.
// ─────────────────────────────────────────────────────────────────────────────
using UnityEngine;
namespace WL.Combat.Reaction
{
[CreateAssetMenu(fileName = "WLEliteSettings", menuName = "WL/Elite Settings", order = 325)]
public sealed class WLEliteSettings : ScriptableObject
{
public const string ResourcesPath = "WL/WLEliteSettings";
static WLEliteSettings s_cached;
static bool s_lookupDone;
public static WLEliteSettings Instance
{
get
{
if (!s_lookupDone)
{
s_cached = Resources.Load<WLEliteSettings>(ResourcesPath);
s_lookupDone = true;
}
return s_cached;
}
}
/// <summary>진단·A/B 전용 런타임 스위치. 에셋을 건드리지 않고 마커만 끈다.</summary>
public static bool RuntimeDisabled;
public static bool Enabled
{
get { var i = Instance; return i != null && i.enabled && !RuntimeDisabled; }
}
public static void ClearCache() { s_cached = null; s_lookupDone = false; }
// ─────────────────────────────────────────── 전체 스위치
[Header("전체 스위치")]
[Tooltip("끄면 크기 배수·상시 색·처치 시간 로그가 전부 비활성 = 813e 배치 그대로(원본 동작). 롤백 1순위.")]
public bool enabled = true;
[Tooltip("등장·처치를 Console 에 남긴다(검증용 · GC 발생).")]
public bool verboseLog = false;
// ─────────────────────────────────────────── 크기
[Header("크기 (Spawned(isElite) → localScale = 테이블 기본 스케일 × 배수)")]
[Tooltip("끄면 크기를 건드리지 않는다.")]
public bool scaleEnabled = true;
[Tooltip("MonsterList.f_DefaultScale 로 정해진 원본 스케일에 곱하는 배수. 기준서 813s = 1.3.\n" +
"🔴 NavMeshAgent 반경·stoppingDistance 는 건드리지 않는다(원본 MobActor.Set 이 이미 정한 값 유지).")]
public float scaleMultiplier = 1.3f;
[Tooltip("이 값보다 큰 최종 스케일은 여기서 자른다(카메라 가림 방지 · 0 이하면 제한 없음).")]
public float scaleMaxAbsolute = 6f;
// ─────────────────────────────────────────── 상시 색(아웃라인 대체)
[Header("상시 색 (MPB · 머티리얼 인스턴스 0 · 새 셰이더/머티리얼 0)")]
[Tooltip("끄면 색을 쓰지 않는다. 피격 점멸(MobHitFlash)이 켜지는 동안은 점멸이 이 색을 덮는다(우선순위 = 점멸 > 상시).")]
public bool tintEnabled = true;
[Tooltip("알베도 색 프로퍼티에 쓰는 상시 색(HDR · MK Toon [MainColor] _AlbedoColor). 1 .")]
[ColorUsage(true, true)] public Color tintAlbedo = new Color(1.25f, 1.02f, 0.72f, 1f);
[Tooltip("에미션 프로퍼티에 쓰는 상시 색(HDR · MK Toon _EmissionColor = 키워드 없이 가산). 엘리트의 '테두리 광'.")]
[ColorUsage(true, true)] public Color tintEmission = new Color(0.85f, 0.45f, 0.08f, 1f);
// ─────────────────────────────────────────── 처치 시간(기준서 검증용)
[Header("처치 시간 로그 (기준서 §B 요소1 「엘리트 = 8~12 s」)")]
[Tooltip("등장 → 처치까지 걸린 시간을 재서 Console 에 남긴다(QA 판정 근거). 표본은 링버퍼에 사전 할당 = GC 0.")]
public bool killTimeLogEnabled = true;
[Tooltip("목표 하한(초).")]
public float killTimeTargetMin = 8f;
[Tooltip("목표 상한(초).")]
public float killTimeTargetMax = 12f;
}
}