using UnityEngine; namespace TKS.EditorTools { /// /// BalanceConfig 자산의 최초 1회 시드 값(프로토타입 초안). 이후 수치 조정은 자산(Inspector)에서 한다 — 코드가 SOT 가 아니다. /// 전장 = 가로 20 × 세로 32 (x −10~10 · y −16~16) · 화면에는 세로 18 만 보여 스크롤한다. 아군은 아래(전열 y −12 · 후열 −14) · 적은 전위/중군/후군으로 흩어 배치. /// 아트 id = Resources/Units/<id>/ (아군 = 아웃게임 heroes.csv art 열 · 적 = 일러 세션 납품 이름 <세력>_<병종> · 없으면 도형). /// 챕터·스테이지는 시드하지 않는다 — Assets/Data/Stages/*.csv 가 SOT(StageImporter · 2026-11-05 145 스테이지). 여기는 배치 규칙·장수 배율 출발값만. /// public static class BalanceDefaults { public static void Apply(BalanceConfig c) { c.unitStats = new[] { Stats(UnitType.Infantry, 100, 30, 10, 4.5f, 0f, 0.45f), Stats(UnitType.Cavalry, 110, 28, 8, 6.5f, 0f, 0.45f), Stats(UnitType.Archer, 70, 26, 4, 4.0f, 0f, 0.42f), // 궁병 사거리 = slingMaxDistance (attackRange 미사용 · #1080) Stats(UnitType.Spear, 100, 30, 10, 4.5f, 2.2f, 0.45f), Stats(UnitType.Strategist, 65, 24, 3, 4.0f, 0f, 0.42f), // PD 2026-11-05 #1087 ⑤ 제안값 · 사거리 = slingMaxDistance(궁병과 동일) }; // 상성: 보병 > 창병 > 기병 > 보병 · 원거리(궁병·책사)는 근접 3종에게 약함(받는 피해 1.5) · 원거리가 주는 피해 = 전부 1.0 c.matchup = new float[UnitTypeInfo.Count * UnitTypeInfo.Count]; for (int i = 0; i < c.matchup.Length; i++) c.matchup[i] = 1f; c.SetMatchup(UnitType.Infantry, UnitType.Spear, 1.5f); c.SetMatchup(UnitType.Infantry, UnitType.Cavalry, 0.7f); c.SetMatchup(UnitType.Spear, UnitType.Cavalry, 1.5f); c.SetMatchup(UnitType.Spear, UnitType.Infantry, 0.7f); c.SetMatchup(UnitType.Cavalry, UnitType.Infantry, 1.5f); c.SetMatchup(UnitType.Cavalry, UnitType.Spear, 0.7f); c.SetMatchup(UnitType.Infantry, UnitType.Archer, 1.5f); c.SetMatchup(UnitType.Cavalry, UnitType.Archer, 1.5f); c.SetMatchup(UnitType.Spear, UnitType.Archer, 1.5f); c.SetMatchup(UnitType.Infantry, UnitType.Strategist, 1.5f); // 책사 열 = 궁병 열과 같은 값으로 출발(PD 확인 대상) c.SetMatchup(UnitType.Cavalry, UnitType.Strategist, 1.5f); c.SetMatchup(UnitType.Spear, UnitType.Strategist, 1.5f); c.defenseFactor = 0.5f; c.counterRatio = 0.5f; c.critMultiplier = 2f; c.damageVariance = 0.1f; c.overwatchDamageRatio = 1f; c.bossHpMult = 1.6f; c.bossRadiusMult = 1.25f; c.cavalryKnockback = 0.35f; c.archerRangeRatio = 0.2f; // PD 2026-11-04: 사거리(슬링샷 범위) 밖 +20 % 안의 적에게 다가가 사격 c.archerMeleeDealtRatio = 0.5f; // PD 2026-11-04 #1080: 궁수 근접 전투 피해 50 % c.archerMeleeTakenRatio = 1.5f; // PD 2026-11-04 #1080: 궁수 근접 피격 +50 % c.arrowRadius = 0.1f; // PD 2026-11-05 #1087 ⑥: 화살 투사체 폭(경로 위 첫 유닛 피격) c.strategistSplashRadius = 1.5f; // PD 2026-11-05 #1087 ⑤ 제안값: 광역 반경(유닛 지름 약 1.7 개) c.strategistSplashRatio = 0.6f; // 광역 피해 = 대상별 피해 × 0.6(크리 없음) c.strategistAllyDamageRatio = 1f; // 광역 아군 피해 = 적과 동일(PD 확인 대상) c.collisionPushRatio = 1f; // PD 2026-11-04 #1080: 보병 알까기 밀어내기 = 남은 거리 그대로 c.collisionSelfBounceRatio = 0.5f; // PD 2026-11-04 #1081: 보병 자신도 반대로 튕김(남은 거리의 절반 · 손맛 조정 대상) c.spearPushRatio = 1.5f; // PD 2026-11-10: 창병 = 적을 크게 밀침(남은 거리 × 1.5 · 보병 1.0) c.spearRecoilRatio = 0.2f; // PD 2026-11-10: 창병 자신은 적게 밀림(밀린 거리 × 0.2 = 남은 거리 × 0.3 · 보병 자기 튕김 0.5) · 옛 0.5(#1098) c.unitArtHeight = 1.5f; c.mountedArtMaxTop = 1.3f; // 기마 머리 끝 상한 = 표준 키 × 1.3(PD 2026-11-09) c.boardArt = "battlefield_01"; // 원화 세션 1차 납품(2026-11-04) · Resources/Board/ c.minDragDistance = 0.35f; c.finalHitTolerance = 0.15f; c.moveSpeed = 9f; c.boardSize = new Vector2(20f, 32f); c.cameraViewHeight = 18f; c.cameraMinViewHeight = 10f; c.cameraMaxViewHeight = 36f; // 편성 자리(2026-11-05 #1093 시스템 기획 §10 A): 전열 3 = 앞줄 x −4/0/+4 · y −12 · 후열 2 = 뒷줄 x −2/+2 · y −14 // 아군 영웅·병사 정의는 시드하지 않는다 — Assets/Data/OutGame/heroes.csv(HeroDb · TKS/Import OutGame Data)가 SOT c.playerSpawnPoints = new[] { new Vector2(-4f, -12f), new Vector2(0f, -12f), new Vector2(4f, -12f), new Vector2(-2f, -14f), new Vector2(2f, -14f), }; // 적 배치 규칙 = 구 시드 4 스테이지(황건적의 난·호로관·적벽·오장원)의 전위 y −6~−4.5 · 중군 −2~5 · 후군 7~9 · 장수 10~13 · 가로 간격 2.5~3 을 규칙화 c.formation = new BalanceConfig.FormationRule { frontY = -5.5f, middleY = 0.5f, rearY = 7.5f, commandY = 11f, colGap = 2.6f, rowGap = 1.8f, maxPerRow = 5, rowStagger = 0.5f, frontShare = 0.4f, rearShare = 0.15f, }; // 장수 배율 출발값(밸런스 세션 조정) · 보스 = 구 시드 보스 4인(1.3~1.6 / 1.2~1.5)의 가운데 값 · 장각·여포·조조는 generals.csv 에 구 값 승계 c.bossGeneralHpMult = 1.5f; c.bossGeneralAtkMult = 1.3f; c.eliteGeneralHpMult = 1.25f; c.eliteGeneralAtkMult = 1.15f; c.chapters = new BalanceConfig.ChapterDef[0]; c.stages = new BalanceConfig.StageDef[0]; } static BalanceConfig.UnitStats Stats(UnitType t, int hp, int atk, int def, float sling, float range, float radius) { return new BalanceConfig.UnitStats { type = t, maxHp = hp, atk = atk, def = def, slingMaxDistance = sling, attackRange = range, radius = radius }; } } }