Project_WL/Assets/WL/Look/Sprite/WLSpriteLookSettings.cs

102 lines
5.4 KiB
C#

// ─────────────────────────────────────────────────────────────────────────────
// 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;
/// <summary>에셋이 없으면 null(호출부는 전부 건너뛴다 = C8).</summary>
public static WLSpriteLookSettings Instance
{
get
{
if (s_instance == null && !s_tried) { s_tried = true; s_instance = Resources.Load<WLSpriteLookSettings>(ResourcesPath); }
return s_instance;
}
}
public static void ClearCache() { s_instance = null; s_tried = false; }
/// <summary>프로브·QA 용 런타임 스위치(에셋을 안 건드리고 끈다).</summary>
public static bool RuntimeDisabled;
/// <summary>이 축이 살아 있는가 = 에셋 존재 · enabled_ · 런타임 스위치 off.</summary>
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";
}
}