돌진 포즈 #1084 — 조준 중 = 출발 자세(ready 1프레임) · 슬링샷 이동 중 = 병종 돌진 포즈(action 1프레임 고정) · 멈추면 대기 · 공격 애니 대신 포즈 전환(PD 2026-11-05 · 키아트 세션 경유) · 테스트 23/23

- UnitView.SetCharging(on) · Charging · 돌진 중 PlayAttack/피격 클립 무시(색만) · SetFacing 세트 전환 시 돌진 포즈 유지
- ActionResolver.Resolve: 루틴 전 SetCharging(true) · 끝나면 false(생존 시 대기)
- 테스트: 출발 자세·돌진 포즈·피격 포즈 유지·종료 뒤 대기 단언

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-11-05 00:56:38 +09:00
parent 7578c4d31a
commit ec15fed24e
3 changed files with 41 additions and 6 deletions

View File

@ -54,6 +54,8 @@ namespace TKS
if (dist < 0.001f || !u.IsAlive) yield break;
Vector2 dir = delta / dist;
// 슬링샷 돌진 중 = 병종 돌진 포즈 1프레임 고정 · 끝나면 대기 (PD 2026-11-05 #1084)
if (u.View != null) u.View.SetCharging(true);
switch (u.Type)
{
case UnitType.Infantry:
@ -69,6 +71,7 @@ namespace TKS
yield return ArcherRoutine(u, origin, dir, dist, target, moveOnly, o);
break;
}
if (u.View != null) u.View.SetCharging(false);
}
// ---------- 미리보기(드라이런) ----------

View File

@ -33,6 +33,7 @@ namespace TKS
Color baseColor;
Coroutine flash;
bool aiming;
bool charging; // 슬링샷 돌진(이동) 중 = 돌진 포즈 고정
bool facingBack; // 위를 봄(뒷모습 back_* 세트) · false = 아래를 봄(앞모습 front_*)
bool facingLeft; // 왼쪽을 봄(좌우 반전) · false = 오른쪽(기본)
const float FacingEps = 0.05f;
@ -88,7 +89,8 @@ namespace TKS
string cur = anim.Current ?? "";
string suffix = cur.StartsWith("back_") ? cur.Substring(5) : (cur.StartsWith("front_") ? cur.Substring(6) : "idle");
anim.SetIdle(ClipName("idle"));
if (suffix == "idle") anim.PlayIdle();
if (charging) anim.Play(ClipName("action"), true);
else if (suffix == "idle") anim.PlayIdle();
else if (suffix == "ready") anim.Play(ClipName("ready"), true);
else if (suffix == "victory") anim.Play(ClipName("victory"), false);
else anim.Play(ClipName(suffix), false, AttackHold, true);
@ -200,19 +202,34 @@ namespace TKS
if (highlightRing != null) highlightRing.enabled = on;
}
/// <summary>조준(당기는) 중 = 준비 자세 · 끝나면 대기.</summary>
/// <summary>조준(당기는) 중 = 출발 자세(ready · 1프레임) · 끝나면 대기 (PD 2026-11-05 #1084).</summary>
public void SetAiming(bool on)
{
if (anim == null || aiming == on) return;
aiming = on;
if (on) anim.Play(ClipName("ready"), true);
else anim.PlayIdle();
else if (!charging) anim.PlayIdle();
}
/// <summary>공격 자세(1 프레임) 잠깐 → 대기.</summary>
/// <summary>슬링샷 돌진(이동) 중 = 병종 돌진 포즈(action · 1프레임 고정) · 멈추면 대기 (PD 2026-11-05 #1084).</summary>
public void SetCharging(bool on)
{
if (anim == null || charging == on) return;
charging = on;
aiming = false;
if (on) anim.Play(ClipName("action"), true);
else if (unit != null && unit.IsAlive) anim.PlayIdle();
}
public bool Charging
{
get { return charging; }
}
/// <summary>공격 자세(1 프레임) 잠깐 → 대기. 돌진 중이면 이미 돌진 포즈라 그대로 둔다.</summary>
public void PlayAttack()
{
if (anim == null || !isActiveAndEnabled) return;
if (anim == null || !isActiveAndEnabled || charging) return;
aiming = false;
anim.Play(ClipName("action"), false, AttackHold, true);
}
@ -237,7 +254,7 @@ namespace TKS
if (anim != null)
{
anim.Renderer.color = ArtHitTint;
if (unit.IsAlive) anim.Play(ClipName("damage"), false, HitHold, true);
if (unit.IsAlive && !charging) anim.Play(ClipName("damage"), false, HitHold, true); // 돌진 중 피격은 색만(포즈 유지)
}
else
{

View File

@ -475,6 +475,21 @@ namespace TKS.Tests
rigged.View.PlayAttack();
Assert.AreEqual("back_action", rigged.View.Anim.Current, "공격 자세 클립");
// PD 2026-11-05 #1084: 조준 중 = 출발 자세(ready) · 돌진 중 = 돌진 포즈(action 고정) · 멈추면 대기
rigged.View.SetAiming(true);
Assert.AreEqual("back_ready", rigged.View.Anim.Current, "조준(당기는) 중 = 출발 자세");
rigged.View.SetAiming(false);
rigged.View.SetCharging(true);
Assert.AreEqual("back_action", rigged.View.Anim.Current, "돌진 중 = 병종 돌진 포즈");
rigged.View.OnHit();
Assert.AreEqual("back_action", rigged.View.Anim.Current, "돌진 중 피격은 포즈 유지");
rigged.View.SetCharging(false);
Assert.AreEqual("back_idle", rigged.View.Anim.Current, "멈추면 대기");
var o2 = new ActionOutcome();
yield return bm.ResolveForTest(rigged, rigged.Position + new Vector2(0f, 2f), false, o2);
Assert.IsFalse(rigged.View.Charging, "슬링샷이 끝나면 돌진 포즈 해제");
Assert.AreEqual("back_idle", rigged.View.Anim.Current);
// 원화 세션 1차 납품(2026-11-04): 황건적 5종 정지 그림(front_idle 1장) + 전장 배경
int enemyArt = 0;
foreach (var e in bm.AliveUnits(Faction.Enemy))