90 lines
4.1 KiB
C#
90 lines
4.1 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
|
// WLCharacterPalette.cs — 팔레트 아틀라스 UV 를 런타임에 끼운다 (WL-814x)
|
|
//
|
|
// PD 지시 #814 · 발주서 WL-814x
|
|
//
|
|
// ■ 왜 이렇게 하나
|
|
// 화면 속 캐릭터는 키 117 px 뿐이라 텍셀 수천 개가 평균 나 화면 1 px 이 된다(814u 실측).
|
|
// 그래서 텍스처를 아무리 곱게 그려도 「흐린 사진」이 된다.
|
|
// → 메시의 각 덩어리 UV 를 **팔레트 텍스처의 칸 한가운데**로 보내면 그 덩어리는
|
|
// 아무리 축소돼도 항상 단색이다(평균 날 디테일이 애초에 없다).
|
|
//
|
|
// ■ 되돌리기
|
|
// WLCharacterPaletteSettings.enabled_ = 0 → 아무것도 안 한다 = 814s + 814t 상태 100 %.
|
|
//
|
|
// ■ 성능 / GC
|
|
// Awake 1회. 렌더러 수(7)만큼만 돈다. 바꿀 것이 없으면 대입도 하지 않는다.
|
|
//
|
|
// 🔴 Debug.LogError / Debug.LogException 을 쓰지 않는다(813z 규칙).
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace WL.Look.Character
|
|
{
|
|
public static class WLCharacterPalette
|
|
{
|
|
// 진단(프로브가 읽는다)
|
|
public static int AppliedRenderers, AppliedMeshes;
|
|
public static string LastLog = "";
|
|
|
|
static readonly List<Renderer> s_buf = new List<Renderer>(16);
|
|
|
|
/// <summary>SO 가 켜져 있으면 팔레트 메시·머티리얼로 갈아끼운다.</summary>
|
|
public static void Apply(GameObject root)
|
|
{
|
|
AppliedRenderers = 0; AppliedMeshes = 0;
|
|
var cfg = WLCharacterPaletteSettings.Instance;
|
|
if (cfg == null || root == null || cfg.enabled_ == 0)
|
|
{
|
|
LastLog = cfg == null ? "SO 없음 → 적용 0" : "enabled_=0 → 적용 0 (814s+814t 상태)";
|
|
return;
|
|
}
|
|
var names = cfg.rendererNames;
|
|
if (names == null || names.Length == 0) { LastLog = "표 비어 있음 → 적용 0"; return; }
|
|
|
|
s_buf.Clear();
|
|
root.GetComponentsInChildren<Renderer>(true, s_buf);
|
|
for (int ri = 0; ri < s_buf.Count; ri++)
|
|
{
|
|
var r = s_buf[ri];
|
|
if (r == null) continue;
|
|
int idx = IndexOf(names, r.name);
|
|
if (idx < 0) continue;
|
|
|
|
// ① 메시 — 스킨 메시는 본/바인드포즈가 원본과 같으므로 그대로 갈아끼워진다.
|
|
var smr = r as SkinnedMeshRenderer;
|
|
if (smr != null && cfg.paletteMeshes != null && idx < cfg.paletteMeshes.Length)
|
|
{
|
|
var m = cfg.paletteMeshes[idx];
|
|
if (m != null && smr.sharedMesh != m) { smr.sharedMesh = m; AppliedMeshes++; }
|
|
}
|
|
|
|
// ② 머티리얼
|
|
if (cfg.paletteMaterials != null && idx < cfg.paletteMaterials.Length)
|
|
{
|
|
var want = cfg.paletteMaterials[idx];
|
|
if (want != null)
|
|
{
|
|
var mats = r.sharedMaterials;
|
|
bool changed = false;
|
|
for (int si = 0; si < mats.Length; si++)
|
|
if (mats[si] != want) { mats[si] = want; changed = true; }
|
|
if (changed) { r.sharedMaterials = mats; AppliedRenderers++; }
|
|
}
|
|
}
|
|
}
|
|
|
|
LastLog = "렌더러 " + AppliedRenderers + " · 메시 " + AppliedMeshes;
|
|
if (cfg.verboseLog != 0) Debug.Log("[WL814x CharacterPalette] " + LastLog);
|
|
}
|
|
|
|
static int IndexOf(string[] names, string n)
|
|
{
|
|
for (int i = 0; i < names.Length; i++) if (names[i] == n) return i;
|
|
return -1;
|
|
}
|
|
}
|
|
}
|