From 99082eeb7cea85f75ec5637ba8fd40085deda8ff Mon Sep 17 00:00:00 2001 From: Fiore Date: Tue, 29 Apr 2025 09:26:09 +0900 Subject: [PATCH] =?UTF-8?q?[feat]=20=EB=A7=88=EB=B2=95=EC=82=AC=20?= =?UTF-8?q?=EB=AA=AC=EC=8A=A4=ED=84=B0=EC=9D=98=20=EB=8F=84=EB=A7=9D=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 경로 탐색 주기를 설정해 성능 향상 - 상태 진입과 이탈시 초기화처리 - 버그 수정 : 플레이어와 거리를 체크하고 전투 시작 - 경로 탐색 성능 향상 - 배틀 시퀸스 프레임 작성 work in #DEG-100 --- .../Character/Enemy/CasterDemonController.cs | 15 ++++- .../Enemy/EnemyState/Caster/EnemyStateFlee.cs | 60 ++++++++++++------- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/Assets/Scripts/Character/Enemy/CasterDemonController.cs b/Assets/Scripts/Character/Enemy/CasterDemonController.cs index ad492597..af724400 100644 --- a/Assets/Scripts/Character/Enemy/CasterDemonController.cs +++ b/Assets/Scripts/Character/Enemy/CasterDemonController.cs @@ -4,11 +4,22 @@ using UnityEngine; public class CasterDemonController : EnemyController { + private bool _doneBattleSequence = true; public override void BattleSequence() { - // TODO : 배틀 중일 때 루프 - Debug.Log("## 몬스터의 교전 행동 루프"); + // 전투 행동이 이미 진행 중일 경우 실행 막기 + if (_doneBattleSequence) + { + // 전투 행동 시작 + _doneBattleSequence = false; + + // TODO : 배틀 중일 때 루프 + Debug.Log("## 몬스터의 교전 행동 루프"); + + // 전투 행동이 끝남 + _doneBattleSequence = true; + } } diff --git a/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs index 9445ab69..95bf28e1 100644 --- a/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs +++ b/Assets/Scripts/Character/Enemy/EnemyState/Caster/EnemyStateFlee.cs @@ -6,7 +6,11 @@ public class EnemyStateFlee :IEnemyState private EnemyController _enemyController; private Transform _playerTransform; private float _fleeDistance = 5f; // 도망치는 거리 - private float _attackRange = 7f; // 공격 범위 + private float _safeRange = 7f; // 공격 범위 + + // 경로 탐색 주기 조절용 + private float _fleeSearchTimer = 0; + private float _fleeThresholdTime = 0.2f; // 막다른길 검사용 private Vector3 _lastPosition; @@ -21,9 +25,11 @@ public class EnemyStateFlee :IEnemyState _playerTransform = _enemyController.TraceTargetTransform; _lastPosition = _enemyController.transform.position; + + _enemyController.Agent.ResetPath(); + _enemyController.Agent.isStopped = false; _stuckTimer = 0f; - - + _fleeSearchTimer = 0; } public void Update() @@ -34,8 +40,28 @@ public class EnemyStateFlee :IEnemyState return; } + float currentDist = Vector3.Distance( + _enemyController.transform.position, + _playerTransform.position + ); + if (currentDist >= _safeRange) + { + // 목적지 리셋 후 전투 시작 + _enemyController.Agent.isStopped = true; + _enemyController.Agent.ResetPath(); + _enemyController.BattleSequence(); + return; + } + FindPositionFlee(); + if (!_enemyController.Agent.pathPending && + _enemyController.Agent.pathStatus == NavMeshPathStatus.PathInvalid) + { + // 막다른 길임 : 대체 행동 실행 + HandleDeadEnd(); + } + // 막힘 감지 (실제 이동 체크) CheckPath(); @@ -44,45 +70,37 @@ public class EnemyStateFlee :IEnemyState private void CheckPath() { - float distance = Vector3.Distance(_enemyController.transform.position, _playerTransform.position); - if (distance < StuckMoveThreshold) + float moved = Vector3.Distance(_enemyController.transform.position, _lastPosition); + if (moved < StuckMoveThreshold) { _stuckTimer += Time.deltaTime; if (_stuckTimer >= StuckThresholdTime) { - // 막다른 길임 : 대체 행동 실행 HandleDeadEnd(); _stuckTimer = 0f; } } else { - // 정상적인 길: 배틀 루프 실행 - _enemyController.BattleSequence(); _stuckTimer = 0f; } } private void FindPositionFlee() { + _fleeSearchTimer += Time.deltaTime; + if (_fleeSearchTimer <= _fleeThresholdTime) return; + // 1) 목표 도망 위치 계산 Vector3 fleeDirection = (_enemyController.transform.position - _playerTransform.position).normalized; Vector3 fleeTarget = _enemyController.transform.position + fleeDirection * _fleeDistance; // 2) 경로 계산해 보기 - NavMeshPath path = new NavMeshPath(); - _enemyController.Agent.CalculatePath(fleeTarget, path); + _enemyController.Agent.SetDestination(fleeTarget); - if (path.status == NavMeshPathStatus.PathComplete) - { - // 제대로 도망갈 수 있으면 목적지 설정 - _enemyController.Agent.SetDestination(fleeTarget); - } - else - { - // 막다른 길임 : 대체 행동 실행 - HandleDeadEnd(); - } + // 3) 이동 + _enemyController.Agent.isStopped = false; + _fleeSearchTimer = 0; } private void HandleDeadEnd() @@ -103,6 +121,8 @@ public class EnemyStateFlee :IEnemyState public void Exit() { + _enemyController.Agent.isStopped = true; + _enemyController.Agent.ResetPath(); _playerTransform = null; _enemyController = null; }