diff --git a/Assets/Prefabs/Enemy.prefab b/Assets/Prefabs/Enemy.prefab index f47b89a..3c70ad8 100644 --- a/Assets/Prefabs/Enemy.prefab +++ b/Assets/Prefabs/Enemy.prefab @@ -31,16 +31,17 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1661912868639658944} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 5.508, y: 1.032, z: 1} + m_LocalPosition: {x: 5.508, y: 1.532, z: 1} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!212 &1577774018119691272 SpriteRenderer: + serializedVersion: 2 m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -56,6 +57,11 @@ SpriteRenderer: m_ReflectionProbeUsage: 0 m_RayTracingMode: 0 m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -77,10 +83,13 @@ SpriteRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 m_SortingLayerID: 1907945055 m_SortingLayer: 0 m_SortingOrder: 5 - m_Sprite: {fileID: -7548370174848201806, guid: f7b7e5d5d35e8ea4a9574fc970089486, type: 3} + m_MaskInteraction: 0 + m_Sprite: {fileID: -7548370174848201806, guid: f7b7e5d5d35e8ea4a9574fc970089486, + type: 3} m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 m_FlipY: 0 @@ -89,11 +98,10 @@ SpriteRenderer: m_AdaptiveModeThreshold: 0.5 m_SpriteTileMode: 0 m_WasSpriteAssigned: 1 - m_MaskInteraction: 0 m_SpriteSortPoint: 0 --- !u!95 &1605217082131907960 Animator: - serializedVersion: 4 + serializedVersion: 7 m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -107,13 +115,15 @@ Animator: m_ApplyRootMotion: 0 m_LinearVelocityBlending: 0 m_StabilizeFeet: 0 + m_AnimatePhysics: 0 m_WarningMessage: m_HasTransformHierarchy: 1 m_AllowConstantClipSamplingOptimization: 1 - m_KeepAnimatorControllerStateOnDisable: 0 + m_KeepAnimatorStateOnDisable: 0 + m_WriteDefaultValuesOnDisable: 0 --- !u!50 &1702612949800919892 Rigidbody2D: - serializedVersion: 4 + serializedVersion: 5 m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -124,10 +134,16 @@ Rigidbody2D: m_UseFullKinematicContacts: 1 m_UseAutoMass: 0 m_Mass: 1 - m_LinearDrag: 0 - m_AngularDrag: 0.05 + m_LinearDamping: 0 + m_AngularDamping: 0.05 m_GravityScale: 1 m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 m_Interpolate: 1 m_SleepingMode: 0 m_CollisionDetection: 1 @@ -140,13 +156,34 @@ CapsuleCollider2D: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1661912868639658944} m_Enabled: 1 + serializedVersion: 3 m_Density: 1 m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 m_IsTrigger: 0 m_UsedByEffector: 0 - m_UsedByComposite: 0 - m_Offset: {x: 0, y: -0.11} - m_Size: {x: 0.45, y: 0.09} + m_CompositeOperation: 0 + m_CompositeOrder: 0 + m_Offset: {x: -0.11551046, y: -0.094290674} + m_Size: {x: 0.5664339, y: 0.59230876} m_Direction: 0 --- !u!114 &2651140156555518892 MonoBehaviour: @@ -182,6 +219,9 @@ MonoBehaviour: m_EditorClassIdentifier: path: {fileID: 0} ouch: {fileID: 8300000, guid: b7f741588644cd64bbee6387cb54a96d, type: 3} + hitRangeX: 0.7 + hitRangeY: 1 + stompMinDy: 0.1 --- !u!82 &5843668731025413174 AudioSource: m_ObjectHideFlags: 0 @@ -193,6 +233,7 @@ AudioSource: serializedVersion: 4 OutputAudioMixerGroup: {fileID: 0} m_audioClip: {fileID: 0} + m_Resource: {fileID: 0} m_PlayOnAwake: 0 m_Volume: 1 m_Pitch: 1 @@ -288,6 +329,10 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: ffad43bb006db4856a9c527b89b48db9, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: + maxHearts: 1 maxHP: 1 + invulnerableDuration: 0.5 + resurrectInvulnerableDuration: 2 + canResurrect: 0 diff --git a/Assets/Scenes/Ingame.unity b/Assets/Scenes/Ingame.unity index 5c70ede..4e47a17 100644 --- a/Assets/Scenes/Ingame.unity +++ b/Assets/Scenes/Ingame.unity @@ -4142,7 +4142,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -6.9554644 + value: -6.4554644 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -5203,7 +5203,7 @@ PrefabInstance: - target: {fileID: 5102505034379151491, guid: 6f545478bd0fb7a478ed6f674a5210f5, type: 3} propertyPath: m_LocalPosition.y - value: -1.2901306 + value: -0.7901306 objectReference: {fileID: 0} - target: {fileID: 5102505034379151491, guid: 6f545478bd0fb7a478ed6f674a5210f5, type: 3} @@ -13067,7 +13067,7 @@ PrefabInstance: - target: {fileID: 4009130065698333725, guid: 9a1bd12ebb35d4dc997aa0c5494eda9b, type: 3} propertyPath: m_LocalPosition.y - value: 0 + value: 0.5000000 objectReference: {fileID: 0} - target: {fileID: 4009130065698333725, guid: 9a1bd12ebb35d4dc997aa0c5494eda9b, type: 3} @@ -16838,7 +16838,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -3.8154645 + value: -3.3154645 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -118941,7 +118941,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: 1.3445356 + value: 1.8445356 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -121349,7 +121349,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -6.9554644 + value: -6.4554644 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -125071,7 +125071,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -1.4454646 + value: -0.9454646 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -125506,7 +125506,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -5.4154644 + value: -4.9154644 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -125864,7 +125864,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 4520396350849616, guid: 7d60c822c3f1b408ea7a00ecdb5e047a, type: 3} propertyPath: m_LocalPosition.y - value: 0 + value: 0.5000000 objectReference: {fileID: 0} - target: {fileID: 4520396350849616, guid: 7d60c822c3f1b408ea7a00ecdb5e047a, type: 3} propertyPath: m_LocalPosition.z @@ -133748,7 +133748,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: 3.8145354 + value: 4.3145354 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -137743,7 +137743,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -1.8354645 + value: -1.3354645 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -137836,7 +137836,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -6.9954643 + value: -6.4954643 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -140571,7 +140571,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -4.965464 + value: -4.4654640 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -296270,7 +296270,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -6.2054644 + value: -5.7054644 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -297389,7 +297389,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -5.345464 + value: -4.8454640 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -311611,7 +311611,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -0.6254645 + value: -0.1254645 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -314947,7 +314947,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -1.7554646 + value: -1.2554646 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -317850,7 +317850,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -5.4154644 + value: -4.9154644 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} @@ -320806,7 +320806,7 @@ PrefabInstance: - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} propertyPath: m_LocalPosition.y - value: -0.41546452 + value: 0.0845355 objectReference: {fileID: 0} - target: {fileID: 1658460978237467174, guid: f158aa2be3df6489185ef721f6fd79c1, type: 3} diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs index a6d5b21..942f57b 100644 --- a/Assets/Scripts/Mechanics/EnemyController.cs +++ b/Assets/Scripts/Mechanics/EnemyController.cs @@ -12,7 +12,7 @@ namespace Platformer.Mechanics [RequireComponent(typeof(AnimationController), typeof(Collider2D))] public class EnemyController : MonoBehaviour { - public PatrolPath path; + public PatrolPath path; // legacy 호환·자동 patrol 영역 도입 후 미사용 public AudioClip ouch; /// BT5-Dev #16 — Distance 기반 감지 영역 X 임계값 (전체 폭). 표준 platformer Enemy 옆 닿음 영역 0.6~0.8. @@ -22,7 +22,19 @@ namespace Platformer.Mechanics /// 밟기 판정 — Player가 Enemy보다 위 거리. 발 닿는 느낌 영역(0.05~0.15). public float stompMinDy = 0.1f; - internal PatrolPath.Mover mover; + // PD 명시 2026-05-08 — 자동 patrol (생성 위치 기준 좌/우 random 100~150 왕복) + public float patrolMinRange = 100f; + public float patrolMaxRange = 150f; + public float patrolArriveThreshold = 0.5f; + public float cliffCheckDistance = 0.6f; // 발 앞 절벽 검출 거리 + public float cliffCheckDepth = 0.8f; // 발 아래 Raycast 거리 + public LayerMask groundLayerMask = ~0; // 절벽 검출용 ground layer (default = 모든 layer) + + private float _startX; + private float _targetX; + private int _patrolPhase; // 0: right out / 1: right back / 2: left out / 3: left back + + internal PatrolPath.Mover mover; // legacy 호환·미사용 internal AnimationController control; internal Collider2D _collider; internal AudioSource _audio; @@ -63,18 +75,58 @@ namespace Platformer.Mechanics } } - // BT5-Dev #17 marker — 본 영역 출력 시 새 코드 영역 적용 정합. 출력 X = Editor Asset Refresh 영역 미수행 - Debug.Log($"[BT17-MARKER@{name}] sr={(spriteRenderer != null ? "OK" : "NULL")} hitX={hitRangeX} hitY={hitRangeY} stomp={stompMinDy} | colB={_collider?.bounds.size} vB={VisualBounds.size}"); + // PD 명시 2026-05-08 — 자동 patrol 시작 위치 저장 + 첫 목표 설정 + _startX = transform.position.x; + _patrolPhase = 0; + SetNextPatrolTarget(); + } + + void SetNextPatrolTarget() + { + float range = Random.Range(patrolMinRange, patrolMaxRange); + switch (_patrolPhase) + { + case 0: _targetX = _startX + range; break; // 우측 random 이동 + case 1: _targetX = _startX; break; // 시작 위치 복귀 + case 2: _targetX = _startX - range; break; // 좌측 random 이동 + case 3: _targetX = _startX; break; // 시작 위치 복귀 + } } void Update() { - if (path != null) + // PD 명시 2026-05-08 — PatrolPath 영역 폐기·자동 patrol (생성 위치 기준 좌/우 random 100~150 왕복) + 절벽 검출 + float dx = _targetX - transform.position.x; + + if (Mathf.Abs(dx) < patrolArriveThreshold) { - if (mover == null) mover = path.CreateMover(control.maxSpeed * 0.5f); - control.move.x = Mathf.Clamp(mover.Position.x - transform.position.x, -1, 1); + _patrolPhase = (_patrolPhase + 1) % 4; + SetNextPatrolTarget(); + dx = _targetX - transform.position.x; } + float moveDir = Mathf.Sign(dx); + + // 절벽 검출 — 발 앞 영역 Raycast 지면 X 시 시작 위치로 즉시 복귀 + if (Mathf.Abs(dx) > patrolArriveThreshold && _collider != null) + { + Vector2 footAhead = new Vector2( + _collider.bounds.center.x + moveDir * cliffCheckDistance, + _collider.bounds.min.y + 0.05f + ); + RaycastHit2D groundHit = Physics2D.Raycast(footAhead, Vector2.down, cliffCheckDepth, groundLayerMask); + if (groundHit.collider == null) + { + // 절벽 영역 → 시작 위치 즉시 복귀 (반대 방향 phase 강제) + _patrolPhase = (_patrolPhase % 2 == 0) ? _patrolPhase + 1 : _patrolPhase; + _targetX = _startX; + dx = _targetX - transform.position.x; + moveDir = Mathf.Sign(dx); + } + } + + control.move.x = Mathf.Clamp(dx, -1, 1); + // PD 지시 2026-05-07 — Player ↔ Enemy 통과 가능이지만 Bounds.Intersects로 매 프레임 감지 if (_cachedPlayer == null) {