// ───────────────────────────────────────────────────────────────────────────── // WLReferenceLookSettings.cs — 「레퍼런스 느낌」 4요소의 값 단일 출처 (WL-814t · #814) // // PD 지시(2026-09-12) 「레퍼런스 게임 같은 느낌을 살릴 수 없을까?」 · 발주서 WL-814t §2-3. // 레퍼런스 특징 = ⓐ 굵은 검은 외곽선 ⓑ 매우 어두운 그림자(강한 대비) // ⓒ 보라~자홍 배경 + 금색/주황 조명 ⓓ 윤곽의 밝은 테(림라이트) // // ■ C45 — 값은 코드 상수가 아니라 이 에셋(`Resources/WL/WLReferenceLookSettings.asset`) // ■ C8 — `enabled_ = 0` 이면 `WLReferenceLook` 이 **아무것도 하지 않는다** = 814s 상태 100 % // // 🔴 어셈블리 주의: Assets/WL/Look/ 에 .asmdef 를 만들지 말 것(Assembly-CSharp 단일). // ───────────────────────────────────────────────────────────────────────────── using UnityEngine; namespace WL.Look.Arena { [CreateAssetMenu(fileName = "WLReferenceLookSettings", menuName = "WL/Reference Look Settings", order = 37)] public sealed class WLReferenceLookSettings : ScriptableObject { public const string ResourcesPath = "WL/WLReferenceLookSettings"; private static WLReferenceLookSettings s_instance; private static bool s_tried; /// 에셋이 없으면 null — 호출부는 전부 건너뛴다(C8 롤백). public static WLReferenceLookSettings Instance { get { if (s_instance == null && !s_tried) { s_tried = true; s_instance = Resources.Load(ResourcesPath); } return s_instance; } } [Header("마스터 (C8)")] [Tooltip("0 이면 이 기능 전체가 꺼진다 = WL-814s 상태 100 %.")] public int enabled_ = 1; [Tooltip("1 이면 적용 결과를 콘솔에 1줄 남긴다.")] public int verboseLog = 0; // ── Ⓐ 외곽선 ──────────────────────────────────────────────────────── [Header("Ⓐ 외곽선 (inverted hull · 두께 단위 = 화면 픽셀 @1080×1920)")] public bool outlineOn = true; [Tooltip("캐릭터 외곽선 두께(px · 아레나 실제 카메라 직교 10 = 캐릭터 키 98~117 px 기준). " + "🔴 814u 실측: 이 크기에서 1 px 띠가 이미 캐릭터 면적의 27 %, 3 px 이면 76 % 를 먹는다 → 상한 1(비교용 2).")] public float outlineWidth = 1.0f; [Tooltip("도트(픽셀) 모드에서 쓰는 캐릭터 외곽선 두께(px · 저해상도 RT 기준).")] public float outlineWidthPixelMode = 1.0f; [Tooltip("외곽선 색. 순검정보다 아주 어두운 중성/보라가 레퍼런스에 가깝다.")] public Color outlineColor = new Color(0.043f, 0.031f, 0.067f, 1f); [Tooltip("배경(바위·나무·건물)에도 외곽선을 넣을지.")] public bool outlineOnBackground = true; [Tooltip("배경 외곽선 두께(px @직교 10). 배경 물체는 화면에서 크므로 캐릭터보다 굵어도 된다.")] public float outlineWidthBackground = 2.5f; [Tooltip("켜면 두께를 카메라 줌(직교 크기)에 맞춰 비례시킨다 = 캐릭터 대비 굵기가 항상 같다(2D 스프라이트처럼).")] public bool outlineScaleWithZoom = true; [Tooltip("위 비례의 기준 직교 반높이 = 아레나 실제 카메라(10). 이 크기일 때 두께가 위 px 값 그대로다.")] public float outlineRefOrthoSize = 10f; [Tooltip("0 = 균일 색(검정) · 1 = 표면색 연동(머리칼=짙은 갈색, 옷=짙은 빨강 …). 레퍼런스는 부위마다 선 색이 다르다.")] [Range(0f, 1f)] public float outlineTintAmount = 0f; [Tooltip("색 연동일 때 표면색을 얼마나 어둡게 할지(작을수록 진하다).")] [Range(0f, 1f)] public float outlineTintDarkness = 0.28f; [Tooltip("껍데기를 카메라에서 뒤로 미는 양(m). 저폴리 하드에지의 실루엣 안쪽 얼룩을 없앤다.")] public float outlineDepthBias = 0.06f; // ── Ⓑ 명암 대비 ───────────────────────────────────────────────────── [Header("Ⓑ 명암 대비 (Toon 램프)")] public bool contrastOn = true; [Tooltip("`_MinimumDarkness` — 그림자 바닥 밝기. 기본 0.2 · 낮을수록 어둡다.")] [Range(0f, 0.5f)] public float minimumDarkness = 0.08f; [Tooltip("`_ShadowDiffuseColor` 에 곱하는 계수. 1 미만이면 그림자가 더 진해진다.")] [Range(0.2f, 1.5f)] public float shadowColorScale = 0.72f; [Tooltip("그림자에 섞을 색조(보라). 0 이면 안 섞는다.")] [Range(0f, 1f)] public float shadowTintAmount = 0.35f; public Color shadowTint = new Color(0.243f, 0.106f, 0.353f, 1f); [Tooltip("캐릭터 `_Shades`(색 단계 수). 0 이면 원래 값(배경과 동일 7) 유지. 레퍼런스2 = 부위당 2~3단.")] public int charShades = 0; // ── Ⓒ 색조·분위기 ─────────────────────────────────────────────────── [Header("Ⓒ 색조·분위기 (Volume + 라이트)")] public bool moodOn = true; [Tooltip("0=끔 · 0.5=은은 · 1=강함. Volume weight 와 라이트 보간에 함께 쓴다.")] [Range(0f, 1f)] public float moodStrength = 0.75f; [Tooltip("씬에 붙일 포스트 프로파일(없으면 Ⓒ 는 라이트만 바꾼다).")] public VolumeProfileRef profile = new VolumeProfileRef(); [Tooltip("키라이트(Directional) 목표 색 — 레퍼런스의 금색/주황.")] public Color keyLightColor = new Color(1f, 0.76f, 0.42f, 1f); [Tooltip("키라이트 목표 세기.")] public float keyLightIntensity = 1.15f; [Tooltip("앰비언트 목표 색 — 레퍼런스의 보라~자홍.")] public Color ambientColor = new Color(0.259f, 0.165f, 0.373f, 1f); // ── Ⓓ 림라이트 ────────────────────────────────────────────────────── [Header("Ⓓ 림라이트 (캐릭터 윤곽의 밝은 테)")] public bool rimOn = true; [Range(0f, 4f)] public float rimStrength = 1.25f; [Range(0.5f, 8f)] public float rimPower = 3.0f; [Range(0f, 1f)] public float rimUpBias = 0.35f; public Color rimColor = new Color(1f, 0.82f, 0.5f, 1f); [Tooltip("배경에도 림을 넣을지(레퍼런스는 캐릭터만).")] public bool rimOnBackground = false; /// 인스펙터에서 프로파일을 물릴 수 있게 하는 얇은 래퍼(Volume 패키지 타입 직접 노출). [System.Serializable] public sealed class VolumeProfileRef { public UnityEngine.Rendering.VolumeProfile asset; } } }