From 9b1709b92ced0a4c580b8c29c8ec34b8fb0439cd Mon Sep 17 00:00:00 2001 From: fiore Date: Fri, 25 Apr 2025 15:17:27 +0900 Subject: [PATCH 1/4] =?UTF-8?q?DEG-95=20=EC=9B=90=EA=B1=B0=EB=A6=AC=20?= =?UTF-8?q?=EB=A7=88=EB=B2=95=EC=82=AC=20=EB=B3=B4=EC=8A=A4=20=ED=8C=A8?= =?UTF-8?q?=ED=84=B4=20=EC=84=A4=EA=B3=84=20=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 근접 몬스터 전투 패턴 리팩토링 - 전략 패턴과 템플릿 메서드 패턴을 조합 --- Assets/Editor/EnemyControllerEditor.cs | 7 -- Assets/JYY/Animator/Dummy Monster.controller | 3 + .../Animator/Dummy Monster.controller.meta | 8 +++ .../Dummy.meta} | 5 +- Assets/JYY/Materials/Dummy/Dummy Monster.mat | 3 + .../Materials/Dummy/Dummy Monster.mat.meta | 8 +++ Assets/JYY/Materials/Dummy/Dummy Player.mat | 3 + .../JYY/Materials/Dummy/Dummy Player.mat.meta | 8 +++ Assets/JYY/Prefabs/AoE Indicator.meta | 8 +++ .../AOEIndicatorDynamo.prefab | 0 .../AOEIndicatorDynamo.prefab.meta | 0 .../AOEIndicatorHorizontal.prefab | 0 .../AOEIndicatorHorizontal.prefab.meta | 0 .../AOEIndicatorVertical.prefab | 0 .../AOEIndicatorVertical.prefab.meta | 0 .../AoE Indicator Chariot.prefab | 0 .../AoE Indicator Chariot.prefab.meta | 0 .../AoE Indicator Horizontal.prefab | 0 .../AoE Indicator Horizontal.prefab.meta | 0 .../AoE Indicator Vertical.prefab | 0 .../AoE Indicator Vertical.prefab.meta | 0 .../JYY/Prefabs/AoE Slash Blue Chariot.prefab | 3 - Assets/JYY/Prefabs/[Enemy] PldDog.prefab | 4 +- Assets/JYY/Scenes/MonsterTest.unity | 4 +- .../Character/Enemy/CasterDemonController.cs | 8 +++ .../Enemy/CasterDemonController.cs.meta | 11 ++++ .../Character/Enemy/EnemyController.cs | 65 +++++++++++++++---- .../Character/Enemy/EnemyState/Caster.meta | 3 + .../Enemy/EnemyState/Caster/EnemyStateFlee.cs | 52 +++++++++++++++ .../EnemyState/Caster/EnemyStateFlee.cs.meta | 3 + .../Character/Enemy/EnemyState/Commons.meta | 3 + .../{ => Commons}/EnemyStateDead.cs | 0 .../{ => Commons}/EnemyStateDead.cs.meta | 0 .../{ => Commons}/EnemyStateIdle.cs | 16 ++++- .../{ => Commons}/EnemyStateIdle.cs.meta | 0 .../Enemy/EnemyState/EnemyStateAttack.cs | 24 ------- .../Enemy/EnemyState/EnemyStateAttack.cs.meta | 3 - .../Character/Enemy/EnemyState/Melee.meta | 3 + .../EnemyState/{ => Melee}/EnemyStateTrace.cs | 7 +- .../{ => Melee}/EnemyStateTrace.cs.meta | 0 .../Character/Enemy/PldDogController.cs | 19 +++--- 41 files changed, 207 insertions(+), 74 deletions(-) create mode 100644 Assets/JYY/Animator/Dummy Monster.controller create mode 100644 Assets/JYY/Animator/Dummy Monster.controller.meta rename Assets/JYY/{Prefabs/AoE Slash Blue Chariot.prefab.meta => Materials/Dummy.meta} (57%) create mode 100644 Assets/JYY/Materials/Dummy/Dummy Monster.mat create mode 100644 Assets/JYY/Materials/Dummy/Dummy Monster.mat.meta create mode 100644 Assets/JYY/Materials/Dummy/Dummy Player.mat create mode 100644 Assets/JYY/Materials/Dummy/Dummy Player.mat.meta create mode 100644 Assets/JYY/Prefabs/AoE Indicator.meta rename Assets/JYY/Prefabs/{ => AoE Indicator}/AOEIndicatorDynamo.prefab (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AOEIndicatorDynamo.prefab.meta (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AOEIndicatorHorizontal.prefab (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AOEIndicatorHorizontal.prefab.meta (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AOEIndicatorVertical.prefab (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AOEIndicatorVertical.prefab.meta (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AoE Indicator Chariot.prefab (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AoE Indicator Chariot.prefab.meta (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AoE Indicator Horizontal.prefab (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AoE Indicator Horizontal.prefab.meta (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AoE Indicator Vertical.prefab (100%) rename Assets/JYY/Prefabs/{ => AoE Indicator}/AoE Indicator Vertical.prefab.meta (100%) delete mode 100644 Assets/JYY/Prefabs/AoE Slash Blue Chariot.prefab create mode 100644 Assets/Scripts/Character/Enemy/CasterDemonController.cs create mode 100644 Assets/Scripts/Character/Enemy/CasterDemonController.cs.meta create mode 100644 Assets/Scripts/Character/Enemy/EnemyState/Caster.meta create mode 100644 Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs create mode 100644 Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs.meta create mode 100644 Assets/Scripts/Character/Enemy/EnemyState/Commons.meta rename Assets/Scripts/Character/Enemy/EnemyState/{ => Commons}/EnemyStateDead.cs (100%) rename Assets/Scripts/Character/Enemy/EnemyState/{ => Commons}/EnemyStateDead.cs.meta (100%) rename Assets/Scripts/Character/Enemy/EnemyState/{ => Commons}/EnemyStateIdle.cs (58%) rename Assets/Scripts/Character/Enemy/EnemyState/{ => Commons}/EnemyStateIdle.cs.meta (100%) delete mode 100644 Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs delete mode 100644 Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs.meta create mode 100644 Assets/Scripts/Character/Enemy/EnemyState/Melee.meta rename Assets/Scripts/Character/Enemy/EnemyState/{ => Melee}/EnemyStateTrace.cs (93%) rename Assets/Scripts/Character/Enemy/EnemyState/{ => Melee}/EnemyStateTrace.cs.meta (100%) diff --git a/Assets/Editor/EnemyControllerEditor.cs b/Assets/Editor/EnemyControllerEditor.cs index 82dc98de..a6cb20f2 100644 --- a/Assets/Editor/EnemyControllerEditor.cs +++ b/Assets/Editor/EnemyControllerEditor.cs @@ -27,9 +27,6 @@ public class EnemyControllerEditor : Editor case EnemyState.Trace: GUI.backgroundColor = new Color(1, 0, 1, 1f); break; - case EnemyState.Attack: - GUI.backgroundColor = new Color(1, 1, 0, 1f); - break; case EnemyState.Dead: GUI.backgroundColor = new Color(1, 0, 0, 1f); break; @@ -49,10 +46,6 @@ public class EnemyControllerEditor : Editor EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Idle")) enemyController.SetState(EnemyState.Idle); if (GUILayout.Button("Trace")) enemyController.SetState(EnemyState.Trace); - EditorGUILayout.EndHorizontal(); - - EditorGUILayout.BeginHorizontal(); - if (GUILayout.Button("Attack")) enemyController.SetState(EnemyState.Attack); if (GUILayout.Button("Dead")) enemyController.SetState(EnemyState.Dead); EditorGUILayout.EndHorizontal(); } diff --git a/Assets/JYY/Animator/Dummy Monster.controller b/Assets/JYY/Animator/Dummy Monster.controller new file mode 100644 index 00000000..de7d8664 --- /dev/null +++ b/Assets/JYY/Animator/Dummy Monster.controller @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ca1c24b27ef486457ebafc23ce2f6ed321451f9aa9d234bb264466b3f12f15b +size 1347 diff --git a/Assets/JYY/Animator/Dummy Monster.controller.meta b/Assets/JYY/Animator/Dummy Monster.controller.meta new file mode 100644 index 00000000..7e707a03 --- /dev/null +++ b/Assets/JYY/Animator/Dummy Monster.controller.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cb4d2ce283530414f92984caccad61a0 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 9100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Prefabs/AoE Slash Blue Chariot.prefab.meta b/Assets/JYY/Materials/Dummy.meta similarity index 57% rename from Assets/JYY/Prefabs/AoE Slash Blue Chariot.prefab.meta rename to Assets/JYY/Materials/Dummy.meta index 5ba3ecc5..90a6eb10 100644 --- a/Assets/JYY/Prefabs/AoE Slash Blue Chariot.prefab.meta +++ b/Assets/JYY/Materials/Dummy.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 -guid: 3f431e991bd65014c833e89305ddd5e3 -PrefabImporter: +guid: 81ad24bdbd6cad44990b4f077f0687e7 +folderAsset: yes +DefaultImporter: externalObjects: {} userData: assetBundleName: diff --git a/Assets/JYY/Materials/Dummy/Dummy Monster.mat b/Assets/JYY/Materials/Dummy/Dummy Monster.mat new file mode 100644 index 00000000..bcf5ec30 --- /dev/null +++ b/Assets/JYY/Materials/Dummy/Dummy Monster.mat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84566d1cced96b3b39f9d3f479b93cba504318e15dccc44e97a8e742ed9aadac +size 3661 diff --git a/Assets/JYY/Materials/Dummy/Dummy Monster.mat.meta b/Assets/JYY/Materials/Dummy/Dummy Monster.mat.meta new file mode 100644 index 00000000..c8b7fb71 --- /dev/null +++ b/Assets/JYY/Materials/Dummy/Dummy Monster.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9a8690b5dbb7c5643896a7d881a8fd6f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Materials/Dummy/Dummy Player.mat b/Assets/JYY/Materials/Dummy/Dummy Player.mat new file mode 100644 index 00000000..e2b75a45 --- /dev/null +++ b/Assets/JYY/Materials/Dummy/Dummy Player.mat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18bf8ebd5397569f2261bb288c087b0c9dd7e0c9c4edcd4ef7e97a38ed2a002d +size 6700 diff --git a/Assets/JYY/Materials/Dummy/Dummy Player.mat.meta b/Assets/JYY/Materials/Dummy/Dummy Player.mat.meta new file mode 100644 index 00000000..8db50417 --- /dev/null +++ b/Assets/JYY/Materials/Dummy/Dummy Player.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc5cecc864a5b0c49b266cec5aaec666 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Prefabs/AoE Indicator.meta b/Assets/JYY/Prefabs/AoE Indicator.meta new file mode 100644 index 00000000..6f952565 --- /dev/null +++ b/Assets/JYY/Prefabs/AoE Indicator.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2dbfaa22c1aa28242a4e80ed518bfae2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Prefabs/AOEIndicatorDynamo.prefab b/Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorDynamo.prefab similarity index 100% rename from Assets/JYY/Prefabs/AOEIndicatorDynamo.prefab rename to Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorDynamo.prefab diff --git a/Assets/JYY/Prefabs/AOEIndicatorDynamo.prefab.meta b/Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorDynamo.prefab.meta similarity index 100% rename from Assets/JYY/Prefabs/AOEIndicatorDynamo.prefab.meta rename to Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorDynamo.prefab.meta diff --git a/Assets/JYY/Prefabs/AOEIndicatorHorizontal.prefab b/Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorHorizontal.prefab similarity index 100% rename from Assets/JYY/Prefabs/AOEIndicatorHorizontal.prefab rename to Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorHorizontal.prefab diff --git a/Assets/JYY/Prefabs/AOEIndicatorHorizontal.prefab.meta b/Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorHorizontal.prefab.meta similarity index 100% rename from Assets/JYY/Prefabs/AOEIndicatorHorizontal.prefab.meta rename to Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorHorizontal.prefab.meta diff --git a/Assets/JYY/Prefabs/AOEIndicatorVertical.prefab b/Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorVertical.prefab similarity index 100% rename from Assets/JYY/Prefabs/AOEIndicatorVertical.prefab rename to Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorVertical.prefab diff --git a/Assets/JYY/Prefabs/AOEIndicatorVertical.prefab.meta b/Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorVertical.prefab.meta similarity index 100% rename from Assets/JYY/Prefabs/AOEIndicatorVertical.prefab.meta rename to Assets/JYY/Prefabs/AoE Indicator/AOEIndicatorVertical.prefab.meta diff --git a/Assets/JYY/Prefabs/AoE Indicator Chariot.prefab b/Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Chariot.prefab similarity index 100% rename from Assets/JYY/Prefabs/AoE Indicator Chariot.prefab rename to Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Chariot.prefab diff --git a/Assets/JYY/Prefabs/AoE Indicator Chariot.prefab.meta b/Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Chariot.prefab.meta similarity index 100% rename from Assets/JYY/Prefabs/AoE Indicator Chariot.prefab.meta rename to Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Chariot.prefab.meta diff --git a/Assets/JYY/Prefabs/AoE Indicator Horizontal.prefab b/Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Horizontal.prefab similarity index 100% rename from Assets/JYY/Prefabs/AoE Indicator Horizontal.prefab rename to Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Horizontal.prefab diff --git a/Assets/JYY/Prefabs/AoE Indicator Horizontal.prefab.meta b/Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Horizontal.prefab.meta similarity index 100% rename from Assets/JYY/Prefabs/AoE Indicator Horizontal.prefab.meta rename to Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Horizontal.prefab.meta diff --git a/Assets/JYY/Prefabs/AoE Indicator Vertical.prefab b/Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Vertical.prefab similarity index 100% rename from Assets/JYY/Prefabs/AoE Indicator Vertical.prefab rename to Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Vertical.prefab diff --git a/Assets/JYY/Prefabs/AoE Indicator Vertical.prefab.meta b/Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Vertical.prefab.meta similarity index 100% rename from Assets/JYY/Prefabs/AoE Indicator Vertical.prefab.meta rename to Assets/JYY/Prefabs/AoE Indicator/AoE Indicator Vertical.prefab.meta diff --git a/Assets/JYY/Prefabs/AoE Slash Blue Chariot.prefab b/Assets/JYY/Prefabs/AoE Slash Blue Chariot.prefab deleted file mode 100644 index 995bcd81..00000000 --- a/Assets/JYY/Prefabs/AoE Slash Blue Chariot.prefab +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d42386e12ec2eec2385f13fdcd2558718c9150245a834d5a667060f750b1ced -size 3100 diff --git a/Assets/JYY/Prefabs/[Enemy] PldDog.prefab b/Assets/JYY/Prefabs/[Enemy] PldDog.prefab index 8b998d43..9eb356ef 100644 --- a/Assets/JYY/Prefabs/[Enemy] PldDog.prefab +++ b/Assets/JYY/Prefabs/[Enemy] PldDog.prefab @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4cedd199100ba2d66a0dfe22b6ab902677fcc6485b02d0553115d0e012b3c97 -size 79510 +oid sha256:fa57e55a6b7dc452a770a0a0ddb528ffa765818ec608bcb60f14e4e984a18e59 +size 79971 diff --git a/Assets/JYY/Scenes/MonsterTest.unity b/Assets/JYY/Scenes/MonsterTest.unity index f315080d..d772a68e 100644 --- a/Assets/JYY/Scenes/MonsterTest.unity +++ b/Assets/JYY/Scenes/MonsterTest.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70e2e15667c9821fdb140d6ca8987d4caf3436e36abc139ba9da1192a5428331 -size 21018 +oid sha256:efc792ecb073a66263abf936bd751584b41224bde07c7f02418d10223d0c07f4 +size 22331 diff --git a/Assets/Scripts/Character/Enemy/CasterDemonController.cs b/Assets/Scripts/Character/Enemy/CasterDemonController.cs new file mode 100644 index 00000000..190de9ad --- /dev/null +++ b/Assets/Scripts/Character/Enemy/CasterDemonController.cs @@ -0,0 +1,8 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class CasterDemonController : EnemyController +{ + +} diff --git a/Assets/Scripts/Character/Enemy/CasterDemonController.cs.meta b/Assets/Scripts/Character/Enemy/CasterDemonController.cs.meta new file mode 100644 index 00000000..88b08083 --- /dev/null +++ b/Assets/Scripts/Character/Enemy/CasterDemonController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 79bc1ad21773bcf4e982d5fc7a93887b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Character/Enemy/EnemyController.cs b/Assets/Scripts/Character/Enemy/EnemyController.cs index 07f72e13..64002b75 100644 --- a/Assets/Scripts/Character/Enemy/EnemyController.cs +++ b/Assets/Scripts/Character/Enemy/EnemyController.cs @@ -1,8 +1,10 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; -public enum EnemyState { None, Idle, Trace, Attack, Dead } +public enum EnemyState { None, Idle, Trace, Dead, Flee} +public enum MonsterType { Melee, Caster, Ranged } [RequireComponent(typeof(NavMeshAgent))] [RequireComponent(typeof(Animator))] @@ -11,10 +13,12 @@ public abstract class EnemyController : CharacterBase [Header("AI")] [SerializeField] private float detectCircleRadius = 10f; // 플레이어 탐지 범위 [SerializeField] private LayerMask targetLayerMask; // 플레이어 레이어 마스크 + [SerializeField] private MonsterType monsterType; + public MonsterType MonsterType => monsterType; public Transform TraceTargetTransform { get; private set; } public NavMeshAgent Agent { get; private set; } - public Animator EnemyAnimator { get; private set; } + private Animator EnemyAnimator { get; set; } public EnemyState CurrentState {get; private set;} public LayerMask TargetLayerMask => targetLayerMask; public float MoveSpeed => moveSpeed; @@ -31,10 +35,14 @@ public abstract class EnemyController : CharacterBase // ----- // 상태 변수 + // Commons private EnemyStateIdle _enemyStateIdle; - private EnemyStateTrace _enemyStateTrace; - private EnemyStateAttack _enemyStateAttack; private EnemyStateDead _enemyStateDead; + // Melee + private EnemyStateTrace _enemyStateTrace; + // Caster + private EnemyStateFlee _enemyStateFlee; + private Dictionary _enemyStates; @@ -49,18 +57,36 @@ public abstract class EnemyController : CharacterBase base.Start(); // 상태 객체 생성 + // Commons _enemyStateIdle = new EnemyStateIdle(); - _enemyStateTrace = new EnemyStateTrace(); - _enemyStateAttack = new EnemyStateAttack(); _enemyStateDead = new EnemyStateDead(); + // Melee + _enemyStateTrace = new EnemyStateTrace(); + // Caster + _enemyStateFlee = new EnemyStateFlee(); - _enemyStates = new Dictionary + switch (MonsterType) { - { EnemyState.Idle, _enemyStateIdle }, - { EnemyState.Trace, _enemyStateTrace }, - { EnemyState.Attack, _enemyStateAttack }, - { EnemyState.Dead, _enemyStateDead }, - }; + case MonsterType.Melee: + _enemyStates = new Dictionary + { + { EnemyState.Idle, _enemyStateIdle }, + { EnemyState.Trace, _enemyStateTrace }, + { EnemyState.Dead, _enemyStateDead }, + }; + break; + case MonsterType.Caster: + _enemyStates = new Dictionary + { + { EnemyState.Idle, _enemyStateIdle }, + { EnemyState.Flee, _enemyStateFlee }, + { EnemyState.Dead, _enemyStateDead }, + }; + break; + case MonsterType.Ranged: + break; + } + SetState(EnemyState.Idle); } @@ -84,6 +110,13 @@ public abstract class EnemyController : CharacterBase } + // 전략 패턴과 템플릿 메서드 패턴을 활용 + public virtual void BattleSequence() + { + // 이 메서드는 자식 요소에서 오버라이드하여 구현합니다. + Debug.LogWarning("BattleSequence가 구현되지 않았습니다."); + } + public override void Die() { base.Die(); @@ -106,6 +139,12 @@ public abstract class EnemyController : CharacterBase return null; } + private void OnDrawGizmos() + { + Gizmos.color = Color.red; + Gizmos.DrawWireSphere(transform.position, detectCircleRadius); + } + #endregion #region 애니메이션 제어 diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Caster.meta b/Assets/Scripts/Character/Enemy/EnemyState/Caster.meta new file mode 100644 index 00000000..9a5dd5bc --- /dev/null +++ b/Assets/Scripts/Character/Enemy/EnemyState/Caster.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 06fb9eac62a34336b6023cc088be367d +timeCreated: 1745554862 \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs new file mode 100644 index 00000000..47d7c03f --- /dev/null +++ b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs @@ -0,0 +1,52 @@ +using UnityEngine; + +public class EnemyStateFlee :IEnemyState +{ + private EnemyController _enemyController; + private Transform _detectPlayerTransform; + + private const float MaxDetectPlayerInCircleWaitTime = 0.2f; + private float _detectPlayerInCircleWaitTime = 0f; + + private float _fleeDistance = 5f; // 도망치는 거리 + private float _attackRange = 7f; // 공격 범위 + + public void Enter(EnemyController enemyController) + { + _enemyController = enemyController; + Debug.Log("## Flee 상태 진입"); + + _detectPlayerTransform = _enemyController.TraceTargetTransform; + if (!_detectPlayerTransform) + { + _enemyController.SetState(EnemyState.Idle); + return; + } + } + + public void Update() + { + // 도망치는 방향 계산 + Vector3 fleeDirection = (_enemyController.transform.position - _detectPlayerTransform.position).normalized; + Vector3 fleeTarget = _enemyController.transform.position + fleeDirection * _fleeDistance; + + _enemyController.Agent.SetDestination(fleeTarget); + + float distance = Vector3.Distance(_enemyController.transform.position, _detectPlayerTransform.position); + + // 일정 범위 안으로 플레이어가 접근하면 공격 시퀸스 + if (distance <= _attackRange) + { + + return; + } + + + } + + public void Exit() + { + _detectPlayerTransform = null; + _enemyController = null; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs.meta b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs.meta new file mode 100644 index 00000000..9f798685 --- /dev/null +++ b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 52fff5e2310f42608e3e3c5b45dcae38 +timeCreated: 1745554266 \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Commons.meta b/Assets/Scripts/Character/Enemy/EnemyState/Commons.meta new file mode 100644 index 00000000..d4b32419 --- /dev/null +++ b/Assets/Scripts/Character/Enemy/EnemyState/Commons.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 452917766030468e87209330ca1b410e +timeCreated: 1745554696 \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateDead.cs b/Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateDead.cs similarity index 100% rename from Assets/Scripts/Character/Enemy/EnemyState/EnemyStateDead.cs rename to Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateDead.cs diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateDead.cs.meta b/Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateDead.cs.meta similarity index 100% rename from Assets/Scripts/Character/Enemy/EnemyState/EnemyStateDead.cs.meta rename to Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateDead.cs.meta diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateIdle.cs b/Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateIdle.cs similarity index 58% rename from Assets/Scripts/Character/Enemy/EnemyState/EnemyStateIdle.cs rename to Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateIdle.cs index a0fbbc52..d23de9c8 100644 --- a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateIdle.cs +++ b/Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateIdle.cs @@ -1,8 +1,8 @@ -using UnityEngine; +using System; +using UnityEngine; public class EnemyStateIdle: IEnemyState { - private EnemyController _enemyController; public void Enter(EnemyController enemyController) @@ -17,7 +17,17 @@ public class EnemyStateIdle: IEnemyState var detectPlayerTransform = _enemyController.DetectPlayerInCircle(); if (detectPlayerTransform) { - _enemyController.SetState(EnemyState.Trace); + switch (_enemyController.MonsterType) + { + case MonsterType.Melee: + _enemyController.SetState(EnemyState.Trace); + break; + case MonsterType.Caster: + _enemyController.SetState(EnemyState.Flee); + break; + case MonsterType.Ranged: + break; + } } } diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateIdle.cs.meta b/Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateIdle.cs.meta similarity index 100% rename from Assets/Scripts/Character/Enemy/EnemyState/EnemyStateIdle.cs.meta rename to Assets/Scripts/Character/Enemy/EnemyState/Commons/EnemyStateIdle.cs.meta diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs b/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs deleted file mode 100644 index 194ce30c..00000000 --- a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -public class EnemyStateAttack : IEnemyState -{ - private EnemyController _enemyController; - - - public void Enter(EnemyController enemyController) - { - _enemyController = enemyController; - } - - public void Update() - { - - } - - public void Exit() - { - _enemyController = null; - } -} \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs.meta b/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs.meta deleted file mode 100644 index 6116ce6e..00000000 --- a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 29b87c92807e4f6b94c8a08ccc510321 -timeCreated: 1744799701 \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Melee.meta b/Assets/Scripts/Character/Enemy/EnemyState/Melee.meta new file mode 100644 index 00000000..0df3aa26 --- /dev/null +++ b/Assets/Scripts/Character/Enemy/EnemyState/Melee.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 64b8e3ece30b427eb71a9b6e33292292 +timeCreated: 1745554748 \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs b/Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs similarity index 93% rename from Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs rename to Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs index b301d19a..38bb4200 100644 --- a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs +++ b/Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs @@ -35,11 +35,8 @@ public class EnemyStateTrace : IEnemyState PlayerTracking(); - if (_enemyController.Agent.remainingDistance <= _enemyController.Agent.stoppingDistance) - { - // TODO: 타겟에 도착함 -> 공격 준비 - // _enemyController.SetState(EnemyState.Attack); - } + // 전투 패턴은 몬스터 객체에게 위임 + _enemyController.BattleSequence(); } public void Exit() diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs.meta b/Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs.meta similarity index 100% rename from Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs.meta rename to Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs.meta diff --git a/Assets/Scripts/Character/Enemy/PldDogController.cs b/Assets/Scripts/Character/Enemy/PldDogController.cs index 2655b9e8..aa1ac14a 100644 --- a/Assets/Scripts/Character/Enemy/PldDogController.cs +++ b/Assets/Scripts/Character/Enemy/PldDogController.cs @@ -8,6 +8,8 @@ using Random = UnityEngine.Random; public class PldDogController : EnemyController { + // ---- + // 팔라딘 독 고유 액션 private static readonly int WindUp = Animator.StringToHash("WindUp"); private static readonly int Slash = Animator.StringToHash("Slash"); private static readonly int BoomShot = Animator.StringToHash("BoomShot"); @@ -34,7 +36,7 @@ public class PldDogController : EnemyController [SerializeField] private GameObject horizontalWarning; [SerializeField] private GameObject horizontalSlash; - private float _patternTimer = 0f; + [SerializeField] private float _patternTimer = 0f; private int _currentPatternIndex = 0; private bool _isPatternRunning = false; private bool _isFirstAttack = true; @@ -53,23 +55,20 @@ public class PldDogController : EnemyController }; } - protected override void Update() + public override void BattleSequence() { - base.Update(); - - if (CurrentState != EnemyState.Trace || _isPatternRunning) - return; + _patternTimer += Time.deltaTime; + if (_isPatternRunning) return; float distanceToPlayer = Vector3.Distance(transform.position, TraceTargetTransform.position); if (distanceToPlayer <= meleeRange) // 근접 범위 { if (!Agent.isStopped) Agent.isStopped = true; - _patternTimer += Time.deltaTime; if (!_isPatternRunning && (_isFirstAttack || _patternTimer >= patternInterval)) { - ExecutePattern(_currentPatternIndex); + ExecutePattern(); _isFirstAttack = false; } @@ -78,16 +77,16 @@ public class PldDogController : EnemyController { if (Agent.isStopped) Agent.isStopped = false; Agent.SetDestination(TraceTargetTransform.position); - _patternTimer += Time.deltaTime; if (!_isPatternRunning && _patternTimer >= patternInterval) { + Debug.Log("## 폭탄 던질 조건 만족"); BombThrowPattern(); } } } - private void ExecutePattern(int patternIndex) + private void ExecutePattern() { _isPatternRunning = true; Agent.isStopped = true; From 39379da3009df615f21395a50dcd8ca0c362017a Mon Sep 17 00:00:00 2001 From: fiore Date: Fri, 25 Apr 2025 15:46:54 +0900 Subject: [PATCH 2/4] =?UTF-8?q?DEG-95=20[Fix]=20=ED=8C=94=EB=9D=BC?= =?UTF-8?q?=EB=94=98=20=EB=AA=AC=EC=8A=A4=ED=84=B0=20=ED=8F=AD=ED=83=84=20?= =?UTF-8?q?=EB=8D=98=EC=A7=80=EB=8A=94=20=EC=95=A0=EB=8B=88=EB=A9=94?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EB=88=84=EB=9D=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 공격 패턴 순차 실행 -> 랜덤 실행으로 변경 --- Assets/JYY/Animator/PldDogControl.controller | 4 ++-- Assets/JYY/Scenes/MonsterTest.unity | 2 +- Assets/Scripts/Character/Enemy/EnemyController.cs | 2 +- .../Enemy/EnemyState/Caster/EnemyStateFlee.cs | 11 ++--------- Assets/Scripts/Character/Enemy/PldDogController.cs | 14 +++++++++++--- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Assets/JYY/Animator/PldDogControl.controller b/Assets/JYY/Animator/PldDogControl.controller index 7b80e503..9a22018c 100644 --- a/Assets/JYY/Animator/PldDogControl.controller +++ b/Assets/JYY/Animator/PldDogControl.controller @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9473c357cb74d4228523205a76d0a1a1cc71d82baf736270906c82a171efe7e6 -size 16154 +oid sha256:7c8e0126546f60a0df64adf8fb366d479da5eb832ec0453ea51dfc7c731e2084 +size 17507 diff --git a/Assets/JYY/Scenes/MonsterTest.unity b/Assets/JYY/Scenes/MonsterTest.unity index d772a68e..e6211594 100644 --- a/Assets/JYY/Scenes/MonsterTest.unity +++ b/Assets/JYY/Scenes/MonsterTest.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:efc792ecb073a66263abf936bd751584b41224bde07c7f02418d10223d0c07f4 +oid sha256:1423d99c1df3a3bb884799cdc72b7eca0f11c1b831f7414e56921662d826d6f9 size 22331 diff --git a/Assets/Scripts/Character/Enemy/EnemyController.cs b/Assets/Scripts/Character/Enemy/EnemyController.cs index 64002b75..059a109d 100644 --- a/Assets/Scripts/Character/Enemy/EnemyController.cs +++ b/Assets/Scripts/Character/Enemy/EnemyController.cs @@ -114,7 +114,7 @@ public abstract class EnemyController : CharacterBase public virtual void BattleSequence() { // 이 메서드는 자식 요소에서 오버라이드하여 구현합니다. - Debug.LogWarning("BattleSequence가 구현되지 않았습니다."); + Debug.LogWarning("BattleSequence가 구현되지 않음 : " + "BattleSequence()를 오버라이드하여 구현하십시오."); } public override void Die() diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs index 47d7c03f..56718a5b 100644 --- a/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs +++ b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs @@ -26,7 +26,7 @@ public class EnemyStateFlee :IEnemyState public void Update() { - // 도망치는 방향 계산 + // 도망치는 방향 계산 Vector3 fleeDirection = (_enemyController.transform.position - _detectPlayerTransform.position).normalized; Vector3 fleeTarget = _enemyController.transform.position + fleeDirection * _fleeDistance; @@ -34,14 +34,7 @@ public class EnemyStateFlee :IEnemyState float distance = Vector3.Distance(_enemyController.transform.position, _detectPlayerTransform.position); - // 일정 범위 안으로 플레이어가 접근하면 공격 시퀸스 - if (distance <= _attackRange) - { - - return; - } - - + _enemyController.BattleSequence(); } public void Exit() diff --git a/Assets/Scripts/Character/Enemy/PldDogController.cs b/Assets/Scripts/Character/Enemy/PldDogController.cs index aa1ac14a..cc0887b0 100644 --- a/Assets/Scripts/Character/Enemy/PldDogController.cs +++ b/Assets/Scripts/Character/Enemy/PldDogController.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Serialization; @@ -37,7 +38,7 @@ public class PldDogController : EnemyController [SerializeField] private GameObject horizontalSlash; [SerializeField] private float _patternTimer = 0f; - private int _currentPatternIndex = 0; + private int _lastPatternIndex = -1; private bool _isPatternRunning = false; private bool _isFirstAttack = true; @@ -92,9 +93,16 @@ public class PldDogController : EnemyController Agent.isStopped = true; IsMeleeCombat = true; - _patternActions[_currentPatternIndex]?.Invoke(); + var available = Enumerable + .Range(0, _patternActions.Count) + .Where(i => i != _lastPatternIndex) + .ToList(); - _currentPatternIndex = (_currentPatternIndex + 1) % _patternActions.Count; // 패턴 순환 + int nextIndex = available[Random.Range(0, available.Count)]; + + _patternActions[nextIndex]?.Invoke(); + + _lastPatternIndex = nextIndex; } // 순환 패턴과 별개로 동작하는 특수 패턴 From 2bb71999b7a27619a290cd5931f5f6577005b165 Mon Sep 17 00:00:00 2001 From: fiore Date: Fri, 25 Apr 2025 17:05:20 +0900 Subject: [PATCH 3/4] =?UTF-8?q?DEG-95=20=EB=AA=AC=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EA=B0=80=20=EB=8F=84=EB=A7=9D=EC=B9=98=EB=8A=94=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 도망치는 애니메이션을 상태 스크립트에서 처리 - 전투 패턴은 몬스터 객체에게 위임 --- .../Character/Enemy/CasterDemonController.cs | 13 ++- .../Character/Enemy/EnemyController.cs | 13 ++- .../Enemy/EnemyState/Caster/EnemyStateFlee.cs | 98 +++++++++++++++---- .../Character/Enemy/PldDogController.cs | 2 +- 4 files changed, 106 insertions(+), 20 deletions(-) diff --git a/Assets/Scripts/Character/Enemy/CasterDemonController.cs b/Assets/Scripts/Character/Enemy/CasterDemonController.cs index 190de9ad..ad492597 100644 --- a/Assets/Scripts/Character/Enemy/CasterDemonController.cs +++ b/Assets/Scripts/Character/Enemy/CasterDemonController.cs @@ -4,5 +4,16 @@ using UnityEngine; public class CasterDemonController : EnemyController { - + + public override void BattleSequence() + { + // TODO : 배틀 중일 때 루프 + Debug.Log("## 몬스터의 교전 행동 루프"); + } + + + public override void OnCannotFleeBehaviour() + { + Debug.Log("## 몬스터가 막다른 길에 몰려 뭔가 함"); + } } diff --git a/Assets/Scripts/Character/Enemy/EnemyController.cs b/Assets/Scripts/Character/Enemy/EnemyController.cs index 059a109d..894c7334 100644 --- a/Assets/Scripts/Character/Enemy/EnemyController.cs +++ b/Assets/Scripts/Character/Enemy/EnemyController.cs @@ -110,13 +110,24 @@ public abstract class EnemyController : CharacterBase } + #region 몬스터의 행동 패턴 위임 + // 전략 패턴과 템플릿 메서드 패턴을 활용 public virtual void BattleSequence() { // 이 메서드는 자식 요소에서 오버라이드하여 구현합니다. - Debug.LogWarning("BattleSequence가 구현되지 않음 : " + "BattleSequence()를 오버라이드하여 구현하십시오."); + Debug.LogWarning("BattleSequence가 구현되지 않음 : BattleSequence()를 오버라이드하여 구현하십시오."); } + // 도망치며 싸우는 몬스터가 도망칠 곳이 없을때 취할 행동 + public virtual void OnCannotFleeBehaviour() + { + Debug.LogWarning("OnCannotFleeBehaviour가 구현되지 않음 : OnCannotFleeBehaviour() 오버라이드하여 구현하십시오."); + } + + #endregion + + public override void Die() { base.Die(); diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs index 56718a5b..9445ab69 100644 --- a/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs +++ b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs @@ -1,45 +1,109 @@ using UnityEngine; +using UnityEngine.AI; public class EnemyStateFlee :IEnemyState { private EnemyController _enemyController; - private Transform _detectPlayerTransform; - - private const float MaxDetectPlayerInCircleWaitTime = 0.2f; - private float _detectPlayerInCircleWaitTime = 0f; - + private Transform _playerTransform; private float _fleeDistance = 5f; // 도망치는 거리 private float _attackRange = 7f; // 공격 범위 + // 막다른길 검사용 + private Vector3 _lastPosition; + private float _stuckTimer = 0f; + private const float StuckThresholdTime = 1f; // 1초 동안 거의 못 움직이면 막힌 걸로 간주 + private const float StuckMoveThreshold = 0.1f; // 이내 이동은 “제자리”로 본다 + public void Enter(EnemyController enemyController) { _enemyController = enemyController; Debug.Log("## Flee 상태 진입"); - _detectPlayerTransform = _enemyController.TraceTargetTransform; - if (!_detectPlayerTransform) - { - _enemyController.SetState(EnemyState.Idle); - return; - } + _playerTransform = _enemyController.TraceTargetTransform; + _lastPosition = _enemyController.transform.position; + _stuckTimer = 0f; + + } public void Update() { - // 도망치는 방향 계산 - Vector3 fleeDirection = (_enemyController.transform.position - _detectPlayerTransform.position).normalized; + if (!_playerTransform) + { + _enemyController.SetState(EnemyState.Idle); + return; + } + + FindPositionFlee(); + + // 막힘 감지 (실제 이동 체크) + CheckPath(); + + _lastPosition = _enemyController.transform.position; + } + + private void CheckPath() + { + float distance = Vector3.Distance(_enemyController.transform.position, _playerTransform.position); + if (distance < StuckMoveThreshold) + { + _stuckTimer += Time.deltaTime; + if (_stuckTimer >= StuckThresholdTime) + { + // 막다른 길임 : 대체 행동 실행 + HandleDeadEnd(); + _stuckTimer = 0f; + } + } + else + { + // 정상적인 길: 배틀 루프 실행 + _enemyController.BattleSequence(); + _stuckTimer = 0f; + } + } + + private void FindPositionFlee() + { + // 1) 목표 도망 위치 계산 + Vector3 fleeDirection = (_enemyController.transform.position - _playerTransform.position).normalized; Vector3 fleeTarget = _enemyController.transform.position + fleeDirection * _fleeDistance; - _enemyController.Agent.SetDestination(fleeTarget); + // 2) 경로 계산해 보기 + NavMeshPath path = new NavMeshPath(); + _enemyController.Agent.CalculatePath(fleeTarget, path); - float distance = Vector3.Distance(_enemyController.transform.position, _detectPlayerTransform.position); + if (path.status == NavMeshPathStatus.PathComplete) + { + // 제대로 도망갈 수 있으면 목적지 설정 + _enemyController.Agent.SetDestination(fleeTarget); + } + else + { + // 막다른 길임 : 대체 행동 실행 + HandleDeadEnd(); + } + } - _enemyController.BattleSequence(); + private void HandleDeadEnd() + { + // 무작위 도망 지점 샘플링 시도 + Vector3 randomDirection = Random.insideUnitSphere * (_fleeDistance * 2); + randomDirection += _playerTransform.position; + + if (NavMesh.SamplePosition(randomDirection, out var hit, (_fleeDistance * 2), NavMesh.AllAreas)) + { + _enemyController.Agent.SetDestination(hit.position); + return; + } + + // 대체 경로도 찾을 수 없는 경우 + _enemyController.OnCannotFleeBehaviour(); } public void Exit() { - _detectPlayerTransform = null; + _playerTransform = null; _enemyController = null; } } \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/PldDogController.cs b/Assets/Scripts/Character/Enemy/PldDogController.cs index cc0887b0..c6cb613b 100644 --- a/Assets/Scripts/Character/Enemy/PldDogController.cs +++ b/Assets/Scripts/Character/Enemy/PldDogController.cs @@ -37,7 +37,7 @@ public class PldDogController : EnemyController [SerializeField] private GameObject horizontalWarning; [SerializeField] private GameObject horizontalSlash; - [SerializeField] private float _patternTimer = 0f; + private float _patternTimer = 0f; private int _lastPatternIndex = -1; private bool _isPatternRunning = false; private bool _isFirstAttack = true; From 544f0003f051abf10423e2fafc0e3acab539bd54 Mon Sep 17 00:00:00 2001 From: fiore Date: Sun, 27 Apr 2025 22:26:12 +0900 Subject: [PATCH 4/4] =?UTF-8?q?DEG-95=20=EC=BD=94=EB=93=9C=20=EB=8B=A4?= =?UTF-8?q?=EB=93=AC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/JYY/Scenes/MonsterTest.unity | 2 +- Assets/Scripts/Character/Enemy/EnemyController.cs | 6 ++---- .../Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Assets/JYY/Scenes/MonsterTest.unity b/Assets/JYY/Scenes/MonsterTest.unity index e6211594..d772a68e 100644 --- a/Assets/JYY/Scenes/MonsterTest.unity +++ b/Assets/JYY/Scenes/MonsterTest.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1423d99c1df3a3bb884799cdc72b7eca0f11c1b831f7414e56921662d826d6f9 +oid sha256:efc792ecb073a66263abf936bd751584b41224bde07c7f02418d10223d0c07f4 size 22331 diff --git a/Assets/Scripts/Character/Enemy/EnemyController.cs b/Assets/Scripts/Character/Enemy/EnemyController.cs index 894c7334..9883b5db 100644 --- a/Assets/Scripts/Character/Enemy/EnemyController.cs +++ b/Assets/Scripts/Character/Enemy/EnemyController.cs @@ -60,14 +60,11 @@ public abstract class EnemyController : CharacterBase // Commons _enemyStateIdle = new EnemyStateIdle(); _enemyStateDead = new EnemyStateDead(); - // Melee - _enemyStateTrace = new EnemyStateTrace(); - // Caster - _enemyStateFlee = new EnemyStateFlee(); switch (MonsterType) { case MonsterType.Melee: + _enemyStateTrace = new EnemyStateTrace(); _enemyStates = new Dictionary { { EnemyState.Idle, _enemyStateIdle }, @@ -76,6 +73,7 @@ public abstract class EnemyController : CharacterBase }; break; case MonsterType.Caster: + _enemyStateFlee = new EnemyStateFlee(); _enemyStates = new Dictionary { { EnemyState.Idle, _enemyStateIdle }, diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs b/Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs index 38bb4200..ba2c7f76 100644 --- a/Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs +++ b/Assets/Scripts/Character/Enemy/EnemyState/Melee/EnemyStateTrace.cs @@ -30,8 +30,8 @@ public class EnemyStateTrace : IEnemyState public void Update() { - if(_enemyController.IsMeleeCombat) return; - if (_enemyController.Agent.enabled != true) return; + if (_enemyController.Agent.enabled != true || + _enemyController.IsMeleeCombat) return; PlayerTracking();