diff --git a/AgentScripts/WL813s_Probe.cs b/AgentScripts/WL813s_Probe.cs new file mode 100644 index 000000000..9bd6ea1e1 --- /dev/null +++ b/AgentScripts/WL813s_Probe.cs @@ -0,0 +1,521 @@ +// PD 지시 #813 · 발주서 WL-813s — 엘리트 몹(존별 배치 · 크기 1.3× · 상시 색 · HP 8~12 s · 킬캠 · 드랍) 검증 프로브 +// (에디트 모드 전용 · Play 0 · 로그인 0 · 에셋 무수정) +// +// 실행 (CLAUDE.md §1: using 금지 · 네임스페이스 풀어 쓰기) +// unity command run_script --file AgentScripts/WL813s_Probe.cs --entry WL813s_Probe.Edit --timeout 900 +// +// 무엇을 재는가 +// A. 데이터 — MonsterAppear.json 새 행 813021~813024 인식 · 몹 ID 가 MonsterList 의 Elite 인지 · +// 실 HP(f_BaseHPRate × n_MonsterHP) → Q3 실측 DPS 15/s 기준 처치 시간 · 몹/투사체 프리팹 실존 · +// WL_Nature.prefab 의 스포너 전수(존 5 + 엘리트 4 + 레거시 14) 연결 · text_lv null 0 +// B. 마커 — 진짜 엘리트 프리팹으로 가짜 Spawned(Elite) → 스케일 1.3× · MPB 색 부착 · **멱등**(2회) · +// 가짜 Killed(Elite) → 색 뗌 · 처치 시간(TTK) 측정 · RestoreAll 로 원본 스케일 복귀 +// C. 연계 — 킬캠(811d): CombatCameraDirector 를 리플렉션으로 구독시키고 진짜 Killed 를 올려 Elite/일반 대조 · +// 드랍(813f): LootBurst.BurstCount(SO, Elite) 실행 · 임팩트 티어(811gh): bossKillIncludesElite 실값 +// D. GC — Spawned/Killed 각 100회의 GC.GetAllocatedBytesForCurrentThread() 증가분(0 B 목표) +// E. C8 — WLEliteSettings.RuntimeDisabled = true(= 에셋 enabled 0 과 같은 Enabled 게이트) +// → 크기 원본 · 색 0 · MPB 잔류 0 +// F. 원본 — Assets/Script/** · Core · UI 에 813s 문자열 0 · MobHitFlash 합성 배선 확인 +// +// 에디트 모드 주의 +// · [RuntimeInitializeOnLoadMethod] 는 Play 에서만 돈다 → EliteMarker.Probe* 헬퍼로 핸들러를 직접 부른다. +// · Time.unscaledTime 은 한 호출 안에서 멈춰 있다 → TTK 는 ImpactRunner.ForceTick 으로 시뮬 시계를 민다(811gh 방식). +// · 프로브가 만드는 오브젝트는 전부 HideAndDontSave + DestroyImmediate. 어떤 에셋도 쓰지 않는다. +public static class WL813s_Probe +{ + const string kOut = "AgentScripts/staging/WL813s/EDIT_PROBE.txt"; + const string kAppear = "Assets/ResWork/Table/Export/MonsterAppear.json"; + const string kList = "Assets/ResWork/Table/Export/MonsterList.json"; + const string kMap = "Assets/Res_Addr/Map/WL_Nature.prefab"; + const string kFlash = "Assets/WL/Combat/Reaction/MobHitFlash.cs"; + const float kDps = 15f; // Q3 실측(보스 9000 → 6247 / 3분) · 813u 발주서 근거 + + static readonly int[] kEliteSpawners = new int[] { 813021, 813022, 813023, 813024 }; + static readonly int[] kZoneSpawners = new int[] { 813001, 813002, 813003, 813004 }; + + static System.Collections.Generic.List s_log = new System.Collections.Generic.List(); + static bool s_hooked; + static void OnLog(string cond, string stack, UnityEngine.LogType t) + { + if (t == UnityEngine.LogType.Error || t == UnityEngine.LogType.Exception || t == UnityEngine.LogType.Assert) + s_log.Add(t + " | " + cond); + } + static void Hook() { if (!s_hooked) { UnityEngine.Application.logMessageReceived += OnLog; s_hooked = true; } } + static void Unhook() { if (s_hooked) { UnityEngine.Application.logMessageReceived -= OnLog; s_hooked = false; } } + + static UnityEngine.GameObject s_root, s_eliteGo, s_normalGo; + static MobActor s_elite, s_normal; + static float s_eliteBaseScale = -1f; + + public static string Edit() + { + var sb = new System.Text.StringBuilder(); + sb.Append("# WL-813s 프로브 (에디트 모드 · Play 0 · 로그인 0)\n"); + sb.Append("unity=").Append(UnityEngine.Application.unityVersion) + .Append(" isPlaying=").Append(UnityEngine.Application.isPlaying) + .Append(" utc=").Append(System.DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")).Append("\n\n"); + + Hook(); s_log.Clear(); + try + { + Section0(sb); + SectionA(sb); + BuildFakes(sb); + SectionB(sb); + SectionC(sb); + SectionD(sb); + SectionE(sb); + SectionF(sb); + } + catch (System.Exception ex) { sb.Append("\n🔴 예외: ").Append(ex.ToString()).Append("\n"); } + finally { Cleanup(sb); Unhook(); } + + sb.Append("\n## 프로브 중 Error/Exception: ").Append(s_log.Count).Append("\n"); + for (int i = 0; i < s_log.Count && i < 30; i++) sb.Append(" ").Append(s_log[i]).Append("\n"); + + var dir = System.IO.Path.GetDirectoryName(kOut); + if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir); + System.IO.File.WriteAllText(kOut, sb.ToString(), new System.Text.UTF8Encoding(false)); + return sb.ToString(); + } + + // ═══════════════════════════════════════════════ 0. 환경 · SO 실값 + static void Section0(System.Text.StringBuilder sb) + { + sb.Append("## 0. SO 실값 (전부 에셋에서 읽은 값 · 코드 상수 0)\n"); + var el = WL.Combat.Reaction.WLEliteSettings.Instance; + sb.Append("WLEliteSettings: ").Append(el == null ? "🔴 에셋 없음" : "로드 O").Append("\n"); + if (el != null) + sb.Append(" enabled=").Append(el.enabled) + .Append(" scaleEnabled=").Append(el.scaleEnabled) + .Append(" scaleMultiplier=").Append(el.scaleMultiplier.ToString("F2")) + .Append(" scaleMaxAbsolute=").Append(el.scaleMaxAbsolute.ToString("F1")) + .Append(" tintEnabled=").Append(el.tintEnabled) + .Append("\n tintAlbedo=").Append(el.tintAlbedo.ToString("F2")) + .Append(" tintEmission=").Append(el.tintEmission.ToString("F2")) + .Append(" 목표 처치 ").Append(el.killTimeTargetMin.ToString("F0")).Append("~").Append(el.killTimeTargetMax.ToString("F0")).Append(" s\n"); + + var loot = WL.Combat.Loot.WLLootSettings.Instance; + sb.Append("WLLootSettings: ").Append(loot == null ? "🔴 없음" : "burstEnabled=" + loot.burstEnabled + + " elite=" + loot.eliteBurstMin + "~" + loot.eliteBurstMax + + " normal=" + loot.normalBurstCount + " boss=" + loot.bossBurstMin + "~" + loot.bossBurstMax + + " burstRollsBag=" + loot.burstRollsBag + " burstGoldShare=" + loot.burstGoldShare.ToString("F2")).Append("\n"); + + var cam = WL.CombatCamera.WLCombatCameraSettings.Instance; + sb.Append("WLCombatCameraSettings: ").Append(cam == null ? "🔴 없음" : "killCamEnabled=" + cam.killCamEnabled + + " onElite=" + cam.killCamOnElite + " onBoss=" + cam.killCamOnBoss + " onNormal=" + cam.killCamOnNormal + + " directHitOnly=" + cam.killCamDirectHitOnly + " maxPerRun=" + cam.killCamMaxPerRun).Append("\n"); + + var tier = WL.Combat.Reaction.WLImpactTierSettings.Instance; + sb.Append("WLImpactTierSettings: ").Append(tier == null ? "🔴 없음" : "tierEnabled=" + tier.tierEnabled + + " bossKillIncludesElite=" + tier.bossKillIncludesElite).Append("\n"); + + var blink = WL.Combat.Reaction.WLHitBlinkSettings.Instance; + sb.Append("WLHitBlinkSettings: ").Append(blink == null ? "🔴 없음" + : "colorProperties=[" + string.Join(",", blink.colorProperties) + "] emissionProperties=[" + + string.Join(",", blink.emissionProperties) + "] dissolveElite hdr=" + blink.dissolveEdgeHdrElite).Append("\n"); + sb.Append("코어 CombatEvents.Enabled=").Append(WL.Combat.Core.CombatEvents.Enabled).Append("\n\n"); + } + + // ═══════════════════════════════════════════════ A. 데이터 + static void SectionA(System.Text.StringBuilder sb) + { + sb.Append("## A. 데이터 — MonsterAppear 새 행 · MonsterList 대조 · 자산 실존 · 스포너 연결\n"); + string appear = System.IO.File.ReadAllText(kAppear); + string list = System.IO.File.ReadAllText(kList); + + sb.Append("| 스포너 | Lv | ATK | HP(행) | 몹ID | e_MonsterType | f_BaseHPRate | 실 HP | DPS15 처치 s | f_DefaultScale | ×1.3 | 리젠 s | 동시 | 몹 프리팹 | 투사체 |\n"); + sb.Append("|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|\n"); + int ok = 0; + var el = WL.Combat.Reaction.WLEliteSettings.Instance; + float mul = el != null ? el.scaleMultiplier : 1.3f; + for (int i = 0; i < kEliteSpawners.Length; i++) + { + string row = Row(appear, "n_SpawnerID", kEliteSpawners[i].ToString()); + if (row == null) { sb.Append("| ").Append(kEliteSpawners[i]).Append(" | 🔴 행 없음 |\n"); continue; } + string mobId = F(row, "s_AppearMonster"); + string hp = F(row, "n_MonsterHP"); + string mrow = Row(list, "n_MonsterID", mobId); + string type = mrow != null ? F(mrow, "e_MonsterType") : "?"; + float hpRate = mrow != null ? Num(F(mrow, "f_BaseHPRate")) : 0f; + float scale = mrow != null ? Num(F(mrow, "f_DefaultScale")) : 0f; + string prefab = mrow != null ? F(mrow, "s_MonsterPrefab") : ""; + string proj = mrow != null ? F(mrow, "s_Porjectile1") : ""; + float realHp = hpRate * Num(hp); + bool mobOk = Exists("Assets/Res_Addr/Mobs/" + prefab + ".prefab"); + bool projOk = Exists("Assets/Res_Addr/Projectile/" + proj + ".prefab"); + if (type == "Elite" && mobOk && projOk) ok++; + sb.Append("| ").Append(kEliteSpawners[i]).Append(" | ").Append(F(row, "n_AppearMonsterLv")) + .Append(" | ").Append(F(row, "n_MonsterATK")).Append(" | ").Append(hp) + .Append(" | ").Append(mobId).Append(" | ").Append(type) + .Append(" | ").Append(hpRate.ToString("F0")).Append(" | ").Append(realHp.ToString("F0")) + .Append(" | ").Append((realHp / kDps).ToString("F1")) + .Append(" | ").Append(scale.ToString("F1")).Append(" | ").Append((scale * mul).ToString("F2")) + .Append(" | ").Append(F(row, "f_SpawnerDelay")).Append(" | ").Append(F(row, "n_MaxMonsterCount")) + .Append(" | ").Append(prefab).Append(mobOk ? " O" : " 🔴").Append(" | ").Append(proj).Append(projOk ? " O" : " 🔴") + .Append(" |\n"); + } + sb.Append("새 행 정상 = ").Append(ok).Append(" / ").Append(kEliteSpawners.Length).Append("\n"); + + // 기존 존 행 무변경 확인(813u 와의 충돌 방지 규칙) + sb.Append("기존 존 행(813001~813005 · 813010) 값 = "); + for (int i = 0; i < kZoneSpawners.Length; i++) + { + string r = Row(appear, "n_SpawnerID", kZoneSpawners[i].ToString()); + sb.Append(kZoneSpawners[i]).Append(":HP").Append(F(r, "n_MonsterHP")).Append("/몹").Append(F(r, "s_AppearMonster")).Append(" "); + } + sb.Append("\n"); + + // WL_Nature 스포너 전수 + var map = UnityEditor.AssetDatabase.LoadAssetAtPath(kMap); + if (map == null) sb.Append("🔴 ").Append(kMap).Append(" 로드 실패\n"); + else + { + var mgrs = map.GetComponentsInChildren(true); + int nullText = 0, eliteNodes = 0; + sb.Append("WL_Nature 스포너 ").Append(mgrs.Length).Append("개 — "); + for (int i = 0; i < mgrs.Length; i++) + { + if (mgrs[i].text_lv == null) nullText++; + for (int j = 0; j < kEliteSpawners.Length; j++) if (mgrs[i].SpawnerID == kEliteSpawners[j]) eliteNodes++; + } + sb.Append("엘리트 노드 ").Append(eliteNodes).Append("/4 · text_lv null ").Append(nullText).Append("\n"); + for (int i = 0; i < mgrs.Length; i++) + { + bool isElite = false; + for (int j = 0; j < kEliteSpawners.Length; j++) if (mgrs[i].SpawnerID == kEliteSpawners[j]) isElite = true; + if (!isElite) continue; + var t = mgrs[i].transform; + var rend = mgrs[i].GetComponentInChildren(true); + sb.Append(" ").Append(Path(t)).Append(" id=").Append(mgrs[i].SpawnerID) + .Append(" pos=").Append(t.position.ToString("F1")).Append(" range=").Append(mgrs[i].MobGenRange.ToString("F0")) + .Append(" lv라벨렌더러=").Append(rend == null ? "없음" : (rend.enabled ? "켬" : "끔")).Append("\n"); + } + // 같은 좌표의 존 스포너와 대조 + for (int j = 0; j < kZoneSpawners.Length; j++) + { + UnityEngine.Vector3 zp = UnityEngine.Vector3.zero, ep = UnityEngine.Vector3.zero; + bool hz = false, he = false; + for (int i = 0; i < mgrs.Length; i++) + { + if (mgrs[i].SpawnerID == kZoneSpawners[j]) { zp = mgrs[i].transform.position; hz = true; } + if (mgrs[i].SpawnerID == kEliteSpawners[j]) { ep = mgrs[i].transform.position; he = true; } + } + if (hz && he) + sb.Append(" 존 ").Append(kZoneSpawners[j]).Append(" ↔ 엘리트 ").Append(kEliteSpawners[j]) + .Append(" 거리 ").Append(UnityEngine.Vector3.Distance(zp, ep).ToString("F2")).Append(" m\n"); + } + } + sb.Append("\n"); + } + + // ═══════════════════════════════════════════════ 준비 + static void BuildFakes(System.Text.StringBuilder sb) + { + sb.Append("## 준비: 진짜 엘리트 프리팹으로 가짜 액터\n"); + s_root = new UnityEngine.GameObject("[813s] root"); + s_root.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + s_root.SetActive(false); + + string appear = System.IO.File.ReadAllText(kAppear); + string list = System.IO.File.ReadAllText(kList); + string mobId = F(Row(appear, "n_SpawnerID", "813021"), "s_AppearMonster"); + string mrow = Row(list, "n_MonsterID", mobId); + string prefabName = mrow != null ? F(mrow, "s_MonsterPrefab") : "Elite/Aspethis_D"; + float defScale = mrow != null ? Num(F(mrow, "f_DefaultScale")) : 1f; + + var prefab = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Res_Addr/Mobs/" + prefabName + ".prefab"); + if (prefab == null) { sb.Append("🔴 엘리트 프리팹 로드 실패 ").Append(prefabName).Append("\n\n"); return; } + + s_eliteGo = UnityEngine.Object.Instantiate(prefab, s_root.transform); + s_eliteGo.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + s_eliteGo.name = "[813s] elite " + prefabName; + s_elite = s_eliteGo.GetComponent(); + if (s_elite == null) s_elite = s_eliteGo.AddComponent(); + s_elite.m_Role = eRole.Mob; + s_elite.m_SubRole = eSubRol.Elite; // 원본 MobActor.Set(:82) 이 e_MonsterType 으로 넣는 값 + s_elite.transform.localScale = defScale * UnityEngine.Vector3.one; // 원본 MobActor.Set(:87) 과 같은 대입 + s_eliteBaseScale = defScale; + + var normalPrefab = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Res_Addr/Mobs/Mob/Batty_A.prefab"); + if (normalPrefab != null) + { + s_normalGo = UnityEngine.Object.Instantiate(normalPrefab, s_root.transform); + s_normalGo.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + s_normalGo.name = "[813s] normal Batty_A"; + s_normal = s_normalGo.GetComponent(); + if (s_normal != null) { s_normal.m_Role = eRole.Mob; s_normal.m_SubRole = eSubRol.None; } + } + + var rends = s_eliteGo.GetComponentsInChildren(true); + sb.Append("엘리트 = ").Append(prefabName).Append(" · Renderer ").Append(rends.Length) + .Append(" · 기본 스케일 ").Append(defScale.ToString("F2")).Append(" · IsSubRole(Elite)=").Append(s_elite.IsSubRole(eSubRol.Elite)).Append("\n"); + if (rends.Length > 0 && rends[0].sharedMaterial != null && rends[0].sharedMaterial.shader != null) + { + var sh = rends[0].sharedMaterial.shader; + sb.Append("셰이더[0] = ").Append(sh.name) + .Append(" · _AlbedoColor=").Append(sh.FindPropertyIndex("_AlbedoColor") >= 0) + .Append(" · _EmissionColor=").Append(sh.FindPropertyIndex("_EmissionColor") >= 0) + .Append(" · _RimColor=").Append(sh.FindPropertyIndex("_RimColor") >= 0) + .Append(" (🔴 _RimColor 는 _MK_RIM_* shader_feature 게이팅이라 MPB 로 못 켠다 → 쓰지 않는다)\n"); + } + sb.Append("\n"); + } + + // ═══════════════════════════════════════════════ B. 마커 + static void SectionB(System.Text.StringBuilder sb) + { + sb.Append("## B. 마커 — 크기 1.3× · 상시 색 · 멱등 · 처치 시간\n"); + if (s_elite == null) { sb.Append("🔴 엘리트 액터 없음 — 건너뜀\n\n"); return; } + WL.Combat.Reaction.WLEliteSettings.RuntimeDisabled = false; + WL.Combat.Reaction.EliteMarker.ClearAll(); + WL.Combat.Reaction.EliteMarker.ResetDiagnostics(); + WL.Combat.Reaction.MobHitFlash.ResetDiagnostics(); + WL.Combat.Reaction.ImpactRunner.ResetForceClock(); + + var el = WL.Combat.Reaction.WLEliteSettings.Instance; + float before = s_elite.transform.localScale.x; + + WL.Combat.Reaction.EliteMarker.ProbeSpawned(s_elite); + float after1 = s_elite.transform.localScale.x; + bool tinted1 = WL.Combat.Reaction.MobHitFlash.HasEliteTint(s_elite); + bool block1 = WL.Combat.Reaction.MobHitFlash.HasAnyBlock(s_elite); + + WL.Combat.Reaction.EliteMarker.ProbeSpawned(s_elite); // 멱등 확인(풀 재사용 재등장) + WL.Combat.Reaction.EliteMarker.ProbeSpawned(s_elite); + float after3 = s_elite.transform.localScale.x; + + sb.Append("B-1 크기: 기본 ").Append(before.ToString("F3")) + .Append(" → 1회 ").Append(after1.ToString("F3")) + .Append(" (기대 ").Append((before * (el != null ? el.scaleMultiplier : 1.3f)).ToString("F3")).Append(")") + .Append(" → 3회 ").Append(after3.ToString("F3")) + .Append(" · 멱등 ").Append(UnityEngine.Mathf.Abs(after1 - after3) < 0.0005f ? "PASS" : "🔴 FAIL") + .Append(" · EliteMarker.BaseScaleOf=").Append(WL.Combat.Reaction.EliteMarker.BaseScaleOf(s_elite).ToString("F3")).Append("\n"); + sb.Append("B-2 상시 색: HasEliteTint=").Append(tinted1) + .Append(" · MPB 부착=").Append(block1) + .Append(" · TintApplied=").Append(WL.Combat.Reaction.EliteMarker.TintApplied) + .Append(" TintSkipped=").Append(WL.Combat.Reaction.EliteMarker.TintSkipped) + .Append(" · MobHitFlash.StatesCreated=").Append(WL.Combat.Reaction.MobHitFlash.StatesCreated).Append("\n"); + + // 일반 몹은 마커 대상이 아니다 + if (s_normal != null) + { + float nb = s_normal.transform.localScale.x; + WL.Combat.Reaction.EliteMarker.ProbeSpawned(s_normal); + sb.Append("B-3 일반 몹(Batty_A): 스케일 ").Append(nb.ToString("F3")).Append(" → ").Append(s_normal.transform.localScale.x.ToString("F3")) + .Append(" · 색=").Append(WL.Combat.Reaction.MobHitFlash.HasEliteTint(s_normal)) + .Append(" · SkippedNotElite=").Append(WL.Combat.Reaction.EliteMarker.SkippedNotElite) + .Append(UnityEngine.Mathf.Abs(nb - s_normal.transform.localScale.x) < 0.0005f ? " → PASS" : " → 🔴 FAIL").Append("\n"); + } + + // 처치 시간 — 시뮬 시계를 10 s 민다(811gh ImpactRunner.ForceTick) + for (int i = 0; i < 20; i++) WL.Combat.Reaction.ImpactRunner.ForceTick(0.5f); + WL.Combat.Reaction.EliteMarker.ProbeKilled(s_elite, eSubRol.Elite); + sb.Append("B-4 처치: TTK=").Append(WL.Combat.Reaction.EliteMarker.LastKillTime.ToString("F2")).Append(" s (시뮬 10.00 s 주입)") + .Append(" · 색 뗌=").Append(!WL.Combat.Reaction.MobHitFlash.HasEliteTint(s_elite)) + .Append(" · 크기 유지=").Append(s_elite.transform.localScale.x.ToString("F3")) + .Append(" · KillCount=").Append(WL.Combat.Reaction.EliteMarker.KillCount).Append("\n"); + WL.Combat.Reaction.ImpactRunner.ResetForceClock(); + + WL.Combat.Reaction.EliteMarker.RestoreAll(); + sb.Append("B-5 RestoreAll: 스케일 ").Append(s_elite.transform.localScale.x.ToString("F3")) + .Append(" (기대 ").Append(s_eliteBaseScale.ToString("F3")).Append(")") + .Append(" · MPB 잔류=").Append(WL.Combat.Reaction.MobHitFlash.HasAnyBlock(s_elite)) + .Append(UnityEngine.Mathf.Abs(s_elite.transform.localScale.x - s_eliteBaseScale) < 0.0005f ? " → PASS" : " → 🔴 FAIL").Append("\n\n"); + } + + // ═══════════════════════════════════════════════ C. 연계(킬캠 · 드랍 · 티어) + static void SectionC(System.Text.StringBuilder sb) + { + sb.Append("## C. 연계 — 킬캠(811d) · 드랍(813f) · 임팩트 티어(811gh)\n"); + + // C-1 드랍 버스트 수 — 실제 함수 실행 + var loot = WL.Combat.Loot.WLLootSettings.Instance; + if (loot == null) sb.Append("C-1 🔴 WLLootSettings 없음\n"); + else + { + int min = int.MaxValue, max = int.MinValue, zero = 0; + for (int i = 0; i < 200; i++) + { + int c = WL.Combat.Loot.LootBurst.BurstCount(loot, eSubRol.Elite); + if (c < min) min = c; if (c > max) max = c; if (c <= 0) zero++; + } + int nrm = WL.Combat.Loot.LootBurst.BurstCount(loot, eSubRol.None); + int bos = WL.Combat.Loot.LootBurst.BurstCount(loot, eSubRol.Boss); + sb.Append("C-1 LootBurst.BurstCount(Elite) 200회 → ").Append(min).Append("~").Append(max) + .Append(" · 0건 ").Append(zero).Append("회 (0 이면 「드랍 100 %」 성립)") + .Append(" · 일반=").Append(nrm).Append(" 보스=").Append(bos).Append("\n"); + sb.Append(" 버스트 1건은 백(").Append(loot.burstRollsBag ? "8130001 추첨" : "추첨 안 함") + .Append(") → 빈손이면 골드(비중 ").Append(loot.burstGoldShare.ToString("F2")).Append(")로 대체 = 무조건 무언가 떨어진다\n"); + } + + // C-2 임팩트 티어 — bossKillIncludesElite 실값(소스 ImpactTier.cs:130 의 유일한 분기) + var tier = WL.Combat.Reaction.WLImpactTierSettings.Instance; + sb.Append("C-2 ImpactTier.bossKillIncludesElite = ").Append(tier == null ? "?" : tier.bossKillIncludesElite.ToString()) + .Append(" (이 값이 1 이면 Elite 처치가 BossKill 티어 = 히트스톱 ") + .Append(tier != null && tier.hitStopMs != null && tier.hitStopMs.Length > 3 ? tier.hitStopMs[3].ToString("F0") : "?") + .Append(" ms · 셰이크 배수 ") + .Append(tier != null && tier.shakeMultiplier != null && tier.shakeMultiplier.Length > 3 ? tier.shakeMultiplier[3].ToString("F2") : "?") + .Append(") · 이번 작업에서 값 변경 없음(이미 1)\n"); + + // C-3 킬캠 — 리플렉션으로 구독시키고 진짜 Killed 를 올린다 + float ts0 = UnityEngine.Time.timeScale; + var camType = typeof(WL.CombatCamera.CombatCameraDirector); + var reg = camType.GetMethod("Register", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); + if (reg == null || s_elite == null) sb.Append("C-3 🔴 Register/엘리트 없음 — 건너뜀\n"); + else + { + WL.Combat.Core.CombatEvents.Killed.Clear(); + WL.Combat.Core.CombatEvents.Spawned.Clear(); + WL.Combat.Core.CombatEvents.ComboStage.Clear(); + reg.Invoke(null, null); + WL.CombatCamera.CombatCameraDirector.ResetDiagnostics(); + WL.CombatCamera.CombatCameraDirector.ResetRun(); + WL.CombatCamera.CombatCameraDirector.ResetCooldown(); + + WL.Combat.Core.CombatEvents.RaiseKilled(s_elite); + int eliteCam = WL.CombatCamera.CombatCameraDirector.KillCamCount; + int eliteRole = WL.CombatCamera.CombatCameraDirector.KillCamSkippedRole; + string eliteInfo = WL.CombatCamera.CombatCameraDirector.LastInfo; + var slow = WL.CombatCamera.CombatCameraDirector.LastSlowMoResult; + + WL.CombatCamera.CombatCameraDirector.ResetCooldown(); + int camBeforeNormal = WL.CombatCamera.CombatCameraDirector.KillCamCount; + if (s_normal != null) WL.Combat.Core.CombatEvents.RaiseKilled(s_normal); + int normalCam = WL.CombatCamera.CombatCameraDirector.KillCamCount - camBeforeNormal; + int normalRole = WL.CombatCamera.CombatCameraDirector.KillCamSkippedRole - eliteRole; + + sb.Append("C-3 킬캠: Killed(Elite) → KillCamCount ").Append(eliteCam) + .Append(" · 역할 스킵 ").Append(eliteRole) + .Append(" · 슬로모 ").Append(slow).Append(" · info=\"").Append(eliteInfo).Append("\"\n"); + sb.Append(" 대조 Killed(일반 몹) → KillCamCount +").Append(normalCam) + .Append(" · 역할 스킵 +").Append(normalRole).Append(" (killCamOnNormal=0 이라 스킵이 정상)\n"); + sb.Append(" 판정: 엘리트 킬캠 조건 ").Append(eliteCam >= 1 ? "열림 PASS" : "🔴 닫힘").Append("\n"); + + WL.CombatCamera.CombatCameraDirector.ReleaseAll(); + WL.Combat.Core.TimeScaleArbiter.ReleaseAll(); + WL.Combat.Core.CombatEvents.Killed.Clear(); + WL.Combat.Core.CombatEvents.Spawned.Clear(); + WL.Combat.Core.CombatEvents.ComboStage.Clear(); + } + UnityEngine.Time.timeScale = ts0; + sb.Append(" Time.timeScale ").Append(ts0.ToString("F2")).Append(" → ").Append(UnityEngine.Time.timeScale.ToString("F2")).Append(" (복원)\n\n"); + } + + // ═══════════════════════════════════════════════ D. GC + static void SectionD(System.Text.StringBuilder sb) + { + sb.Append("## D. GC (0 B 목표)\n"); + if (s_elite == null) { sb.Append("🔴 건너뜀\n\n"); return; } + WL.Combat.Reaction.WLEliteSettings.RuntimeDisabled = false; + // 상태·MPB 를 미리 만들어 두고(1회 할당은 풀 크기 상한) 반복분만 잰다 + WL.Combat.Reaction.EliteMarker.ProbeSpawned(s_elite); + WL.Combat.Reaction.EliteMarker.ProbeKilled(s_elite, eSubRol.Elite); + + long a0 = System.GC.GetAllocatedBytesForCurrentThread(); + for (int i = 0; i < 100; i++) WL.Combat.Reaction.EliteMarker.ProbeSpawned(s_elite); + long a1 = System.GC.GetAllocatedBytesForCurrentThread(); + for (int i = 0; i < 100; i++) { WL.Combat.Reaction.EliteMarker.ProbeSpawned(s_elite); WL.Combat.Reaction.EliteMarker.ProbeKilled(s_elite, eSubRol.Elite); } + long a2 = System.GC.GetAllocatedBytesForCurrentThread(); + sb.Append("Spawned ×100 = ").Append(a1 - a0).Append(" B · Spawned+Killed ×100 = ").Append(a2 - a1).Append(" B\n"); + sb.Append("(killTimeLogEnabled=").Append(WL.Combat.Reaction.WLEliteSettings.Instance != null && WL.Combat.Reaction.WLEliteSettings.Instance.killTimeLogEnabled) + .Append(" · 켜져 있으면 Debug.Log 문자열이 잡힌다 = 값이 0 이 아니면 그 로그분)\n\n"); + } + + // ═══════════════════════════════════════════════ E. C8 + static void SectionE(System.Text.StringBuilder sb) + { + sb.Append("## E. C8 — WLEliteSettings 를 끄면 원본 동작 100 %\n"); + if (s_elite == null) { sb.Append("🔴 건너뜀\n\n"); return; } + WL.Combat.Reaction.EliteMarker.ClearAll(); + s_elite.transform.localScale = s_eliteBaseScale * UnityEngine.Vector3.one; + WL.Combat.Reaction.EliteMarker.ResetDiagnostics(); + + WL.Combat.Reaction.WLEliteSettings.RuntimeDisabled = true; + sb.Append("Enabled=").Append(WL.Combat.Reaction.WLEliteSettings.Enabled).Append(" (기대 False)\n"); + WL.Combat.Reaction.EliteMarker.ProbeSpawned(s_elite); + bool sizeOk = UnityEngine.Mathf.Abs(s_elite.transform.localScale.x - s_eliteBaseScale) < 0.0005f; + bool tintOff = !WL.Combat.Reaction.MobHitFlash.HasEliteTint(s_elite); + bool blockOff = !WL.Combat.Reaction.MobHitFlash.HasAnyBlock(s_elite); + sb.Append("크기 ").Append(s_elite.transform.localScale.x.ToString("F3")).Append(" (원본 ").Append(s_eliteBaseScale.ToString("F3")).Append(")") + .Append(" · 색 ").Append(tintOff ? "0" : "🔴 남음").Append(" · MPB ").Append(blockOff ? "0" : "🔴 남음") + .Append(" · SkippedDisabled=").Append(WL.Combat.Reaction.EliteMarker.SkippedDisabled) + .Append(sizeOk && tintOff && blockOff ? " → PASS" : " → 🔴 FAIL").Append("\n"); + WL.Combat.Reaction.WLEliteSettings.RuntimeDisabled = false; + sb.Append("\n"); + } + + // ═══════════════════════════════════════════════ F. 원본 · 배선 + static void SectionF(System.Text.StringBuilder sb) + { + sb.Append("## F. 원본 무수정 · 배선\n"); + string[] originals = new string[] { + "Assets/Script/Character/Actor.cs", + "Assets/Script/Character/Mob/MobActor.cs", + "Assets/Script/Mgr/MobControlMgr.cs", + "Assets/WL/Combat/Core/CombatEvents.cs", + "Assets/WL/Combat/Core/WLCombatCoreSettings.cs", + }; + for (int i = 0; i < originals.Length; i++) + { + if (!System.IO.File.Exists(originals[i])) { sb.Append(" ").Append(originals[i]).Append(" 🔴 없음\n"); continue; } + string t = System.IO.File.ReadAllText(originals[i]); + sb.Append(" ").Append(originals[i]).Append(" — \"EliteMarker\" ").Append(t.Contains("EliteMarker") ? "🔴 있음" : "0") + .Append(" · \"813s\" ").Append(t.Contains("813s") ? "🔴 있음" : "0").Append("\n"); + } + string flash = System.IO.File.Exists(kFlash) ? System.IO.File.ReadAllText(kFlash) : ""; + sb.Append(" MobHitFlash 합성 배선 — SetEliteTint ").Append(flash.Contains("SetEliteTint") ? "O" : "🔴") + .Append(" · Apply 안 s.elite ").Append(flash.Contains("if (s.elite)") ? "O" : "🔴") + .Append(" · RestoreAll 포함 ").Append(flash.Contains("!s.tint && !s.elite") ? "O" : "🔴").Append("\n\n"); + } + + // ═══════════════════════════════════════════════ 정리 · 헬퍼 + static void Cleanup(System.Text.StringBuilder sb) + { + WL.Combat.Reaction.WLEliteSettings.RuntimeDisabled = false; + try { WL.Combat.Reaction.EliteMarker.ClearAll(); } catch (System.Exception) { } + try { WL.Combat.Reaction.MobHitFlash.ClearAll(); } catch (System.Exception) { } + try { WL.Combat.Reaction.ImpactRunner.ResetForceClock(); } catch (System.Exception) { } + if (s_root != null) { UnityEngine.Object.DestroyImmediate(s_root); s_root = null; } + s_eliteGo = null; s_normalGo = null; s_elite = null; s_normal = null; + sb.Append("\n## 정리: 임시 오브젝트 파괴 · 상태 비움 완료\n"); + } + + static bool Exists(string path) { return UnityEditor.AssetDatabase.LoadAssetAtPath(path) != null; } + + static string Path(UnityEngine.Transform t) + { + string p = t.name; + while (t.parent != null) { t = t.parent; p = t.name + "/" + p; } + return p; + } + + /// 단일 라인 JSON 에서 key == value 인 객체 하나를 문자열로 잘라 온다. + static string Row(string json, string key, string value) + { + if (json == null || value == null) return null; + string needle = "\"" + key + "\": \"" + value + "\""; + int i = json.IndexOf(needle, System.StringComparison.Ordinal); + if (i < 0) return null; + int s = json.LastIndexOf('{', i); + int e = json.IndexOf('}', i); + return s < 0 || e < 0 ? null : json.Substring(s, e - s + 1); + } + + static string F(string row, string key) + { + if (row == null) return "?"; + string needle = "\"" + key + "\": \""; + int i = row.IndexOf(needle, System.StringComparison.Ordinal); + if (i < 0) return "?"; + i += needle.Length; + int e = row.IndexOf('"', i); + return e < 0 ? "?" : row.Substring(i, e - i); + } + + static float Num(string s) + { + float v; + return float.TryParse(s, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out v) ? v : 0f; + } +} diff --git a/Assets/ResWork/Table/Export/MonsterAppear.json b/Assets/ResWork/Table/Export/MonsterAppear.json index 4b38af612..0eee394e3 100644 --- a/Assets/ResWork/Table/Export/MonsterAppear.json +++ b/Assets/ResWork/Table/Export/MonsterAppear.json @@ -1 +1 @@ -[{"n_SpawnerID": "1", "n_AppearMonsterLv": "1", "n_MonsterATK": "10", "n_MonsterDEF": "-10", "n_MonsterMDEF": "-10", "n_MonsterHP": "300", "s_AppearMonster": "101|102|103|104", "e_SpawnerType": "Random", "f_SpawnerDelay": "4", "n_MaxMonsterCount": "15", "f_PatrolRange": "10", "n_DropExp": "10", "n_DropGold": "1", "n_DropReward": "9700001"}, {"n_SpawnerID": "2", "n_AppearMonsterLv": "2", "n_MonsterATK": "10", "n_MonsterDEF": "2", "n_MonsterMDEF": "2", "n_MonsterHP": "99999", "s_AppearMonster": "105|106|107", "e_SpawnerType": "Order", "f_SpawnerDelay": "3.8", "n_MaxMonsterCount": "10", "f_PatrolRange": "4", "n_DropExp": "15", "n_DropGold": "2", "n_DropReward": "9700001"}, {"n_SpawnerID": "3", "n_AppearMonsterLv": "3", "n_MonsterATK": "99999", "n_MonsterDEF": "3", "n_MonsterMDEF": "3", "n_MonsterHP": "10000", "s_AppearMonster": "1014|1015", "e_SpawnerType": "Order", "f_SpawnerDelay": "3.6", "n_MaxMonsterCount": "10", "f_PatrolRange": "5", "n_DropExp": "20", "n_DropGold": "3", "n_DropReward": "9700001"}, {"n_SpawnerID": "4", "n_AppearMonsterLv": "4", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "111|112|113", "e_SpawnerType": "PhaseAllKill", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "5", "n_AppearMonsterLv": "5", "n_MonsterATK": "5", "n_MonsterDEF": "1", "n_MonsterMDEF": "1", "n_MonsterHP": "100", "s_AppearMonster": "114|115|116|117", "e_SpawnerType": "Phase", "f_SpawnerDelay": "4", "n_MaxMonsterCount": "10", "f_PatrolRange": "3", "n_DropExp": "10", "n_DropGold": "1", "n_DropReward": "9700001"}, {"n_SpawnerID": "6", "n_AppearMonsterLv": "6", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "118|119|120", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "7", "n_AppearMonsterLv": "7", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "121|122|123", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "8", "n_AppearMonsterLv": "8", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "124|125|126|127|128", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "9", "n_AppearMonsterLv": "9", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "129|130|131|132|133", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "10", "n_AppearMonsterLv": "10", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "134|135|136", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "11", "n_AppearMonsterLv": "11", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "137|138|139|140", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "12", "n_AppearMonsterLv": "12", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "141|142|143|144|145", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "13", "n_AppearMonsterLv": "13", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "70", "s_AppearMonster": "146|147|148|149|150|151|152|153|154", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "14", "n_AppearMonsterLv": "14", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "155|156|157", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "15", "n_AppearMonsterLv": "15", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "158|159|160", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "16", "n_AppearMonsterLv": "16", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "161|162|163|164", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "10", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "17", "n_AppearMonsterLv": "17", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "165|166|167", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "10", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "18", "n_AppearMonsterLv": "18", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "168|169|170|171|172", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "19", "n_AppearMonsterLv": "19", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "173|174|175", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "20", "n_AppearMonsterLv": "20", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "176|177|178|179|180|181", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "21", "n_AppearMonsterLv": "21", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "182|183|184|185|186", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "22", "n_AppearMonsterLv": "22", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "187|188|189|190|191", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "23", "n_AppearMonsterLv": "23", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "192|193|194|195|196|197", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "24", "n_AppearMonsterLv": "24", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "198|199|200|201|202|203", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "25", "n_AppearMonsterLv": "25", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "204|205|206|207|208|209|210", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "26", "n_AppearMonsterLv": "26", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "211|212|213|214|215|216|217|218", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "27", "n_AppearMonsterLv": "27", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "219|220|221|222|223|224|225", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "28", "n_AppearMonsterLv": "28", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "226|227|228|229|230|231|232", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "29", "n_AppearMonsterLv": "29", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "233|234|235|236|237|238|239", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "30", "n_AppearMonsterLv": "30", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "240|241|242|243|244|245|246", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "31", "n_AppearMonsterLv": "31", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "247|248|249|250", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "32", "n_AppearMonsterLv": "32", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "251|252|253|254|255|256|257|258|259", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "33", "n_AppearMonsterLv": "33", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "260|261|262|263|264|265|266", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "34", "n_AppearMonsterLv": "34", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "267|268|269|270|271|272|273", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "35", "n_AppearMonsterLv": "35", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "274|275|276|277|278|279|280|281", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "36", "n_AppearMonsterLv": "36", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "282|283|284|285|286|287|288|289|290", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "37", "n_AppearMonsterLv": "37", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "291|292|293|294|295|296|297|298", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "38", "n_AppearMonsterLv": "38", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "299|300|301|302|303|304", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "39", "n_AppearMonsterLv": "39", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "305|306|307|308|309|310|311", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "40", "n_AppearMonsterLv": "40", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "312|313|314|315|316|317|318|319", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "41", "n_AppearMonsterLv": "41", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "320|321|322|323", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "42", "n_AppearMonsterLv": "42", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "324|325|326|327|328|329|330|331|332", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "40", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "43", "n_AppearMonsterLv": "43", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "333|334|335|336|337|338|339|340|341|342|343|344", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "40", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "44", "n_AppearMonsterLv": "44", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "345|346|347", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "10", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "45", "n_AppearMonsterLv": "45", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "2000", "s_AppearMonster": "348|349|350|351", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "46", "n_AppearMonsterLv": "46", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "3000", "s_AppearMonster": "1031", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "1", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "813001", "n_AppearMonsterLv": "1", "n_MonsterATK": "6", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "190", "s_AppearMonster": "101|102|103|104", "e_SpawnerType": "Random", "f_SpawnerDelay": "1.5", "n_MaxMonsterCount": "12", "f_PatrolRange": "8", "n_DropExp": "10", "n_DropGold": "1", "n_DropReward": "8130001"}, {"n_SpawnerID": "813002", "n_AppearMonsterLv": "2", "n_MonsterATK": "8", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "270", "s_AppearMonster": "168|169|170|171|172", "e_SpawnerType": "Random", "f_SpawnerDelay": "1.2", "n_MaxMonsterCount": "15", "f_PatrolRange": "8", "n_DropExp": "15", "n_DropGold": "2", "n_DropReward": "8130001"}, {"n_SpawnerID": "813003", "n_AppearMonsterLv": "3", "n_MonsterATK": "10", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "350", "s_AppearMonster": "173|174|175|146|147|151", "e_SpawnerType": "Random", "f_SpawnerDelay": "1.2", "n_MaxMonsterCount": "14", "f_PatrolRange": "8", "n_DropExp": "20", "n_DropGold": "3", "n_DropReward": "8130001"}, {"n_SpawnerID": "813004", "n_AppearMonsterLv": "4", "n_MonsterATK": "12", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "430", "s_AppearMonster": "118|119|120", "e_SpawnerType": "PhaseAllKill", "f_SpawnerDelay": "2.0", "n_MaxMonsterCount": "8", "f_PatrolRange": "6", "n_DropExp": "30", "n_DropGold": "4", "n_DropReward": "8130001"}, {"n_SpawnerID": "813005", "n_AppearMonsterLv": "5", "n_MonsterATK": "20", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "1500", "s_AppearMonster": "1014|1015|1016", "e_SpawnerType": "Order", "f_SpawnerDelay": "3.0", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "60", "n_DropGold": "8", "n_DropReward": "8130001"}, {"n_SpawnerID": "813010", "n_AppearMonsterLv": "6", "n_MonsterATK": "2", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "90", "s_AppearMonster": "10006", "e_SpawnerType": "Random", "f_SpawnerDelay": "60", "n_MaxMonsterCount": "1", "f_PatrolRange": "4", "n_DropExp": "500", "n_DropGold": "100", "n_DropReward": "8130001"}] \ No newline at end of file +[{"n_SpawnerID": "1", "n_AppearMonsterLv": "1", "n_MonsterATK": "10", "n_MonsterDEF": "-10", "n_MonsterMDEF": "-10", "n_MonsterHP": "300", "s_AppearMonster": "101|102|103|104", "e_SpawnerType": "Random", "f_SpawnerDelay": "4", "n_MaxMonsterCount": "15", "f_PatrolRange": "10", "n_DropExp": "10", "n_DropGold": "1", "n_DropReward": "9700001"}, {"n_SpawnerID": "2", "n_AppearMonsterLv": "2", "n_MonsterATK": "10", "n_MonsterDEF": "2", "n_MonsterMDEF": "2", "n_MonsterHP": "99999", "s_AppearMonster": "105|106|107", "e_SpawnerType": "Order", "f_SpawnerDelay": "3.8", "n_MaxMonsterCount": "10", "f_PatrolRange": "4", "n_DropExp": "15", "n_DropGold": "2", "n_DropReward": "9700001"}, {"n_SpawnerID": "3", "n_AppearMonsterLv": "3", "n_MonsterATK": "99999", "n_MonsterDEF": "3", "n_MonsterMDEF": "3", "n_MonsterHP": "10000", "s_AppearMonster": "1014|1015", "e_SpawnerType": "Order", "f_SpawnerDelay": "3.6", "n_MaxMonsterCount": "10", "f_PatrolRange": "5", "n_DropExp": "20", "n_DropGold": "3", "n_DropReward": "9700001"}, {"n_SpawnerID": "4", "n_AppearMonsterLv": "4", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "111|112|113", "e_SpawnerType": "PhaseAllKill", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "5", "n_AppearMonsterLv": "5", "n_MonsterATK": "5", "n_MonsterDEF": "1", "n_MonsterMDEF": "1", "n_MonsterHP": "100", "s_AppearMonster": "114|115|116|117", "e_SpawnerType": "Phase", "f_SpawnerDelay": "4", "n_MaxMonsterCount": "10", "f_PatrolRange": "3", "n_DropExp": "10", "n_DropGold": "1", "n_DropReward": "9700001"}, {"n_SpawnerID": "6", "n_AppearMonsterLv": "6", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "118|119|120", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "7", "n_AppearMonsterLv": "7", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "121|122|123", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "8", "n_AppearMonsterLv": "8", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "124|125|126|127|128", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "9", "n_AppearMonsterLv": "9", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "129|130|131|132|133", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "10", "n_AppearMonsterLv": "10", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "134|135|136", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "11", "n_AppearMonsterLv": "11", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "137|138|139|140", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "12", "n_AppearMonsterLv": "12", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "141|142|143|144|145", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "13", "n_AppearMonsterLv": "13", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "70", "s_AppearMonster": "146|147|148|149|150|151|152|153|154", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "14", "n_AppearMonsterLv": "14", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "155|156|157", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "15", "n_AppearMonsterLv": "15", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "158|159|160", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "16", "n_AppearMonsterLv": "16", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "161|162|163|164", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "10", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "17", "n_AppearMonsterLv": "17", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "165|166|167", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "10", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "18", "n_AppearMonsterLv": "18", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "168|169|170|171|172", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "19", "n_AppearMonsterLv": "19", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "173|174|175", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "20", "n_AppearMonsterLv": "20", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "176|177|178|179|180|181", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "21", "n_AppearMonsterLv": "21", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "182|183|184|185|186", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "22", "n_AppearMonsterLv": "22", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "187|188|189|190|191", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "23", "n_AppearMonsterLv": "23", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "192|193|194|195|196|197", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "24", "n_AppearMonsterLv": "24", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "198|199|200|201|202|203", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "20", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "25", "n_AppearMonsterLv": "25", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "204|205|206|207|208|209|210", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "26", "n_AppearMonsterLv": "26", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "211|212|213|214|215|216|217|218", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "27", "n_AppearMonsterLv": "27", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "219|220|221|222|223|224|225", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "28", "n_AppearMonsterLv": "28", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "226|227|228|229|230|231|232", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "29", "n_AppearMonsterLv": "29", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "233|234|235|236|237|238|239", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "30", "n_AppearMonsterLv": "30", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "240|241|242|243|244|245|246", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "31", "n_AppearMonsterLv": "31", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "247|248|249|250", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "32", "n_AppearMonsterLv": "32", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "251|252|253|254|255|256|257|258|259", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "33", "n_AppearMonsterLv": "33", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "260|261|262|263|264|265|266", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "34", "n_AppearMonsterLv": "34", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "267|268|269|270|271|272|273", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "25", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "35", "n_AppearMonsterLv": "35", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "274|275|276|277|278|279|280|281", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "36", "n_AppearMonsterLv": "36", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "282|283|284|285|286|287|288|289|290", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "37", "n_AppearMonsterLv": "37", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "291|292|293|294|295|296|297|298", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "38", "n_AppearMonsterLv": "38", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "299|300|301|302|303|304", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "39", "n_AppearMonsterLv": "39", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "305|306|307|308|309|310|311", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "40", "n_AppearMonsterLv": "40", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "312|313|314|315|316|317|318|319", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "30", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "41", "n_AppearMonsterLv": "41", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "320|321|322|323", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "42", "n_AppearMonsterLv": "42", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "324|325|326|327|328|329|330|331|332", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "40", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "43", "n_AppearMonsterLv": "43", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "333|334|335|336|337|338|339|340|341|342|343|344", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "40", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "44", "n_AppearMonsterLv": "44", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "4", "s_AppearMonster": "345|346|347", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "10", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "45", "n_AppearMonsterLv": "45", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "2000", "s_AppearMonster": "348|349|350|351", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "15", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "46", "n_AppearMonsterLv": "46", "n_MonsterATK": "4", "n_MonsterDEF": "4", "n_MonsterMDEF": "4", "n_MonsterHP": "3000", "s_AppearMonster": "1031", "e_SpawnerType": "Random", "f_SpawnerDelay": "3.4", "n_MaxMonsterCount": "1", "f_PatrolRange": "6", "n_DropExp": "25", "n_DropGold": "4", "n_DropReward": "9700001"}, {"n_SpawnerID": "813001", "n_AppearMonsterLv": "1", "n_MonsterATK": "6", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "190", "s_AppearMonster": "101|102|103|104", "e_SpawnerType": "Random", "f_SpawnerDelay": "1.5", "n_MaxMonsterCount": "12", "f_PatrolRange": "8", "n_DropExp": "10", "n_DropGold": "1", "n_DropReward": "8130001"}, {"n_SpawnerID": "813002", "n_AppearMonsterLv": "2", "n_MonsterATK": "8", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "270", "s_AppearMonster": "168|169|170|171|172", "e_SpawnerType": "Random", "f_SpawnerDelay": "1.2", "n_MaxMonsterCount": "15", "f_PatrolRange": "8", "n_DropExp": "15", "n_DropGold": "2", "n_DropReward": "8130001"}, {"n_SpawnerID": "813003", "n_AppearMonsterLv": "3", "n_MonsterATK": "10", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "350", "s_AppearMonster": "173|174|175|146|147|151", "e_SpawnerType": "Random", "f_SpawnerDelay": "1.2", "n_MaxMonsterCount": "14", "f_PatrolRange": "8", "n_DropExp": "20", "n_DropGold": "3", "n_DropReward": "8130001"}, {"n_SpawnerID": "813004", "n_AppearMonsterLv": "4", "n_MonsterATK": "12", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "430", "s_AppearMonster": "118|119|120", "e_SpawnerType": "PhaseAllKill", "f_SpawnerDelay": "2.0", "n_MaxMonsterCount": "8", "f_PatrolRange": "6", "n_DropExp": "30", "n_DropGold": "4", "n_DropReward": "8130001"}, {"n_SpawnerID": "813005", "n_AppearMonsterLv": "5", "n_MonsterATK": "20", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "1500", "s_AppearMonster": "1014|1015|1016", "e_SpawnerType": "Order", "f_SpawnerDelay": "3.0", "n_MaxMonsterCount": "5", "f_PatrolRange": "6", "n_DropExp": "60", "n_DropGold": "8", "n_DropReward": "8130001"}, {"n_SpawnerID": "813010", "n_AppearMonsterLv": "6", "n_MonsterATK": "2", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "90", "s_AppearMonster": "10006", "e_SpawnerType": "Random", "f_SpawnerDelay": "60", "n_MaxMonsterCount": "1", "f_PatrolRange": "4", "n_DropExp": "500", "n_DropGold": "100", "n_DropReward": "8130001"}, {"n_SpawnerID": "813021", "n_AppearMonsterLv": "1", "n_MonsterATK": "6", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "470", "s_AppearMonster": "1023", "e_SpawnerType": "Random", "f_SpawnerDelay": "25", "n_MaxMonsterCount": "1", "f_PatrolRange": "6", "n_DropExp": "30", "n_DropGold": "4", "n_DropReward": "8130001"}, {"n_SpawnerID": "813022", "n_AppearMonsterLv": "2", "n_MonsterATK": "8", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "540", "s_AppearMonster": "1028", "e_SpawnerType": "Random", "f_SpawnerDelay": "25", "n_MaxMonsterCount": "1", "f_PatrolRange": "6", "n_DropExp": "45", "n_DropGold": "8", "n_DropReward": "8130001"}, {"n_SpawnerID": "813023", "n_AppearMonsterLv": "3", "n_MonsterATK": "10", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "610", "s_AppearMonster": "1009", "e_SpawnerType": "Random", "f_SpawnerDelay": "25", "n_MaxMonsterCount": "1", "f_PatrolRange": "6", "n_DropExp": "60", "n_DropGold": "12", "n_DropReward": "8130001"}, {"n_SpawnerID": "813024", "n_AppearMonsterLv": "4", "n_MonsterATK": "12", "n_MonsterDEF": "0", "n_MonsterMDEF": "0", "n_MonsterHP": "680", "s_AppearMonster": "1024", "e_SpawnerType": "Random", "f_SpawnerDelay": "25", "n_MaxMonsterCount": "1", "f_PatrolRange": "6", "n_DropExp": "90", "n_DropGold": "16", "n_DropReward": "8130001"}] \ No newline at end of file diff --git a/Assets/Res_Addr/Map/WL_Nature.prefab b/Assets/Res_Addr/Map/WL_Nature.prefab index 64b9c5298..ca7629f54 100644 --- a/Assets/Res_Addr/Map/WL_Nature.prefab +++ b/Assets/Res_Addr/Map/WL_Nature.prefab @@ -1874,6 +1874,10 @@ Transform: - {fileID: 9148239127049813559} - {fileID: 4756645399688030805} - {fileID: 2585914379847131988} + - {fileID: 8130210000000000002} + - {fileID: 8130220000000000002} + - {fileID: 8130230000000000002} + - {fileID: 8130240000000000002} m_Father: {fileID: 4502284306717827522} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &2416751648744311364 @@ -68686,3 +68690,923 @@ MonoBehaviour: n_MonsterID: 10006 n_SpawnerId: 813010 RegenTime: 60 +--- !u!1 &8130210000000000001 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8130210000000000002} + - component: {fileID: 8130210000000000003} + m_Layer: 3 + m_Name: e1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &8130210000000000002 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130210000000000001} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: 0.8949344, z: -0, w: -0.44619775} + m_LocalPosition: {x: 115, y: 0.38610268, z: -22} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8130210000000000005} + m_Father: {fileID: 5625234380910883685} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8130210000000000003 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130210000000000001} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 06269e6c1653db34090895cd16244df9, type: 3} + m_Name: + m_EditorClassIdentifier: + SpawnerID: 813021 + MobGenRange: 6 + text_lv: {fileID: 8130210000000000007} +--- !u!1 &8130210000000000004 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8130210000000000005} + - component: {fileID: 8130210000000000006} + - component: {fileID: 8130210000000000007} + m_Layer: 3 + m_Name: lv + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 119 + m_IsActive: 1 +--- !u!224 &8130210000000000005 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130210000000000004} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 3.14} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8130210000000000002} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0.01} + m_SizeDelta: {x: 20, y: 5} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!23 &8130210000000000006 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130210000000000004} + m_Enabled: 0 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &8130210000000000007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130210000000000004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Lv.1 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 4096 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 8130210000000000006} + m_maskType: 0 +--- !u!1 &8130220000000000001 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8130220000000000002} + - component: {fileID: 8130220000000000003} + m_Layer: 3 + m_Name: e2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &8130220000000000002 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130220000000000001} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: 0.8949344, z: -0, w: -0.44619775} + m_LocalPosition: {x: 147, y: 2.5930157, z: 30} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8130220000000000005} + m_Father: {fileID: 5625234380910883685} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8130220000000000003 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130220000000000001} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 06269e6c1653db34090895cd16244df9, type: 3} + m_Name: + m_EditorClassIdentifier: + SpawnerID: 813022 + MobGenRange: 6 + text_lv: {fileID: 8130220000000000007} +--- !u!1 &8130220000000000004 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8130220000000000005} + - component: {fileID: 8130220000000000006} + - component: {fileID: 8130220000000000007} + m_Layer: 3 + m_Name: lv + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 119 + m_IsActive: 1 +--- !u!224 &8130220000000000005 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130220000000000004} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 3.14} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8130220000000000002} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0.01} + m_SizeDelta: {x: 20, y: 5} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!23 &8130220000000000006 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130220000000000004} + m_Enabled: 0 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &8130220000000000007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130220000000000004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Lv.1 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 4096 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 8130220000000000006} + m_maskType: 0 +--- !u!1 &8130230000000000001 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8130230000000000002} + - component: {fileID: 8130230000000000003} + m_Layer: 3 + m_Name: e3 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &8130230000000000002 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130230000000000001} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: 0.8949344, z: -0, w: -0.44619775} + m_LocalPosition: {x: 71, y: -0.2855866, z: 18} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8130230000000000005} + m_Father: {fileID: 5625234380910883685} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8130230000000000003 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130230000000000001} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 06269e6c1653db34090895cd16244df9, type: 3} + m_Name: + m_EditorClassIdentifier: + SpawnerID: 813023 + MobGenRange: 6 + text_lv: {fileID: 8130230000000000007} +--- !u!1 &8130230000000000004 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8130230000000000005} + - component: {fileID: 8130230000000000006} + - component: {fileID: 8130230000000000007} + m_Layer: 3 + m_Name: lv + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 119 + m_IsActive: 1 +--- !u!224 &8130230000000000005 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130230000000000004} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 3.14} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8130230000000000002} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0.01} + m_SizeDelta: {x: 20, y: 5} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!23 &8130230000000000006 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130230000000000004} + m_Enabled: 0 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &8130230000000000007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130230000000000004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Lv.1 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 4096 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 8130230000000000006} + m_maskType: 0 +--- !u!1 &8130240000000000001 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8130240000000000002} + - component: {fileID: 8130240000000000003} + m_Layer: 3 + m_Name: e4 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &8130240000000000002 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130240000000000001} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: 0.8949344, z: -0, w: -0.44619775} + m_LocalPosition: {x: 159, y: 0.8762447, z: -22} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8130240000000000005} + m_Father: {fileID: 5625234380910883685} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8130240000000000003 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130240000000000001} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 06269e6c1653db34090895cd16244df9, type: 3} + m_Name: + m_EditorClassIdentifier: + SpawnerID: 813024 + MobGenRange: 6 + text_lv: {fileID: 8130240000000000007} +--- !u!1 &8130240000000000004 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8130240000000000005} + - component: {fileID: 8130240000000000006} + - component: {fileID: 8130240000000000007} + m_Layer: 3 + m_Name: lv + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 119 + m_IsActive: 1 +--- !u!224 &8130240000000000005 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130240000000000004} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 3.14} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8130240000000000002} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0.01} + m_SizeDelta: {x: 20, y: 5} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!23 &8130240000000000006 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130240000000000004} + m_Enabled: 0 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &8130240000000000007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8130240000000000004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Lv.1 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 4096 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 8130240000000000006} + m_maskType: 0 diff --git a/Assets/WL/Combat/Reaction/EliteMarker.cs b/Assets/WL/Combat/Reaction/EliteMarker.cs new file mode 100644 index 000000000..616612a31 --- /dev/null +++ b/Assets/WL/Combat/Reaction/EliteMarker.cs @@ -0,0 +1,275 @@ +// ───────────────────────────────────────────────────────────────────────────── +// EliteMarker.cs — 엘리트 몹 마커: 크기 1.3× + 상시 색 + 처치 시간(TTK) 측정 +// +// PD 지시 #813 · 발주서 WL-813s §1-2 · 기준서 v1 §D-2 813s 행 · §B 요소 1 (2026-09-09) +// +// ■ 무엇을 하나 (원본 훅 0 · Assets/Script/** 무수정 · 정적 · 러너 0) +// Spawned(isElite) → ⓐ localScale = 테이블 기본 스케일 × WLEliteSettings.scaleMultiplier(1.3) +// — **멱등**이다. 풀 재사용 몹이 다시 등장해도 기준 스케일에서 다시 곱하므로 1.3^n 이 되지 않는다. +// ⓑ MobHitFlash 에 「상시 엘리트 색」을 등록한다(MPB · 아래 참고). +// ⓒ 등장 시각을 적어 둔다(TTK). +// Killed(Elite) → ⓐ 등장 → 처치 시간(TTK)을 재서 기준서 8~12 s 대조 로그를 남긴다(링버퍼 · GC 0) +// ⓑ 상시 색을 뗀다(디졸브·풀 잔류 0). **크기는 그대로 둔다** — 사망 순간에 되돌리면 +// 죽는 프레임에 몸집이 튄다. 되돌림은 RestoreAll/ClearAll(씬 전환·C8)에서만. +// +// ■ 왜 색을 MobHitFlash 에 넘기는가 (렌더러 MPB 의 소유자는 하나여야 한다) +// MobHitFlash.Apply 는 렌더러별 MPB 를 **매번 Clear 후 재구성**하고, 오버라이드가 없으면 SetPropertyBlock(null) +// 로 블록을 떼어 SRP Batcher 로 되돌린다. 여기서 별도의 MPB 를 쓰면 첫 피격 점멸에서 통째로 지워진다. +// → 상시 색을 MobHitFlash 의 상태(State.elite)로 넣어 **같은 Apply 가 합성**하게 했다. +// 우선순위 = 피격 점멸(0.03 s) > 상시 엘리트 색. 점멸이 꺼지면 상시 색으로 복귀한다. +// +// ■ 러너를 만들지 않았다 +// 크기는 등장 1회 · 색은 상시(MobHitFlash 가 이미 틱을 갖는다) · TTK 는 이벤트 2개의 시각 차이라 +// **매 프레임 할 일이 없다**. 씬 전환 정리만 SceneManager.activeSceneChanged 로 직접 잡는다 +// (811gh ImpactRunner · 811def WLReactionRunner 어느 쪽 파일도 건드리지 않는다 = 병합 충돌 0). +// 시각은 ImpactRunner.Now(Play = Time.unscaledTime · 프로브 = 시뮬 시계)를 읽어 에디트 모드에서도 TTK 를 잴 수 있다. +// +// ■ 값(C45) — 게임 수치 상수 0. 전부 Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset. +// HP(8~12 s)는 코드가 아니라 **데이터**다 — MonsterAppear.json 엘리트 스포너 행 813021~813024 의 n_MonsterHP. +// 킬캠(811d)·드랍(813f)·임팩트 티어(811gh)는 이미 eSubRol.Elite 분기를 갖고 있어 이 파일이 손대지 않는다. +// +// 🔴 어셈블리 주의: Assets/WL/Combat/ 에 .asmdef 를 만들지 말 것. +// ───────────────────────────────────────────────────────────────────────────── + +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.SceneManagement; +using WL.Combat.Core; + +namespace WL.Combat.Reaction +{ + /// 엘리트 몹 마커. 정적 · 새 Manager/Singleton 0 · 러너 0 · GC 0(상태는 액터당 1회 할당 = 풀 크기 상한). + public static class EliteMarker + { + sealed class State + { + public Actor actor; + public Vector3 baseScale; // 마커 적용 전(= MonsterList.f_DefaultScale) 스케일 + public bool baseCaptured; // 기준 스케일을 잡았는가(멱등 보장) + public bool scaled; // 지금 배수가 걸려 있는가 + public bool tinted; + public float spawnAt; // 등장 시각(ImpactRunner.Now) + public bool alive; + } + + static readonly Dictionary s_states = new Dictionary(16); + static bool s_sceneHooked; + + // ── 처치 시간(TTK) 표본 — 사전 할당 링버퍼(GC 0) + const int kSamples = 16; + static readonly float[] s_ttk = new float[kSamples]; + static int s_ttkCount, s_ttkHead; + + // ── 진단(프로브가 읽는다) + public static bool Subscribed; + public static int SpawnCount, KillCount, ScaleApplied, ScaleSkipped, TintApplied, TintSkipped, StatesCreated, SkippedNotElite, SkippedDisabled; + public static string LastInfo = ""; + public static float LastKillTime = -1f; + public static float LastAppliedScale; + public static int StateCount { get { return s_states.Count; } } + public static int TtkCount { get { return s_ttkCount; } } + + /// 표본 평균 처치 시간(초). 표본이 없으면 -1. + public static float TtkAverage + { + get + { + if (s_ttkCount == 0) return -1f; + float sum = 0f; + for (int i = 0; i < s_ttkCount; i++) sum += s_ttk[i]; + return sum / s_ttkCount; + } + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void Register() + { + CombatEvents.Spawned.Add(OnSpawned); + CombatEvents.Killed.Add(OnKilled); + if (!s_sceneHooked) { SceneManager.activeSceneChanged += OnSceneChanged; s_sceneHooked = true; } + Subscribed = true; + } + + static void OnSceneChanged(Scene from, Scene to) { ClearAll(); } + + static WLEliteSettings St { get { return WLEliteSettings.Instance; } } + + static void Log(string msg) + { + var st = St; + if (st != null && st.verboseLog) Debug.Log("[EliteMarker] " + msg); + } + + /// 엘리트 판정 — 이벤트 스냅샷을 먼저 보고, 없으면 액터를 다시 읽는다(둘 다 Actor.m_SubRole 이 출처). + static bool IsElite(Actor a, bool snapshot) + { + return snapshot || (a != null && a.IsSubRole(eSubRol.Elite)); + } + + // ───────────────────────────────────────── 이벤트 + static void OnSpawned(in SpawnedEvent e) + { + var actor = e.actor; + if (actor == null) return; + if (!IsElite(actor, e.isElite)) { SkippedNotElite++; return; } + if (!WLEliteSettings.Enabled) { SkippedDisabled++; return; } + + var st = St; + var s = GetState(actor); + s.alive = true; + s.spawnAt = ImpactRunner.Now; + SpawnCount++; + + ApplyScale(s, st); + ApplyTint(s, st); + + LastInfo = "spawn"; + Log("등장 " + actor.name + " scale=" + actor.transform.localScale.x.ToString("F2") + + " (기본 " + s.baseScale.x.ToString("F2") + ") 색=" + s.tinted); + } + + static void OnKilled(in KilledEvent e) + { + var victim = e.victim; + if (victim == null) return; + if (e.subRole != eSubRol.Elite && !IsElite(victim, false)) return; + + State s; + if (!s_states.TryGetValue(victim, out s)) return; + if (!s.alive) return; + s.alive = false; + KillCount++; + + var st = St; + float ttk = ImpactRunner.Now - s.spawnAt; + if (ttk >= 0f) + { + LastKillTime = ttk; + s_ttk[s_ttkHead] = ttk; + s_ttkHead = (s_ttkHead + 1) % kSamples; + if (s_ttkCount < kSamples) s_ttkCount++; + if (st != null && st.killTimeLogEnabled) + { + string verdict = ttk < st.killTimeTargetMin ? "빠름" : ttk > st.killTimeTargetMax ? "느림" : "목표"; + Debug.Log("[EliteMarker] 엘리트 처치 " + victim.name + " " + ttk.ToString("F1") + " s (" + + verdict + " · 목표 " + st.killTimeTargetMin.ToString("F0") + "~" + + st.killTimeTargetMax.ToString("F0") + " s · 평균 " + TtkAverage.ToString("F1") + " s)"); + } + } + + // 색만 뗀다(디졸브·풀 잔류 0) · 크기는 유지(사망 프레임 몸집 튐 방지) + if (s.tinted) { MobHitFlash.ClearEliteTint(victim); s.tinted = false; } + LastInfo = "kill"; + } + + // ───────────────────────────────────────── 적용 + static State GetState(Actor actor) + { + State s; + if (s_states.TryGetValue(actor, out s)) return s; + s = new State { actor = actor }; + s_states.Add(actor, s); + StatesCreated++; + return s; + } + + static void ApplyScale(State s, WLEliteSettings st) + { + if (st == null || !st.scaleEnabled) { ScaleSkipped++; return; } + var tf = s.actor != null ? s.actor.transform : null; + if (tf == null) { ScaleSkipped++; return; } + + // 기준 스케일은 처음 볼 때 1회만 잡는다. 원본 MobActor.Set 이 f_DefaultScale 로 넣은 값이다. + if (!s.baseCaptured) { s.baseScale = tf.localScale; s.baseCaptured = true; } + + float mul = st.scaleMultiplier; + if (mul <= 0f) { ScaleSkipped++; return; } + var target = s.baseScale * mul; + if (st.scaleMaxAbsolute > 0f && target.x > st.scaleMaxAbsolute) + target = s.baseScale * (st.scaleMaxAbsolute / Mathf.Max(0.0001f, s.baseScale.x)); + + tf.localScale = target; // 대입(누적 곱이 아니다) = 멱등 + s.scaled = true; + LastAppliedScale = target.x; + ScaleApplied++; + } + + static void ApplyTint(State s, WLEliteSettings st) + { + if (st == null || !st.tintEnabled) { TintSkipped++; return; } + if (MobHitFlash.SetEliteTint(s.actor, st.tintAlbedo, st.tintEmission)) { s.tinted = true; TintApplied++; } + else TintSkipped++; + } + + // ───────────────────────────────────────── 정리 (C8 · 씬 전환 · 프로브) + /// 모든 엘리트의 크기·색을 원복한다. 상태 캐시는 유지. + public static void RestoreAll() + { + foreach (var kv in s_states) + { + var s = kv.Value; + if (s.scaled && s.baseCaptured && s.actor != null && s.actor.transform != null) + s.actor.transform.localScale = s.baseScale; + s.scaled = false; + if (s.tinted) { MobHitFlash.ClearEliteTint(s.actor); s.tinted = false; } + s.alive = false; + } + } + + /// 씬 전환: 원복 후 상태 캐시(파괴된 Actor 참조)를 버린다. + public static void ClearAll() + { + RestoreAll(); + s_states.Clear(); + } + + /// 프로브용 — 이 액터가 지금 마커 상태인가. + public static bool IsMarked(Actor actor) + { + State s; + return actor != null && s_states.TryGetValue(actor, out s) && (s.scaled || s.tinted); + } + + /// 프로브용 — 이 액터의 기준(원본) 스케일. 없으면 -1. + public static float BaseScaleOf(Actor actor) + { + State s; + return actor != null && s_states.TryGetValue(actor, out s) && s.baseCaptured ? s.baseScale.x : -1f; + } + + /// 프로브용 — 에디트 모드에는 구독자가 없다(RuntimeInitializeOnLoadMethod 는 Play 전용) → 핸들러를 직접 부른다. + public static void ProbeSpawned(Actor actor) + { + var e = new SpawnedEvent + { + actor = actor, + isBoss = actor != null && actor.IsSubRole(eSubRol.Boss), + isElite = actor != null && actor.IsSubRole(eSubRol.Elite), + position = actor != null ? actor.Get_position() : Vector3.zero, + time = Time.unscaledTime, frame = Time.frameCount + }; + OnSpawned(in e); + } + + /// 프로브용 — 가짜 Killed. + public static void ProbeKilled(Actor victim, eSubRol subRole) + { + var e = new KilledEvent + { + victim = victim, killer = null, subRole = subRole, + id = victim != null ? victim.Get_ID() : 0, + position = victim != null ? victim.Get_position() : Vector3.zero, + byDirectHit = true, time = Time.unscaledTime, frame = Time.frameCount + }; + OnKilled(in e); + } + + /// 프로브용 카운터 초기화. + public static void ResetDiagnostics() + { + SpawnCount = KillCount = ScaleApplied = ScaleSkipped = TintApplied = TintSkipped = StatesCreated = SkippedNotElite = SkippedDisabled = 0; + LastInfo = ""; LastKillTime = -1f; LastAppliedScale = 0f; + s_ttkCount = 0; s_ttkHead = 0; + } + } +} diff --git a/Assets/WL/Combat/Reaction/EliteMarker.cs.meta b/Assets/WL/Combat/Reaction/EliteMarker.cs.meta new file mode 100644 index 000000000..be85af858 --- /dev/null +++ b/Assets/WL/Combat/Reaction/EliteMarker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 603dc257f7e9450f8fbeb54341cb5aeb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/WL/Combat/Reaction/MobHitFlash.cs b/Assets/WL/Combat/Reaction/MobHitFlash.cs index abb3ae9b3..0bf660cfc 100644 --- a/Assets/WL/Combat/Reaction/MobHitFlash.cs +++ b/Assets/WL/Combat/Reaction/MobHitFlash.cs @@ -40,6 +40,9 @@ namespace WL.Combat.Reaction public int activeIndex = -1; // WL #811gh — 임팩트 티어별 점멸 강도. 1 = 기존 동작(티어 시스템 off 이면 항상 1). public float blinkColorMul = 1f, blinkTimeMul = 1f; + // WL #813s — 엘리트 상시 색(EliteMarker 가 등록). false = 기존 동작 그대로. + public bool elite; + public Color eliteAlbedo, eliteEmission; } static readonly Dictionary s_states = new Dictionary(64); @@ -239,6 +242,13 @@ namespace WL.Combat.Reaction if (r == null) continue; var mpb = s.blocks[i]; mpb.Clear(); + // WL #813s — 엘리트 상시 색을 먼저 깐다. 아래 점멸이 같은 프로퍼티를 덮으므로 우선순위 = 점멸 > 상시. + if (s.elite) + { + var eres = s.resolved[i]; + if (eres.hasColor) mpb.SetColor(eres.colorId, s.eliteAlbedo); + if (eres.hasEmission) mpb.SetColor(eres.emissionId, s.eliteEmission); + } if (s.blinkOn) { var res = s.resolved[i]; @@ -307,8 +317,8 @@ namespace WL.Combat.Reaction foreach (var kv in s_states) { var s = kv.Value; - if (!s.blinkOn && !s.tint) continue; - s.blinkOn = false; s.tint = false; + if (!s.blinkOn && !s.tint && !s.elite) continue; + s.blinkOn = false; s.tint = false; s.elite = false; if (st != null) Apply(s, st); else for (int i = 0; i < s.renderers.Length; i++) if (s.renderers[i] != null) { s.blocks[i].Clear(); s.renderers[i].SetPropertyBlock(null); } } @@ -323,6 +333,45 @@ namespace WL.Combat.Reaction s_states.Clear(); } + // ───────────────────────────────────────── WL #813s — 엘리트 상시 색 (EliteMarker 가 부른다) + // 렌더러 MPB 의 소유자를 하나로 유지하기 위한 진입점이다. 별도 MPB 를 쓰면 이 클래스의 Apply(=Clear 후 재구성)가 + // 첫 피격 점멸에서 통째로 지운다. 상태만 넣고 합성은 기존 Apply 가 한다(우선순위 = 점멸 > 상시). + // WLHitBlinkSettings 의 enabled 와는 무관하다 — 이 SO 는 프로퍼티명 목록(셰이더 실측)의 출처로만 쓴다. + + /// 엘리트 상시 색을 건다. 렌더러·프로퍼티를 못 찾으면 false(색 없음). + public static bool SetEliteTint(Actor actor, Color albedo, Color emission) + { + var st = St; + if (actor == null || st == null) return false; + var s = GetState(actor, st); + if (s == null) return false; + bool any = false; + for (int i = 0; i < s.resolved.Length; i++) if (s.resolved[i].hasColor || s.resolved[i].hasEmission) { any = true; break; } + if (!any) { SkippedNoProperty++; return false; } + s.elite = true; s.eliteAlbedo = albedo; s.eliteEmission = emission; + Apply(s, st); + if (Verbose) Log("엘리트 상시 색 on " + actor.name + " renderers=" + s.renderers.Length); + return true; + } + + /// 엘리트 상시 색을 뗀다(처치·정리). 점멸/디졸브 상태는 건드리지 않는다. + public static void ClearEliteTint(Actor actor) + { + State s; + if (actor == null || !s_states.TryGetValue(actor, out s) || !s.elite) return; + s.elite = false; + var st = St; + if (st != null) Apply(s, st); + else for (int i = 0; i < s.renderers.Length; i++) if (s.renderers[i] != null) { s.blocks[i].Clear(); s.renderers[i].SetPropertyBlock(null); } + } + + /// 프로브용: 이 액터에 엘리트 상시 색이 걸려 있는가. + public static bool HasEliteTint(Actor actor) + { + State s; + return actor != null && s_states.TryGetValue(actor, out s) && s.elite; + } + /// 프로브용: 특정 액터의 렌더러가 지금 프로퍼티 블록을 갖고 있는가(잔류 검사). public static bool HasAnyBlock(Actor actor) { diff --git a/Assets/WL/Combat/Reaction/WLEliteSettings.cs b/Assets/WL/Combat/Reaction/WLEliteSettings.cs new file mode 100644 index 000000000..f0d6d83eb --- /dev/null +++ b/Assets/WL/Combat/Reaction/WLEliteSettings.cs @@ -0,0 +1,102 @@ +// ───────────────────────────────────────────────────────────────────────────── +// WLEliteSettings.cs — 엘리트 몹 마커(크기 · 상시 색 · 처치 시간 로그) 값의 단일 출처(SOT · C45) +// +// PD 지시 #813 · 발주서 WL-813s §1-2 · 기준서 v1 §B 요소 1 「엘리트 = 8~12 s」 · §D-2 813s 행 (2026-09-09) +// +// 에셋 경로(고정): Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset +// → Resources.Load("WL/WLEliteSettings") 로 1회 로드 후 캐시. +// 에셋이 없거나 enabled = false 또는 RuntimeDisabled 면 EliteMarker 가 아무 것도 하지 않는다 +// (C8 · 원본 = 테이블 f_DefaultScale 그대로 · MPB 0 · 813e 배치 동작 100 %). +// +// 【아웃라인 실측 · 2026-09-09】 +// · 기준서가 적은 `QuickOutline` 컴포넌트는 **이 프로젝트에 없다**(Assets 전수 검색 결과 Outline 이름 자산은 +// TMP 아웃라인 피드백 · VFX 링 머티리얼뿐 · 메시 아웃라인 컴포넌트 0). +// · 몹 셰이더는 MK Toon URP Standard Simple 1종(811def 실측 299 프리팹 중 312 머티리얼). +// 림라이트 프로퍼티(`_RimColor`/`_RimSize`)는 **있으나** `#pragma shader_feature_local __ _MK_RIM_DEFAULT _MK_RIM_SPLIT` +// 키워드 게이팅이라 MaterialPropertyBlock 으로는 켤 수 없고, 이미 켜진 머티리얼에 쓰면 **아트 색을 덮어쓴다** +// → `_RimColor` 는 건드리지 않는다(811gh 교훈 「프로퍼티가 있다고 효과가 있는 게 아니다」). +// · 그래서 발주서가 지정한 대체안 = 811gh PcHitReaction 방식의 **MPB 상시 색**. +// `_EmissionColor`(MK Toon Config.hlsl 이 MK_EMISSION 을 항상 정의 → 키워드 없이 가산 · 확실히 보인다) 가 주 성분, +// `_AlbedoColor`([MainColor] · 게이팅 없음) 가 보조. 새 셰이더/머티리얼 에셋 0 · 머티리얼 인스턴스 0 · 드로우 +0. +// +// 🔴 어셈블리 주의: Assets/WL/Combat/ 에 .asmdef 를 만들지 말 것. +// ───────────────────────────────────────────────────────────────────────────── + +using UnityEngine; + +namespace WL.Combat.Reaction +{ + [CreateAssetMenu(fileName = "WLEliteSettings", menuName = "WL/Elite Settings", order = 325)] + public sealed class WLEliteSettings : ScriptableObject + { + public const string ResourcesPath = "WL/WLEliteSettings"; + + static WLEliteSettings s_cached; + static bool s_lookupDone; + + public static WLEliteSettings Instance + { + get + { + if (!s_lookupDone) + { + s_cached = Resources.Load(ResourcesPath); + s_lookupDone = true; + } + return s_cached; + } + } + + /// 진단·A/B 전용 런타임 스위치. 에셋을 건드리지 않고 마커만 끈다. + public static bool RuntimeDisabled; + + public static bool Enabled + { + get { var i = Instance; return i != null && i.enabled && !RuntimeDisabled; } + } + + public static void ClearCache() { s_cached = null; s_lookupDone = false; } + + // ─────────────────────────────────────────── 전체 스위치 + [Header("전체 스위치")] + [Tooltip("끄면 크기 배수·상시 색·처치 시간 로그가 전부 비활성 = 813e 배치 그대로(원본 동작). 롤백 1순위.")] + public bool enabled = true; + + [Tooltip("등장·처치를 Console 에 남긴다(검증용 · GC 발생).")] + public bool verboseLog = false; + + // ─────────────────────────────────────────── 크기 + [Header("크기 (Spawned(isElite) → localScale = 테이블 기본 스케일 × 배수)")] + [Tooltip("끄면 크기를 건드리지 않는다.")] + public bool scaleEnabled = true; + + [Tooltip("MonsterList.f_DefaultScale 로 정해진 원본 스케일에 곱하는 배수. 기준서 813s = 1.3.\n" + + "🔴 NavMeshAgent 반경·stoppingDistance 는 건드리지 않는다(원본 MobActor.Set 이 이미 정한 값 유지).")] + public float scaleMultiplier = 1.3f; + + [Tooltip("이 값보다 큰 최종 스케일은 여기서 자른다(카메라 가림 방지 · 0 이하면 제한 없음).")] + public float scaleMaxAbsolute = 6f; + + // ─────────────────────────────────────────── 상시 색(아웃라인 대체) + [Header("상시 색 (MPB · 머티리얼 인스턴스 0 · 새 셰이더/머티리얼 0)")] + [Tooltip("끄면 색을 쓰지 않는다. 피격 점멸(MobHitFlash)이 켜지는 동안은 점멸이 이 색을 덮는다(우선순위 = 점멸 > 상시).")] + public bool tintEnabled = true; + + [Tooltip("알베도 색 프로퍼티에 쓰는 상시 색(HDR · MK Toon [MainColor] _AlbedoColor). 1 이면 원본 텍스처 그대로.")] + [ColorUsage(true, true)] public Color tintAlbedo = new Color(1.25f, 1.02f, 0.72f, 1f); + + [Tooltip("에미션 프로퍼티에 쓰는 상시 색(HDR · MK Toon _EmissionColor = 키워드 없이 가산). 엘리트의 '테두리 광'.")] + [ColorUsage(true, true)] public Color tintEmission = new Color(0.85f, 0.45f, 0.08f, 1f); + + // ─────────────────────────────────────────── 처치 시간(기준서 검증용) + [Header("처치 시간 로그 (기준서 §B 요소1 「엘리트 = 8~12 s」)")] + [Tooltip("등장 → 처치까지 걸린 시간을 재서 Console 에 남긴다(QA 판정 근거). 표본은 링버퍼에 사전 할당 = GC 0.")] + public bool killTimeLogEnabled = true; + + [Tooltip("목표 하한(초).")] + public float killTimeTargetMin = 8f; + + [Tooltip("목표 상한(초).")] + public float killTimeTargetMax = 12f; + } +} diff --git a/Assets/WL/Combat/Reaction/WLEliteSettings.cs.meta b/Assets/WL/Combat/Reaction/WLEliteSettings.cs.meta new file mode 100644 index 000000000..1198ae9c3 --- /dev/null +++ b/Assets/WL/Combat/Reaction/WLEliteSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a28c4d2e3ea4ce9a58ae342a4b33bf5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset b/Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset new file mode 100644 index 000000000..606f19cd4 --- /dev/null +++ b/Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset @@ -0,0 +1,25 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4a28c4d2e3ea4ce9a58ae342a4b33bf5, type: 3} + m_Name: WLEliteSettings + m_EditorClassIdentifier: Assembly-CSharp::WL.Combat.Reaction.WLEliteSettings + enabled: 1 + verboseLog: 0 + scaleEnabled: 1 + scaleMultiplier: 1.3 + scaleMaxAbsolute: 6 + tintEnabled: 1 + tintAlbedo: {r: 1.25, g: 1.02, b: 0.72, a: 1} + tintEmission: {r: 0.85, g: 0.45, b: 0.08, a: 1} + killTimeLogEnabled: 1 + killTimeTargetMin: 8 + killTimeTargetMax: 12 diff --git a/Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset.meta b/Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset.meta new file mode 100644 index 000000000..317290235 --- /dev/null +++ b/Assets/WL/Combat/Settings/Resources/WL/WLEliteSettings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8ddb616ff5cc4f30851c6a02698405f2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/WL/Combat/Settings/Resources/WL/WLLootSettings.asset b/Assets/WL/Combat/Settings/Resources/WL/WLLootSettings.asset index 3fd91a33a..b01355753 100644 --- a/Assets/WL/Combat/Settings/Resources/WL/WLLootSettings.asset +++ b/Assets/WL/Combat/Settings/Resources/WL/WLLootSettings.asset @@ -47,8 +47,8 @@ MonoBehaviour: magnetRiseHeight: 3 magnetRiseSpeed: 5 burstEnabled: 1 - eliteBurstMin: 1 - eliteBurstMax: 2 + eliteBurstMin: 2 + eliteBurstMax: 3 bossBurstMin: 3 bossBurstMax: 5 normalBurstCount: 0