From 899bbf16f9e75f5a5924ac567caa9c3cfc28a8a0 Mon Sep 17 00:00:00 2001 From: swrring Date: Tue, 12 May 2026 17:30:01 +0900 Subject: [PATCH] =?UTF-8?q?fix(BT12-Dev):=20AnimationController=20field=20?= =?UTF-8?q?initializer=20NRE=20=EC=A0=95=EC=A0=95=20(Awake=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=C2=B7sr/anim/body=20=EC=B4=88=EA=B8=B0=ED=99=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PD: "여전히 움직이지 않아·실측·근본 원인 체크" 근본 (MCP Play 실측·자성 #12·#13): - AnimationController field initializer: PlatformerModel model = Simulation.GetModel() - 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(); } 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) --- .../Scripts/Mechanics/AnimationController.cs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Assets/Scripts/Mechanics/AnimationController.cs b/Assets/Scripts/Mechanics/AnimationController.cs index ed58455..0efaaaf 100644 --- a/Assets/Scripts/Mechanics/AnimationController.cs +++ b/Assets/Scripts/Mechanics/AnimationController.cs @@ -39,7 +39,7 @@ namespace Platformer.Mechanics SpriteRenderer spriteRenderer; Animator animator; - PlatformerModel model = Simulation.GetModel(); + PlatformerModel model; protected virtual void Awake() { @@ -48,13 +48,17 @@ namespace Platformer.Mechanics if (spriteRenderer == null) spriteRenderer = GetComponentInChildren(); animator = GetComponent(); if (animator == null) animator = GetComponentInChildren(); + // BT12-Dev 2026-05-12 — field initializer Awake 영역 이동 (Editor·Play mode 전환 시 model 미초기화 NRE 회피). + try { model = Simulation.GetModel(); } 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; }