123 lines
6.0 KiB
C#
123 lines
6.0 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
|
// WLWeaponFitSettings.cs — 치비 PC 의 무기 크기 자동 보정 단일 출처(SOT · C45)
|
|
//
|
|
// 발주서 WL-814p (#814 잔여 결함) · 근거 = 완료보고 WL-814n §1 ⑰
|
|
// 치비 교체 후 `Elven_Sword_01` 월드 최대변 1.341 m = 캐릭터 키(1.1912 m)의 **113 %**
|
|
// → 어른 몸(Ai01 1.7017 m) 기준으로 만든 무기가 치비 손에 그대로 붙어 과대.
|
|
//
|
|
// ■ 어디를 고치나 — 원본 수정 0
|
|
// 원본이 무기를 다는 지점은 `Assets/Script/Character/PCActor.cs:358`
|
|
// Make_Weapon(fullpath, tfs_weapon[index], Vector3.zero, Vector3.one)
|
|
// = Addressables 비동기 콜백에서 소켓에 **localScale 1** 로 붙인다(실측).
|
|
// 814n 에서 원본 1줄 예외를 이미 소진했으므로 훅을 더 넣지 않는다 →
|
|
// **새 프리팹 `LH_M05` 에만 붙는 `WLWeaponFitter`** 가 소켓을 감시해서 보정한다.
|
|
// Ai01 경로에는 이 컴포넌트가 없으므로 구조적으로 영향 0.
|
|
//
|
|
// ■ 되돌리기(C8)
|
|
// 이 에셋의 `enabled_` 를 끄거나 에셋을 지우면 배수 1.0000 = 컴포넌트 no-op = 지금 상태 100 %.
|
|
//
|
|
// 에셋 경로(고정): Assets/WL/Settings/Resources/WL/WLWeaponFitSettings.asset
|
|
// 🔴 Assets/WL/Character/ 에 .asmdef 를 만들지 말 것(Assembly-CSharp 단일).
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace WL.Character
|
|
{
|
|
[CreateAssetMenu(fileName = "WLWeaponFitSettings", menuName = "WL/Weapon Fit Settings", order = 332)]
|
|
public sealed class WLWeaponFitSettings : ScriptableObject
|
|
{
|
|
public const string ResourcesPath = "WL/WLWeaponFitSettings";
|
|
|
|
static WLWeaponFitSettings s_cached;
|
|
static bool s_lookupDone;
|
|
|
|
/// <summary>설정 에셋(1회 로드 후 캐시). 없으면 null = 무동작.</summary>
|
|
public static WLWeaponFitSettings Instance
|
|
{
|
|
get
|
|
{
|
|
if (!s_lookupDone) { s_cached = Resources.Load<WLWeaponFitSettings>(ResourcesPath); s_lookupDone = true; }
|
|
return s_cached;
|
|
}
|
|
}
|
|
|
|
/// <summary>QA·A/B 전용 런타임 스위치. 0 = 에셋의 enabled_ · 1 = 강제 on · -1 = 강제 off.</summary>
|
|
public static int RuntimeOverride;
|
|
|
|
/// <summary>보정이 살아 있는가. false 면 무기 스케일에 손대지 않는다(C8).</summary>
|
|
public static bool Enabled
|
|
{
|
|
get
|
|
{
|
|
var i = Instance;
|
|
if (i == null || RuntimeOverride < 0) return false;
|
|
return RuntimeOverride > 0 || i.enabled_;
|
|
}
|
|
}
|
|
|
|
/// <summary>테스트용: 캐시를 비운다.</summary>
|
|
public static void ClearCache() { s_cached = null; s_lookupDone = false; }
|
|
|
|
[Serializable]
|
|
public sealed class WeaponRatio
|
|
{
|
|
[Tooltip("무기 프리팹 이름(Assets/Res_Addr/Weapon/<이름>.prefab). \"(Clone)\" 은 무시하고 비교한다.")]
|
|
public string weaponName;
|
|
|
|
[Tooltip("이 무기만 쓸 비율(무기 최대변 ÷ 캐릭터 키). 0 이하면 targetRatio 를 쓴다.")]
|
|
public float ratio;
|
|
}
|
|
|
|
[Header("전체 스위치 (PD 되돌리기 1순위)")]
|
|
[Tooltip("끄면 무기 스케일에 아무것도 하지 않는다 = 지금 상태 100 %. 에셋을 지워도 같다.")]
|
|
public bool enabled_ = true;
|
|
|
|
[Tooltip("보정이 일어날 때 Debug.Log 를 남긴다(A/B 확인용). 기본 끔.")]
|
|
public bool verboseLog;
|
|
|
|
[Header("목표 비율")]
|
|
[Tooltip("보정 후 무기 최대변 ÷ 캐릭터 키. 0.60 = 캐릭터 키의 60 %.\n" +
|
|
"치비 교체 전 어른 Ai01(1.7017 m) 기준 Elven_Sword_01 은 0.79 였다(1.341/1.7017).")]
|
|
public float targetRatio = 0.60f;
|
|
|
|
[Tooltip("보정 배수 하한(원본 크기 대비). 0.3 = 아무리 커도 30 % 미만으로는 줄이지 않는다.")]
|
|
public float minScale = 0.3f;
|
|
|
|
[Tooltip("보정 배수 상한(원본 크기 대비). 1.0 = 무기를 키우지는 않는다.")]
|
|
public float maxScale = 1.0f;
|
|
|
|
[Header("무기별 예외 (비어 있으면 전부 targetRatio)")]
|
|
[Tooltip("이름 → 비율 override. 방패·오브처럼 길이 기준이 다른 무기를 따로 잡을 때만 쓴다.")]
|
|
public List<WeaponRatio> perWeapon = new List<WeaponRatio>();
|
|
|
|
/// <summary>무기 이름에 맞는 목표 비율. 스위치가 꺼져 있으면 0(= 무보정).</summary>
|
|
public static float ResolveRatio(string weaponName)
|
|
{
|
|
var i = Instance;
|
|
if (!Enabled || i == null) return 0f;
|
|
if (i.perWeapon != null && !string.IsNullOrEmpty(weaponName))
|
|
{
|
|
var key = Strip(weaponName);
|
|
for (int n = 0; n < i.perWeapon.Count; n++)
|
|
{
|
|
var row = i.perWeapon[n];
|
|
if (row == null || string.IsNullOrEmpty(row.weaponName) || row.ratio <= 0f) continue;
|
|
if (string.Equals(Strip(row.weaponName), key, StringComparison.OrdinalIgnoreCase)) return row.ratio;
|
|
}
|
|
}
|
|
return i.targetRatio > 0f ? i.targetRatio : 0f;
|
|
}
|
|
|
|
/// <summary>"Elven_Sword_01(Clone)" → "Elven_Sword_01" (원본 `DSUtil.Get_Clone` 이 Instantiate 기본 이름을 쓴다).</summary>
|
|
public static string Strip(string n)
|
|
{
|
|
if (string.IsNullOrEmpty(n)) return n;
|
|
int i = n.IndexOf("(Clone)", StringComparison.Ordinal);
|
|
return i >= 0 ? n.Substring(0, i).Trim() : n.Trim();
|
|
}
|
|
}
|
|
}
|