// ───────────────────────────────────────────────────────────────────────────── // WLSpriteLookSettings.cs — 런타임 빌보드 교체(도트 모드 한정)의 값 단일 출처 (WL-814k · #814) // // ■ C8 롤백: `enabled_ = 0` → 러너를 아예 만들지 않는다 = 원본 3D 100 %. // ■ 🔴 여기에도 특정 캐릭터 이름은 **SO 참조 목록**으로만 들어간다(코드 상수 0). // 시트 SO(WLSpriteSet)가 `actorNamePrefix` 를 들고 있으므로, 목록에 SO 를 넣기만 하면 대상이 된다. // // 🔴 어셈블리 주의: Assets/WL/Look/ 에 .asmdef 를 만들지 말 것(Assembly-CSharp 단일). // ───────────────────────────────────────────────────────────────────────────── using UnityEngine; namespace WL.Look.SpriteBake { [CreateAssetMenu(fileName = "WLSpriteLookSettings", menuName = "WL/Sprite Look Settings (도트 빌보드)", order = 38)] public sealed class WLSpriteLookSettings : ScriptableObject { public const string ResourcesPath = "WL/WLSpriteLookSettings"; static WLSpriteLookSettings s_instance; static bool s_tried; /// 에셋이 없으면 null(호출부는 전부 건너뛴다 = C8). public static WLSpriteLookSettings Instance { get { if (s_instance == null && !s_tried) { s_tried = true; s_instance = Resources.Load(ResourcesPath); } return s_instance; } } public static void ClearCache() { s_instance = null; s_tried = false; } /// 프로브·QA 용 런타임 스위치(에셋을 안 건드리고 끈다). public static bool RuntimeDisabled; /// 이 축이 살아 있는가 = 에셋 존재 · enabled_ · 런타임 스위치 off. public static bool Enabled { get { if (RuntimeDisabled) return false; var s = Instance; return s != null && s.enabled_; } } [Header("공통 (C8 롤백)")] [Tooltip("끄면 러너 0 · 교체 0 = 원본 3D 100 %.")] public bool enabled_ = true; [Tooltip("켜면 교체/복원마다 Console 에 1줄(문자열은 이 값으로 막고 만든다 · GC 주의).")] public bool verboseLog = false; [Header("언제 켜는가")] [Tooltip("🔴 도트 모드(814d LookModeHub 프리셋 pixelRig)에서만 켠다. 끄면 항상 켠다(디버그).")] public bool onlyInPixelMode = true; [Tooltip("새로 스폰된 액터를 찾아보는 주기(초). 0.5 = 프레임당 비용 0에 가깝다.")] public float sweepSeconds = 0.5f; [Tooltip("동시에 스프라이트로 바꿀 액터 수 상한(초과분은 원본 3D 그대로).")] public int maxActors = 24; [Header("시트 목록 — 대상 = 여기 있는 SO 의 actorNamePrefix")] public WLSpriteSet[] sets = new WLSpriteSet[0]; [Header("빌보드")] [Tooltip("🔴 기본(끔) = 카메라 정렬(구운 각도 그대로 · 스프라이트 1px = 화면 1px). " + "켜면 Y축만 회전하는 수직 쿼드 — 구울 때의 내림각만큼 세로가 눌린다(cos 43.6° = 0.72).")] public bool yAxisOnly = false; [Tooltip("yAxisOnly 일 때 눌림을 1/cos(내림각) 로 보정한다.")] public bool yAxisOnlyCompensate = true; [Tooltip("쿼드를 카메라 쪽으로 살짝 당긴다(m) — z-파이팅 여유분.")] public float depthBias = 0.02f; [Tooltip("🔴 켜면 쿼드가 지면에 파묻히지 않도록 필요한 만큼 자동으로 더 당긴다. " + "쿼드는 카메라와 같은 각도로 기울어 있어서 **발밑보다 아래쪽 부분이 지면 속으로 들어간다** — " + "실측(814k): 끄면 캐릭터 아랫부분 7 px 이 지면에 잘렸다. 직교 카메라(도트 모드)에서는 " + "시선 방향으로 당겨도 화면 위치가 1 px 도 안 움직이므로 공짜다.")] public bool autoDepthBias = true; [Tooltip("알파 컷 임계(구울 때 이미 이진화했으므로 0.5 고정 권장).")] [Range(0.01f, 0.99f)] public float alphaCutoff = 0.5f; [Tooltip("빌보드 쿼드가 그려질 레이어(-1 = 액터와 같은 레이어).")] public int quadLayer = -1; [Tooltip("SkinnedMeshRenderer 외에 일반 MeshRenderer(무기·장식)도 같이 끈다. " + "구운 시트에는 그것들도 그려져 있으므로 켜 두는 것이 맞다. 파티클은 건드리지 않는다.")] public bool alsoHideMeshRenderers = true; [Tooltip("그림자 — 구운 스프라이트는 그림자를 못 만든다(한계). 켜면 쿼드 모양 그림자가 생겨 더 이상하다.")] public bool castShadows = false; [Header("동작 폴링")] [Tooltip("Animator 상태를 몇 초마다 다시 볼지. 0 = 매 프레임(가장 정확 · 그래도 할당 0).")] public float statePollSeconds = 0f; [Tooltip("모르는 상태에 들어갔을 때 쓸 동작 키.")] public string fallbackActionKey = "idle"; } }