ThreeKingdomsSlingshot/Assets/Scripts/Editor/SkillTestTools.cs

131 lines
6.4 KiB
C#
Raw Permalink Normal View History

스킬 이펙트 작업 준비 — 스킬 테스트 씬 · WL 이펙트 이식 · 이펙트 표 · 보병·창·기병 슬링샷 공격 = WL 창 돌진 이펙트 시험(PD 2026-11-09) PD 「WL 프로젝트에서 스킬을 구현하던 방식과 동일하게 유닛 별 스킬 구현」 · 「테스트 목적: 보병, 창, 기병을 슬링샷으로 공격할 때 WL 창 돌진 공격 이펙트」 - 스킬 테스트 씬 Assets/Scenes/SkillTest.unity(SkillTestBootstrap · 메뉴 TKS/Skill Test/Build Scene): 영웅 목록 선택(heroes.csv 56) · 더미(죽지 않음 · 행동 토글 · 배치 표 Resources/Skills/skill_test.csv) · 슬링샷 · 액티브 버튼 · 쿨 무시 · 영웅 무적 · 이펙트 보기(에디터 · Assets/VFX 검색 → 영웅에 띄움) - 이펙트 표 Resources/Skills/skill_vfx.csv → Runtime/Skills/SkillVfx(키 = 스킬 id 또는 basic_<병종> · cast/travel/hit · f_every 반복 · 사본 Resources/Fx/TKS_Fx_*) · 훅 = SkillSystem Announce/BeginAction/EndAction/Hit/Instant - WL 이펙트 이식 Assets/VFX(약 640 MB · 빌트인 호환분만 · GUID 유지 · 도구 Tools/wl_vfx_import.py) · URP 셰이더 빌트인 이식 4종 Assets/VFX/_BuiltinPorts · com.unity.shadergraph 17.3.0 · 카메라 깊이 텍스처 켬(셰이더 그래프 소프트 파티클) - 시험: basic_infantry/spear/cavalry travel = TKS_Fx_SpearRush · SpearRushWrap · SpearRushDust(WL WLStaffEarth rushFx 1~3 값 환산) — 표 9행 삭제 = 원래대로 - 테스트 118/118 · console error 0 · 이 PC 첫 임포트 자동 재직렬화(png·tga .meta · UITheme · ProjectSettings · InputManager)는 제외 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 14:12:52 +00:00
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace TKS.EditorTools
{
/// <summary>
/// 스킬 이펙트 작업 도구(2026-11-09 PD 「WL 방식과 동일하게 유닛별 스킬 구현 · 테스트용 씬」).
/// ① 스킬 테스트 씬 만들기/열기 ② WL 에서 옮겨 온 이펙트(Assets/VFX) 재질 검사(분홍 · 빠진 스크립트)
/// ③ 고른 팩 프리팹 → 스킬 이펙트 사본 Resources/Fx/TKS_Fx_&lt;이름&gt;.prefab(원본 팩 무수정 · WL 의 WL_Fx_* 사본 규칙).
/// </summary>
public static class SkillTestTools
{
public const string ScenePath = "Assets/Scenes/SkillTest.unity";
public const string FxCopyFolder = "Assets/Resources/Fx";
/// <summary>씬을 새로 만든다(열린 씬은 건드리지 않음 · 추가로 열었다 저장 후 닫음 · 대화 상자 없음).</summary>
[MenuItem("TKS/Skill Test/Build Scene (스킬 테스트 씬 만들기)")]
public static void BuildScene()
{
var open = EditorSceneManager.GetSceneByPath(ScenePath);
if (open.IsValid() && open.isLoaded)
{
Debug.LogWarning("[TKS] 스킬 테스트 씬이 열려 있어 다시 만들지 않습니다(다른 씬을 연 뒤 다시).");
return;
}
var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive);
var cam = new GameObject("Main Camera");
cam.tag = "MainCamera";
var c = cam.AddComponent<Camera>();
c.orthographic = true;
cam.transform.position = new Vector3(0f, 0f, -10f);
EditorSceneManager.MoveGameObjectToScene(cam, scene);
var go = new GameObject("SkillTestBootstrap");
var boot = go.AddComponent<SkillTestBootstrap>();
boot.Config = AssetDatabase.LoadAssetAtPath<BalanceConfig>("Assets/Resources/BalanceConfig.asset");
EditorSceneManager.MoveGameObjectToScene(go, scene);
Directory.CreateDirectory(Path.GetDirectoryName(ScenePath));
EditorSceneManager.SaveScene(scene, ScenePath);
EditorSceneManager.CloseScene(scene, true);
AssetDatabase.Refresh();
Debug.Log("[TKS] 스킬 테스트 씬 저장: " + ScenePath);
}
[MenuItem("TKS/Skill Test/Open Scene (스킬 테스트 씬 열기)")]
public static void OpenScene()
{
if (!File.Exists(ScenePath)) BuildScene();
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) EditorSceneManager.OpenScene(ScenePath, OpenSceneMode.Single);
}
/// <summary>Assets/VFX 재질(셰이더 없음 · 오류 셰이더 · 미지원 · 컴파일 오류)과 빠진 스크립트 프리팹을 센다. 반환 = 보고 문자열.</summary>
[MenuItem("TKS/VFX/Check Imported VFX (이펙트 재질 검사)")]
public static string CheckVfx()
{
var sb = new StringBuilder();
int total = 0, bad = 0;
foreach (var g in AssetDatabase.FindAssets("t:Material", new[] { SkillTestBootstrap.VfxRoot }))
{
var p = AssetDatabase.GUIDToAssetPath(g);
var m = AssetDatabase.LoadAssetAtPath<Material>(p);
total++;
string why = null;
if (m == null) why = "읽기 실패";
else if (m.shader == null) why = "셰이더 없음";
else if (m.shader.name == "Hidden/InternalErrorShader") why = "오류 셰이더";
else if (!m.shader.isSupported) why = "미지원 " + m.shader.name;
else if (ShaderUtil.ShaderHasError(m.shader)) why = "컴파일 오류 " + m.shader.name;
if (why == null) continue;
bad++;
if (bad <= 20) sb.AppendLine(" 재질 " + why + " · " + p);
}
int prefabs = 0, missing = 0;
foreach (var g in AssetDatabase.FindAssets("t:Prefab", new[] { SkillTestBootstrap.VfxRoot }))
{
var p = AssetDatabase.GUIDToAssetPath(g);
var go = AssetDatabase.LoadAssetAtPath<GameObject>(p);
if (go == null) continue;
prefabs++;
foreach (var comp in go.GetComponentsInChildren<Component>(true))
{
if (comp != null) continue;
missing++;
if (missing <= 20) sb.AppendLine(" 빠진 스크립트 · " + p);
break;
}
}
string head = "[TKS] VFX 검사: 재질 " + total + " · 문제 " + bad + " · 프리팹 " + prefabs + " · 빠진 스크립트 " + missing;
Debug.Log(head + "\n" + sb);
return head + "\n" + sb;
}
/// <summary>Project 창에서 고른 팩 프리팹 → Resources/Fx/TKS_Fx_&lt;이름&gt;.prefab 사본(이미 있으면 건너뜀). 스킬 이펙트 표 s_fx 에 그 이름을 쓴다.</summary>
[MenuItem("TKS/VFX/Make Skill Fx Copy (선택 프리팹 → 스킬 이펙트 사본)")]
public static void CopySelected()
{
foreach (var o in Selection.objects)
{
var p = AssetDatabase.GetAssetPath(o);
if (!p.EndsWith(".prefab")) continue;
MakeCopy(p, null);
}
}
/// <summary>팩 프리팹 사본 만들기(이름 = TKS_Fx_ + name 또는 원본 이름) · 반환 = 사본 경로.</summary>
public static string MakeCopy(string srcPath, string name)
{
if (!Directory.Exists(FxCopyFolder)) Directory.CreateDirectory(FxCopyFolder);
string n = string.IsNullOrEmpty(name) ? Path.GetFileNameWithoutExtension(srcPath) : name;
n = n.Replace(' ', '_');
if (!n.StartsWith("TKS_Fx_")) n = "TKS_Fx_" + n;
string dst = FxCopyFolder + "/" + n + ".prefab";
if (File.Exists(dst))
{
Debug.Log("[TKS] 사본 이미 있음: " + dst);
return dst;
}
AssetDatabase.Refresh();
if (!AssetDatabase.CopyAsset(srcPath, dst))
{
Debug.LogError("[TKS] 사본 실패: " + srcPath + " → " + dst);
return null;
}
Debug.Log("[TKS] 스킬 이펙트 사본: " + srcPath + " → " + dst);
return dst;
}
}
}