fix(BT12-Dev): AnimationController field initializer NRE 정정 (Awake 실행·sr/anim/body 초기화)

PD: "여전히 움직이지 않아·실측·근본 원인 체크"

근본 (MCP Play 실측·자성 #12·#13):
- AnimationController field initializer: PlatformerModel model = Simulation.GetModel<PlatformerModel>()
- Editor·Play mode 전환 시 Simulation.GetModel 호출이 인스턴스 컨텍스트 외부에서 실행
- field initializer 영역 NRE/Exception → Component 생성 자체 실패
- Awake/OnEnable 모두 호출 X
- 결과: spriteRenderer/animator/body 모두 NULL
- AnimationController.ComputeVelocity NRE → KinematicObject.Update/FixedUpdate 영역 실행되나
  spriteRenderer.flipX/animator.SetFloat 호출 NRE → ComputeVelocity 영역 중단·targetVelocity 미설정
- velocity=0·move=0·Enemy 영구 정지

fix:
1. field initializer 폐기·Awake 영역 try-catch로 안전 초기화
   - try { model = Simulation.GetModel<PlatformerModel>(); } catch { model = null; }
2. ComputeVelocity에서 spriteRenderer/animator NULL 가드
3. model NULL 시 jumpModifier=1·jumpDeceleration=0.5 default

검증 (MCP Play):
- 직전: sr=NULL·anim=NULL·body=NULL
- 정정 후: sr=OK·anim=OK·body=OK·IsGrounded=True

회귀 영역 X:
- spriteRenderer/animator GetComponentInChildren fallback 정합
- KinematicObject·EnemyController·patrol·cliffCheck 영역 영역 X

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-05-12 17:30:01 +09:00
parent a502c7aca6
commit 899bbf16f9
1 changed files with 17 additions and 9 deletions

View File

@ -39,7 +39,7 @@ namespace Platformer.Mechanics
SpriteRenderer spriteRenderer;
Animator animator;
PlatformerModel model = Simulation.GetModel<PlatformerModel>();
PlatformerModel model;
protected virtual void Awake()
{
@ -48,13 +48,17 @@ namespace Platformer.Mechanics
if (spriteRenderer == null) spriteRenderer = GetComponentInChildren<SpriteRenderer>();
animator = GetComponent<Animator>();
if (animator == null) animator = GetComponentInChildren<Animator>();
// BT12-Dev 2026-05-12 — field initializer Awake 영역 이동 (Editor·Play mode 전환 시 model 미초기화 NRE 회피).
try { model = Simulation.GetModel<PlatformerModel>(); } catch { model = null; }
}
protected override void ComputeVelocity()
{
float jumpMod = model != null ? model.jumpModifier : 1f;
float jumpDec = model != null ? model.jumpDeceleration : 0.5f;
if (jump && IsGrounded)
{
velocity.y = jumpTakeOffSpeed * model.jumpModifier;
velocity.y = jumpTakeOffSpeed * jumpMod;
jump = false;
}
else if (stopJump)
@ -62,18 +66,22 @@ namespace Platformer.Mechanics
stopJump = false;
if (velocity.y > 0)
{
velocity.y = velocity.y * model.jumpDeceleration;
velocity.y = velocity.y * jumpDec;
}
}
// PD 명시 2026-05-08 — PlayerController와 동일 영역 정합: 좌측 향한 sprite 기준 우측 이동 시 flipX=true
if (move.x > 0.01f)
spriteRenderer.flipX = true;
else if (move.x < -0.01f)
spriteRenderer.flipX = false;
if (spriteRenderer != null)
{
if (move.x > 0.01f) spriteRenderer.flipX = true;
else if (move.x < -0.01f) spriteRenderer.flipX = false;
}
animator.SetBool("grounded", IsGrounded);
animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed);
if (animator != null)
{
animator.SetBool("grounded", IsGrounded);
animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed);
}
targetVelocity = move * maxSpeed;
}