diff --git a/Assets/Editor/PatrolPathEditor.cs b/Assets/Editor/PatrolPathEditor.cs
deleted file mode 100644
index 9006e98..0000000
--- a/Assets/Editor/PatrolPathEditor.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using Platformer.Mechanics;
-using UnityEditor;
-using UnityEngine;
-namespace Platformer
-{
- [CustomEditor(typeof(PatrolPath))]
- public class PatrolPathGizmo : Editor
- {
- public void OnSceneGUI()
- {
- var path = target as PatrolPath;
- using (var cc = new EditorGUI.ChangeCheckScope())
- {
- var sp = path.transform.InverseTransformPoint(Handles.PositionHandle(path.transform.TransformPoint(path.startPosition), path.transform.rotation));
- var ep = path.transform.InverseTransformPoint(Handles.PositionHandle(path.transform.TransformPoint(path.endPosition), path.transform.rotation));
- if (cc.changed)
- {
- sp.y = 0;
- ep.y = 0;
- path.startPosition = sp;
- path.endPosition = ep;
- }
- }
- Handles.Label(path.transform.position, (path.startPosition - path.endPosition).magnitude.ToString());
- }
-
- [DrawGizmo(GizmoType.Selected | GizmoType.NonSelected)]
- static void OnDrawGizmo(PatrolPath path, GizmoType gizmoType)
- {
- var start = path.transform.TransformPoint(path.startPosition);
- var end = path.transform.TransformPoint(path.endPosition);
- Handles.color = Color.yellow;
- Handles.DrawDottedLine(start, end, 5);
- Handles.DrawSolidDisc(start, path.transform.forward, 0.1f);
- Handles.DrawSolidDisc(end, path.transform.forward, 0.1f);
- }
- }
-}
diff --git a/Assets/Editor/PatrolPathEditor.cs.meta b/Assets/Editor/PatrolPathEditor.cs.meta
deleted file mode 100644
index c9fcc3a..0000000
--- a/Assets/Editor/PatrolPathEditor.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 574b9f9d90f1a4e0180d882b20207004
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Scripts/Gameplay/PlayerEnemyCollision.cs b/Assets/Scripts/Gameplay/PlayerEnemyCollision.cs
index 8a41556..d47f89b 100644
--- a/Assets/Scripts/Gameplay/PlayerEnemyCollision.cs
+++ b/Assets/Scripts/Gameplay/PlayerEnemyCollision.cs
@@ -41,7 +41,9 @@ namespace Platformer.Gameplay
bool inAir = !player.IsGrounded;
bool playerAbove = player.transform.position.y > enemy.transform.position.y;
+#if UNITY_EDITOR && ENEMY_DIAG_VERBOSE
Debug.Log($"[PEC] inAir={inAir} above={playerAbove} delta={dyAtCollision:F2} pY={player.transform.position.y:F2} eY={enemy.transform.position.y:F2}");
+#endif
if (inAir && playerAbove)
{
diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs
index 02dc5fb..42127a2 100644
--- a/Assets/Scripts/Mechanics/EnemyController.cs
+++ b/Assets/Scripts/Mechanics/EnemyController.cs
@@ -12,7 +12,6 @@ namespace Platformer.Mechanics
[RequireComponent(typeof(AnimationController), typeof(Collider2D))]
public class EnemyController : MonoBehaviour
{
- public PatrolPath path; // legacy 호환·자동 patrol 영역 도입 후 미사용
public AudioClip ouch;
/// BT5-Dev #16 — Distance 기반 감지 영역 X 임계값 (전체 폭). 표준 platformer Enemy 옆 닿음 영역 0.6~0.8.
@@ -48,7 +47,6 @@ namespace Platformer.Mechanics
private float _maxLeftRange; // 시작 시 측정 — 좌측 안전 patrol 거리
private bool _isInitialized; // BT97: Start 측정 완료 영역 (Awake 이후 활성)
- internal PatrolPath.Mover mover; // legacy 호환·미사용
internal AnimationController control;
internal Collider2D _collider;
internal AudioSource _audio;
@@ -110,7 +108,9 @@ namespace Platformer.Mechanics
_maxRightRange = MeasureSafeWalkDistance(1f);
_maxLeftRange = MeasureSafeWalkDistance(-1f);
+#if UNITY_EDITOR && ENEMY_DIAG_VERBOSE
Debug.Log($"[Enemy@{name}] startX={_startX:F2} startY={_startY:F2} maxR={_maxRightRange:F2} maxL={_maxLeftRange:F2}");
+#endif
SetNextPatrolTarget();
_isInitialized = true;
}
@@ -193,7 +193,9 @@ namespace Platformer.Mechanics
}
if (startTm != null) break;
}
+#if UNITY_EDITOR && ENEMY_DIAG_VERBOSE
Debug.Log($"[Enemy@{name}] dir={dir} startY={transformY:F2} colliderFoot={colliderFootY:F2} spriteFoot={spriteFootY:F2} chosenFootY={chosenFootY:F2} startTm={(startTm!=null?startTm.name:"NULL")} startCell={startCell}");
+#endif
if (startTm == null) return 0f;
// 좌·우 연속 Tile 영역 끝 영역 검색
@@ -369,11 +371,13 @@ namespace Platformer.Mechanics
_cachedPlayer = Object.FindFirstObjectByType();
}
+#if UNITY_EDITOR && ENEMY_DIAG_VERBOSE
if (Time.frameCount % 60 == 0)
{
int allCount = Object.FindObjectsByType(FindObjectsSortMode.None).Length;
Debug.Log($"[BT17-Update@{name}] f={Time.frameCount} cached={(_cachedPlayer != null ? _cachedPlayer.name : "NULL")} pgoTag={(pgo != null ? pgo.name : "NULL")} allPCcount={allCount}");
}
+#endif
}
// BT20 — IgnoreCollision 영역 Awake 시점 Player 발견 X 영역 fallback. Update 영역에서 발견 직후 1회 영역 호출.
@@ -384,7 +388,9 @@ namespace Platformer.Mechanics
{
Physics2D.IgnoreCollision(_collider, pc, true);
_ignoreCollisionApplied = true;
+#if UNITY_EDITOR && ENEMY_DIAG_VERBOSE
Debug.Log($"[BT20-Ignore@{name}] Player↔Enemy IgnoreCollision applied");
+#endif
}
}
if (_cachedPlayer != null && _cachedPlayer.health != null && _cachedPlayer.health.IsAlive)
@@ -400,7 +406,9 @@ namespace Platformer.Mechanics
if (inRange != _diagWasIntersecting)
{
+#if UNITY_EDITOR && ENEMY_DIAG_VERBOSE
Debug.Log($"[EnemyDiag@{name}] inRange={inRange} footHeadDelta={footHeadDelta:F2} VB={VisualBounds.size} PB={_cachedPlayer.Bounds.size}");
+#endif
_diagWasIntersecting = inRange;
}
diff --git a/Assets/Scripts/Mechanics/GameOptimizer.cs b/Assets/Scripts/Mechanics/GameOptimizer.cs
index a660b48..fcd4c28 100644
--- a/Assets/Scripts/Mechanics/GameOptimizer.cs
+++ b/Assets/Scripts/Mechanics/GameOptimizer.cs
@@ -149,7 +149,9 @@ namespace Platformer.Mechanics
if (fgTc != null) fgTc.ProcessTilemapChanges();
var lvlTc = levelGo.GetComponent();
if (lvlTc != null) lvlTc.ProcessTilemapChanges();
+#if UNITY_EDITOR && ENEMY_DIAG_VERBOSE
Debug.Log($"[GameOptimizer] AutoForeground moved={movedHigh + movedSmall} (high={movedHigh} small={movedSmall} threshold={airThresholdY:F2}) / Layer16 applied={applied} levelKept0={levelKept} excluded={excluded}");
+#endif
}
}
diff --git a/Assets/Scripts/Mechanics/PatrolPath.Mover.cs b/Assets/Scripts/Mechanics/PatrolPath.Mover.cs
deleted file mode 100644
index 95cf726..0000000
--- a/Assets/Scripts/Mechanics/PatrolPath.Mover.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using UnityEngine;
-
-namespace Platformer.Mechanics
-{
- public partial class PatrolPath
- {
- ///
- /// The Mover class oscillates between start and end points of a path at a defined speed.
- ///
- public class Mover
- {
- PatrolPath path;
- float p = 0;
- float duration;
- float startTime;
-
- public Mover(PatrolPath path, float speed)
- {
- this.path = path;
- this.duration = (path.endPosition - path.startPosition).magnitude / speed;
- this.startTime = Time.time;
- }
-
- ///
- /// Get the position of the mover for the current frame.
- ///
- ///
- public Vector2 Position
- {
- get
- {
- p = Mathf.InverseLerp(0, duration, Mathf.PingPong(Time.time - startTime, duration));
- return path.transform.TransformPoint(Vector2.Lerp(path.startPosition, path.endPosition, p));
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/Scripts/Mechanics/PatrolPath.Mover.cs.meta b/Assets/Scripts/Mechanics/PatrolPath.Mover.cs.meta
deleted file mode 100644
index 56c8d3a..0000000
--- a/Assets/Scripts/Mechanics/PatrolPath.Mover.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 91fcc8d06d79c4678aabe2abed234213
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Scripts/Mechanics/PatrolPath.cs b/Assets/Scripts/Mechanics/PatrolPath.cs
deleted file mode 100644
index bf279f4..0000000
--- a/Assets/Scripts/Mechanics/PatrolPath.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using UnityEngine;
-
-namespace Platformer.Mechanics
-{
- ///
- /// This component is used to create a patrol path, two points which enemies will move between.
- ///
- public partial class PatrolPath : MonoBehaviour
- {
- ///
- /// One end of the patrol path.
- ///
- public Vector2 startPosition, endPosition;
-
- ///
- /// Create a Mover instance which is used to move an entity along the path at a certain speed.
- ///
- ///
- ///
- public Mover CreateMover(float speed = 1) => new Mover(this, speed);
-
- void Reset()
- {
- startPosition = Vector3.left;
- endPosition = Vector3.right;
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/Scripts/Mechanics/PatrolPath.cs.meta b/Assets/Scripts/Mechanics/PatrolPath.cs.meta
deleted file mode 100644
index a829321..0000000
--- a/Assets/Scripts/Mechanics/PatrolPath.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 83b023ebe508a49c880fc00552f0dfc1
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Scripts/Mechanics/PlatformDropThrough.cs b/Assets/Scripts/Mechanics/PlatformDropThrough.cs
deleted file mode 100644
index b16df30..0000000
--- a/Assets/Scripts/Mechanics/PlatformDropThrough.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using UnityEngine;
-
-namespace Platformer.Mechanics
-{
- ///
- /// BT5-Dev #27 — PD 제안 Layer + Raycast 동적 충돌.
- /// Layer 8(JumpThrough) 발판은 기본 통과(IgnoreLayerCollision). Player 하강 + 발 Raycast 시점만 IgnoreCollision(false)로 충돌 활성 → 착지.
- /// 점프(상승) 시 IgnoreCollision(true) 복구 → 다시 통과.
- /// PlayerController.Awake에서 자동 부착.
- ///
- [RequireComponent(typeof(Collider2D))]
- public class PlatformDropThrough : MonoBehaviour
- {
- const int JUMP_THROUGH_LAYER = 8;
-
- [Tooltip("발 raycast 기본 거리. velocity 영역에 따라 동적 확대.")]
- public float footRayDistance = 1.0f;
-
- Collider2D _self;
- KinematicObject _ko;
- Collider2D _activePlatform;
- int _jumpThroughMask;
-
- void Awake()
- {
- _self = GetComponent();
- _ko = GetComponent();
- _jumpThroughMask = 1 << JUMP_THROUGH_LAYER;
- Debug.Log($"[BT32-DropThrough] Awake — self={(_self != null ? "OK" : "NULL")} ko={(_ko != null ? "OK" : "NULL")} mask={_jumpThroughMask}");
- }
-
- void Start()
- {
- Debug.Log($"[BT32-DropThrough] Start called");
- if (_self == null) return;
- Vector2 footPos = new Vector2(_self.bounds.center.x, _self.bounds.min.y + 0.02f);
- // BT32 — 거리 무한대 = Player 시작 위치 영역 발판 영역 영역 식별
- RaycastHit2D startHit = Physics2D.Raycast(footPos, Vector2.down, Mathf.Infinity, _jumpThroughMask);
- if (startHit.collider != null)
- {
- Physics2D.IgnoreCollision(_self, startHit.collider, false);
- _activePlatform = startHit.collider;
- Debug.Log($"[BT32-StartHit] dist={startHit.distance:F2} platform='{startHit.collider.gameObject.name}' layer={startHit.collider.gameObject.layer}");
- }
- else
- {
- Debug.Log($"[BT32-StartHit] no Layer 8 platform below footPos={footPos} (mask={_jumpThroughMask})");
- // 마지막 수단 — 모든 Layer raycast해서 가장 가까운 영역 식별
- RaycastHit2D anyHit = Physics2D.Raycast(footPos, Vector2.down, Mathf.Infinity);
- if (anyHit.collider != null)
- Debug.Log($"[BT32-AnyHit] anyLayer dist={anyHit.distance:F2} platform='{anyHit.collider.gameObject.name}' layer={anyHit.collider.gameObject.layer}");
- else
- Debug.Log($"[BT32-AnyHit] NOTHING below player");
- }
- }
-
- void Update()
- {
- if (_self == null || _ko == null) return;
-
- // Player 발 위치 (collider 하단 중심)
- Vector2 footPos = new Vector2(_self.bounds.center.x, _self.bounds.min.y + 0.02f);
-
- // velocity 기반 동적 거리 (빠른 하강 시 raycast miss 차단)
- float dist = Mathf.Max(footRayDistance, Mathf.Abs(_ko.velocity.y) * Time.deltaTime + 0.1f);
- RaycastHit2D hit = Physics2D.Raycast(footPos, Vector2.down, dist, _jumpThroughMask);
-
- bool falling = _ko.velocity.y <= 0.01f; // 하강 또는 정지
- bool rising = _ko.velocity.y > 0.5f; // 점프 상승
-
- if (rising)
- {
- // BT5-Dev #33 — 활성 해제 = 점프(상승) 시점만. 발판 떠남(낙하)은 활성 유지 (Player 거리 영역 벗어나도 충돌 유지·복구)
- if (_activePlatform != null)
- {
- Physics2D.IgnoreCollision(_self, _activePlatform, true);
- _activePlatform = null;
- }
- }
- else if (falling && hit.collider != null && hit.collider != _activePlatform)
- {
- // 하강 + 발판 raycast hit → 충돌 활성 (착지)
- Physics2D.IgnoreCollision(_self, hit.collider, false);
- _activePlatform = hit.collider;
- }
- // BT33 — falling + hit X 영역 활성 해제 영역 폐기 (raycast 거리 일시 벗어남 영역 통과 복구 차단)
- }
-
- void OnDrawGizmosSelected()
- {
- if (_self == null) return;
- Vector2 footPos = new Vector2(_self.bounds.center.x, _self.bounds.min.y + 0.02f);
- Gizmos.color = Color.cyan;
- Gizmos.DrawLine(footPos, footPos + Vector2.down * footRayDistance);
- }
- }
-}
diff --git a/Assets/Scripts/Mechanics/PlatformDropThrough.cs.meta b/Assets/Scripts/Mechanics/PlatformDropThrough.cs.meta
deleted file mode 100644
index 8725e6b..0000000
--- a/Assets/Scripts/Mechanics/PlatformDropThrough.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: bc0df74503a03ee478bb504a5cd1b0c3
\ No newline at end of file
diff --git a/Assets/Scripts/Mechanics/PlayerController.cs b/Assets/Scripts/Mechanics/PlayerController.cs
index e9d8bd5..0308796 100644
--- a/Assets/Scripts/Mechanics/PlayerController.cs
+++ b/Assets/Scripts/Mechanics/PlayerController.cs
@@ -91,9 +91,6 @@ namespace Platformer.Mechanics
// 동반 컴포넌트 자동 부착 (Inspector 부착 불요)
if (GetComponent() == null) gameObject.AddComponent();
if (GetComponent() == null) gameObject.AddComponent();
- // 구 PlatformDropThrough 컴포넌트 자동 제거 (Drop-Through는 ContactFilter mask 동적 갱신으로 처리)
- var oldDrop = GetComponent();
- if (oldDrop != null) Destroy(oldDrop);
// 사망 시 입력 차단 / 부활 시 입력 복원
if (health != null)