138 lines
7.6 KiB
C#
138 lines
7.6 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
||
// 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;
|
||
|
||
/// <summary>에셋이 없으면 null — 호출부는 전부 건너뛴다(C8 롤백).</summary>
|
||
public static WLReferenceLookSettings Instance
|
||
{
|
||
get
|
||
{
|
||
if (s_instance == null && !s_tried)
|
||
{
|
||
s_tried = true;
|
||
s_instance = Resources.Load<WLReferenceLookSettings>(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;
|
||
|
||
/// <summary>인스펙터에서 프로파일을 물릴 수 있게 하는 얇은 래퍼(Volume 패키지 타입 직접 노출).</summary>
|
||
[System.Serializable]
|
||
public sealed class VolumeProfileRef
|
||
{
|
||
public UnityEngine.Rendering.VolumeProfile asset;
|
||
}
|
||
}
|
||
}
|