From 517e9c51fc3a54d520faa99695794ce8465da54f Mon Sep 17 00:00:00 2001 From: swrring Date: Fri, 8 May 2026 15:24:25 +0900 Subject: [PATCH] =?UTF-8?q?BT5-Dev=20#104:=20EnemyDeath=20=EA=B0=95?= =?UTF-8?q?=ED=99=94=C2=B7=EC=8B=9C=EC=9E=91=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EB=B0=9C=ED=8C=90=20=EA=B2=80=EC=A6=9D=C2=B7=EC=9E=90=EB=8F=99?= =?UTF-8?q?=20=EC=9E=AC=EB=B0=B0=EC=B9=98=20(PD=202=EA=B1=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PD 보고 (2026-05-08): 1. 떨어졌다 복귀 반복 (시작 위치 발판 X 영역 가설) 2. 밟아서 처치한 Enemy 죽지 X·잔존 정정 (BT104): 1. EnemyDeath.cs: - enemy._collider.enabled = false (기존) - enemy.control.enabled = false (기존) - **enemy.enabled = false** 추가 (EnemyController patrol 영역 정지) - **animator.SetTrigger('death')** 추가 (death 애니메이션) - **Object.Destroy(enemy.gameObject, 1f)** 추가 (1초 후 영역 제거) 2. EnemyController.Start (재배치): - 시작 위치 발 영역 Raycast → groundUnder X 시 = 발판 X - 좌·우 0.5m 간격 50m 영역 검색 → 가까운 발판 영역 발견 시 = transform + _startX 재배치 - _startY = 재배치 후 갱신 효과: - 밟기 처치 = enabled=false + death 애니메이션 + 1초 후 Destroy → 정상 사망 - Enemy 시작 위치 발판 X 시 = 가까운 발판 자동 재배치 → 떨어짐 X - BT102 텔레포트 영역 = 보조 영역 (재배치 후 트리거 X) --- Assets/Scripts/Gameplay/EnemyDeath.cs | 22 +++++++++++--- Assets/Scripts/Mechanics/EnemyController.cs | 33 +++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/Assets/Scripts/Gameplay/EnemyDeath.cs b/Assets/Scripts/Gameplay/EnemyDeath.cs index db96405..89da4da 100644 --- a/Assets/Scripts/Gameplay/EnemyDeath.cs +++ b/Assets/Scripts/Gameplay/EnemyDeath.cs @@ -1,22 +1,36 @@ using Platformer.Core; using Platformer.Mechanics; +using UnityEngine; namespace Platformer.Gameplay { /// /// Fired when the health component on an enemy has a hitpoint value of 0. + /// BT104 (PD 명시 2026-05-08): Enemy 사망 시 patrol·시각 영역 비활성 + 1초 후 GameObject Destroy /// - /// public class EnemyDeath : Simulation.Event { public EnemyController enemy; public override void Execute() { - enemy._collider.enabled = false; - enemy.control.enabled = false; - if (enemy._audio && enemy.ouch) + if (enemy == null) return; + + // 충돌·이동·patrol 영역 비활성 + if (enemy._collider != null) enemy._collider.enabled = false; + if (enemy.control != null) enemy.control.enabled = false; + enemy.enabled = false; // BT104: EnemyController patrol 영역 정지 + + // death 애니메이션 트리거 (Enemy.controller 영역의 'death' parameter) + var animator = enemy.GetComponent(); + if (animator != null) animator.SetTrigger("death"); + + // 사운드 + if (enemy._audio != null && enemy.ouch != null) enemy._audio.PlayOneShot(enemy.ouch); + + // 1초 후 GameObject 영역 Destroy (사망 애니메이션 시간) + Object.Destroy(enemy.gameObject, 1f); } } } \ No newline at end of file diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs index 7baec92..1cd215d 100644 --- a/Assets/Scripts/Mechanics/EnemyController.cs +++ b/Assets/Scripts/Mechanics/EnemyController.cs @@ -102,8 +102,41 @@ namespace Platformer.Mechanics } // BT97 — Start 시점 안전 거리 측정 (AutoForeground Tile data 활성 후·AfterSceneLoad 이후) + // BT104 — 시작 위치 발판 검증·자동 재배치 (PD가 PD Foreground·빈 영역 배치 시 가까운 발판 영역으로 이동) void Start() { + if (_collider != null) + { + Vector2 footHere = new Vector2(_collider.bounds.center.x, _collider.bounds.min.y + 0.05f); + RaycastHit2D groundUnder = Physics2D.Raycast(footHere, Vector2.down, cliffCheckDepth, groundLayerMask); + if (groundUnder.collider == null) + { + // 시작 위치 발판 X — 가까운 좌·우 발판 자동 검색 + for (float d = 0.5f; d <= 50f; d += 0.5f) + { + Vector2 rightProbe = new Vector2(_startX + d, footHere.y); + if (Physics2D.Raycast(rightProbe, Vector2.down, cliffCheckDepth, groundLayerMask).collider != null) + { + _startX += d; + Vector3 newPos = new Vector3(_startX, transform.position.y, transform.position.z); + transform.position = newPos; + if (_body != null) _body.position = newPos; + break; + } + Vector2 leftProbe = new Vector2(_startX - d, footHere.y); + if (Physics2D.Raycast(leftProbe, Vector2.down, cliffCheckDepth, groundLayerMask).collider != null) + { + _startX -= d; + Vector3 newPos = new Vector3(_startX, transform.position.y, transform.position.z); + transform.position = newPos; + if (_body != null) _body.position = newPos; + break; + } + } + } + } + _startY = transform.position.y; // 재배치 후 _startY 갱신 + _maxRightRange = MeasureSafeWalkDistance(1f); _maxLeftRange = MeasureSafeWalkDistance(-1f); SetNextPatrolTarget();