2026-09-06 23:24:25 +00:00
|
|
|
// PD #797 — WLHitFeelSettings 에셋 생성/확인/조정 (Edit 모드 전용 · 리컴파일 완료 후 실행)
|
|
|
|
|
// 확정값은 Edit 모드에서 굽고 Dump 로 디스크와 대조한다(Play 중 에셋 인스턴스 수정 금지).
|
|
|
|
|
using System.Text;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
|
|
|
|
public static class WL797_MakeAsset
|
|
|
|
|
{
|
|
|
|
|
const string Dir1 = "Assets/WL/Feel";
|
|
|
|
|
const string Dir2 = "Assets/WL/Feel/Settings";
|
|
|
|
|
const string Dir3 = "Assets/WL/Feel/Settings/Resources";
|
|
|
|
|
const string Dir4 = "Assets/WL/Feel/Settings/Resources/WL";
|
|
|
|
|
const string Path = "Assets/WL/Feel/Settings/Resources/WL/WLHitFeelSettings.asset";
|
|
|
|
|
|
|
|
|
|
static void EnsureFolder(string parent, string leaf)
|
|
|
|
|
{
|
|
|
|
|
var full = parent + "/" + leaf;
|
|
|
|
|
if (!AssetDatabase.IsValidFolder(full)) AssetDatabase.CreateFolder(parent, leaf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static object Create()
|
|
|
|
|
{
|
|
|
|
|
EnsureFolder("Assets/WL", "Feel");
|
|
|
|
|
EnsureFolder(Dir1, "Settings");
|
|
|
|
|
EnsureFolder(Dir2, "Resources");
|
|
|
|
|
EnsureFolder(Dir3, "WL");
|
|
|
|
|
|
|
|
|
|
var so = AssetDatabase.LoadAssetAtPath<WLHitFeelSettings>(Path);
|
|
|
|
|
bool created = false;
|
|
|
|
|
if (so == null)
|
|
|
|
|
{
|
|
|
|
|
so = ScriptableObject.CreateInstance<WLHitFeelSettings>();
|
|
|
|
|
AssetDatabase.CreateAsset(so, Path);
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
AssetDatabase.Refresh();
|
|
|
|
|
created = true;
|
|
|
|
|
}
|
|
|
|
|
return (created ? "CREATED " : "EXISTS ") + Path + "\n" + Dump();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>디스크의 확정값을 그대로 읽어 출력한다(Play 중 변경이 디스크로 새지 않았는지 대조용).</summary>
|
|
|
|
|
public static object Dump()
|
|
|
|
|
{
|
|
|
|
|
var so = AssetDatabase.LoadAssetAtPath<WLHitFeelSettings>(Path);
|
|
|
|
|
if (so == null) return "MISSING " + Path;
|
|
|
|
|
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
sb.AppendLine("── WLHitFeelSettings (disk) ──");
|
|
|
|
|
sb.AppendLine("enabled=" + so.enabled + " throttleSeconds=" + so.throttleSeconds);
|
|
|
|
|
sb.AppendLine("① hitStop: enabled=" + so.hitStopEnabled + " mode=" + so.hitStopMode
|
|
|
|
|
+ " dur=" + so.hitStopDuration + " killDur=" + so.hitStopKillDuration
|
|
|
|
|
+ " scale=" + so.hitStopTimeScale + " max=" + so.hitStopMax + " minTS=" + so.hitStopMinTimescale);
|
|
|
|
|
sb.AppendLine("② shake: enabled=" + so.cameraShakeEnabled + " amp=" + so.shakeAmplitude
|
|
|
|
|
+ " dur=" + so.shakeDuration + " freq=" + so.shakeFrequency
|
|
|
|
|
+ " axis=" + so.shakeAxisWeight + " killMul=" + so.shakeKillMultiplier
|
|
|
|
|
+ " suppressLegacy=" + so.suppressLegacyShake);
|
|
|
|
|
sb.AppendLine("③ punch: enabled=" + so.scalePunchEnabled + " punch=" + so.scalePunch
|
|
|
|
|
+ " dur=" + so.scalePunchDuration + " skipBoss=" + so.skipPunchOnBoss + " skipKill=" + so.skipPunchOnKill);
|
|
|
|
|
sb.AppendLine("④ flash: enabled=" + so.flashEnabled + " color=" + so.flashColor + " dur=" + so.flashDuration);
|
|
|
|
|
sb.AppendLine("⑤ haptic: enabled=" + so.hapticEnabled);
|
|
|
|
|
sb.AppendLine("log: " + so.logHits);
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-07 05:01:36 +00:00
|
|
|
/// <summary>세기 프리셋. args: "weak" | "mid" | "midplus" | "strong" | "off"</summary>
|
2026-09-06 23:24:25 +00:00
|
|
|
public static object Preset(string name)
|
|
|
|
|
{
|
|
|
|
|
var so = AssetDatabase.LoadAssetAtPath<WLHitFeelSettings>(Path);
|
|
|
|
|
if (so == null) return "MISSING " + Path;
|
|
|
|
|
|
|
|
|
|
switch ((name ?? "").ToLowerInvariant())
|
|
|
|
|
{
|
|
|
|
|
case "off":
|
|
|
|
|
so.enabled = false;
|
|
|
|
|
break;
|
|
|
|
|
case "weak": // A — Feel 공식 Barbarians 데모와 같은 강도
|
|
|
|
|
so.enabled = true;
|
|
|
|
|
so.hitStopDuration = 0.02f; so.hitStopKillDuration = 0.035f;
|
|
|
|
|
so.shakeAmplitude = 0.08f; so.shakeDuration = 0.10f;
|
|
|
|
|
so.scalePunch = 1.08f;
|
|
|
|
|
break;
|
|
|
|
|
case "mid": // B — 발주 기본값 (권고)
|
|
|
|
|
so.enabled = true;
|
|
|
|
|
so.hitStopDuration = 0.03f; so.hitStopKillDuration = 0.05f;
|
|
|
|
|
so.shakeAmplitude = 0.10f; so.shakeDuration = 0.12f;
|
|
|
|
|
so.scalePunch = 1.12f;
|
|
|
|
|
break;
|
2026-09-07 05:01:36 +00:00
|
|
|
case "midplus": // B+ — PD 2026-09-07 "현재보다 미세하게 강하게" (mid 와 strong 의 중간)
|
|
|
|
|
case "mid+":
|
|
|
|
|
so.enabled = true;
|
|
|
|
|
so.hitStopDuration = 0.04f; so.hitStopKillDuration = 0.065f;
|
|
|
|
|
so.shakeAmplitude = 0.11f; so.shakeDuration = 0.12f;
|
|
|
|
|
so.scalePunch = 1.14f;
|
|
|
|
|
break;
|
2026-09-06 23:24:25 +00:00
|
|
|
case "strong": // C — 발주 상한
|
|
|
|
|
so.enabled = true;
|
|
|
|
|
so.hitStopDuration = 0.05f; so.hitStopKillDuration = 0.08f;
|
|
|
|
|
so.shakeAmplitude = 0.12f; so.shakeDuration = 0.12f;
|
|
|
|
|
so.scalePunch = 1.16f;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2026-09-07 05:01:36 +00:00
|
|
|
return "UNKNOWN preset '" + name + "' (weak|mid|midplus|strong|off)";
|
2026-09-06 23:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EditorUtility.SetDirty(so);
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
AssetDatabase.Refresh();
|
|
|
|
|
return "PRESET " + name + " applied\n" + Dump();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>진단 로그 on/off. args: true|false</summary>
|
|
|
|
|
public static object SetLog(bool on)
|
|
|
|
|
{
|
|
|
|
|
var so = AssetDatabase.LoadAssetAtPath<WLHitFeelSettings>(Path);
|
|
|
|
|
if (so == null) return "MISSING " + Path;
|
|
|
|
|
so.logHits = on;
|
|
|
|
|
EditorUtility.SetDirty(so);
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
return "logHits=" + so.logHits;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>플래시 on/off (PD 옵션).</summary>
|
|
|
|
|
public static object SetFlash(bool on)
|
|
|
|
|
{
|
|
|
|
|
var so = AssetDatabase.LoadAssetAtPath<WLHitFeelSettings>(Path);
|
|
|
|
|
if (so == null) return "MISSING " + Path;
|
|
|
|
|
so.flashEnabled = on;
|
|
|
|
|
EditorUtility.SetDirty(so);
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
return "flashEnabled=" + so.flashEnabled;
|
|
|
|
|
}
|
|
|
|
|
}
|