feat: 드로그 기본 루프 게이트를 BT로 이관

- big pattern grace period 판정을 런타임 헬퍼에서 제거하고 BT 조건/액션 노드로 명시

- Increment/Reset Basic Loop Count 노드 추가 및 BT_Drog 재빌드 반영

- Signature Failure Effects 수치를 BT 노드가 직접 보관하도록 정리
This commit is contained in:
2026-04-10 09:22:56 +09:00
parent b019acd0a3
commit 205b20e4e6
12 changed files with 3119 additions and 2162 deletions

View File

@@ -8,7 +8,6 @@ using Colosseum.Skills;
using Unity.Behavior;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Serialization;
namespace Colosseum.Enemy
{
@@ -44,42 +43,9 @@ namespace Colosseum.Enemy
[SerializeField] protected BehaviorGraphAgent behaviorGraphAgent;
[Header("Pattern Flow")]
[Tooltip("대형 패턴(시그니처/기동/조합) 직후 기본 패턴 최소 순환 횟수")]
[Min(0)] [SerializeField] protected int basicLoopMinCountAfterBigPattern = 2;
[Tooltip("패턴 하나가 끝난 뒤 다음 패턴을 시작하기까지의 공통 텀")]
[Min(0f)] [SerializeField] protected float commonPatternInterval = 0.35f;
[Header("시그니처 효과 설정")]
[Tooltip("시그니처 패턴 차단에 필요한 누적 피해 비율")]
[Range(0f, 1f)] [SerializeField] protected float signatureRequiredDamageRatio = 0.1f;
[Tooltip("시그니처 준비 상태를 나타내는 이상상태")]
[SerializeField] protected AbnormalityData signatureTelegraphAbnormality;
[Tooltip("시그니처 차단 성공 시 보스가 멈추는 시간")]
[Min(0f)] [SerializeField] protected float signatureSuccessStaggerDuration = 2f;
[Tooltip("시그니처 실패 시 모든 플레이어에게 적용할 디버프")]
[SerializeField] protected AbnormalityData signatureFailureAbnormality;
[Tooltip("시그니처 실패 시 모든 플레이어에게 주는 기본 피해")]
[Min(0f)] [SerializeField] protected float signatureFailureDamage = 40f;
[Tooltip("시그니처 실패 시 넉백이 적용되는 반경")]
[Min(0f)] [SerializeField] protected float signatureFailureKnockbackRadius = 8f;
[Tooltip("시그니처 실패 시 다운이 적용되는 반경")]
[Min(0f)] [SerializeField] protected float signatureFailureDownRadius = 3f;
[Tooltip("시그니처 실패 시 넉백 속도")]
[Min(0f)] [SerializeField] protected float signatureFailureKnockbackSpeed = 12f;
[Tooltip("시그니처 실패 시 넉백 지속 시간")]
[Min(0f)] [SerializeField] protected float signatureFailureKnockbackDuration = 0.35f;
[Tooltip("시그니처 실패 시 다운 지속 시간")]
[Min(0f)] [SerializeField] protected float signatureFailureDownDuration = 2f;
[Header("Phase State")]
[Tooltip("BT가 관리하는 최대 페이즈 수")]
[Min(1)] [SerializeField] protected int maxPatternPhase = 3;
@@ -123,7 +89,7 @@ namespace Colosseum.Enemy
public float PhaseElapsedTime => Time.time - currentPhaseStartTime;
/// <summary>
/// 마지막 대형 패턴 이후 누적된 기본 루프 횟수
/// 마지막 대형/징벌 패턴 이후 누적된 기본 루프 횟수
/// </summary>
public int BasicLoopCountSinceLastBigPattern => basicLoopCountSinceLastBigPattern;
@@ -152,41 +118,6 @@ namespace Colosseum.Enemy
/// </summary>
public bool DebugModeEnabled => debugMode;
/// <summary>
/// 시그니처 실패 시 모든 플레이어에게 주는 기본 피해
/// </summary>
public float SignatureFailureDamage => signatureFailureDamage;
/// <summary>
/// 시그니처 실패 시 모든 플레이어에게 적용할 디버프
/// </summary>
public AbnormalityData SignatureFailureAbnormality => signatureFailureAbnormality;
/// <summary>
/// 시그니처 실패 시 넉백이 적용되는 반경
/// </summary>
public float SignatureFailureKnockbackRadius => signatureFailureKnockbackRadius;
/// <summary>
/// 시그니처 실패 시 다운이 적용되는 반경
/// </summary>
public float SignatureFailureDownRadius => signatureFailureDownRadius;
/// <summary>
/// 시그니처 실패 시 넉백 속도
/// </summary>
public float SignatureFailureKnockbackSpeed => signatureFailureKnockbackSpeed;
/// <summary>
/// 시그니처 실패 시 넉백 지속 시간
/// </summary>
public float SignatureFailureKnockbackDuration => signatureFailureKnockbackDuration;
/// <summary>
/// 시그니처 실패 시 다운 지속 시간
/// </summary>
public float SignatureFailureDownDuration => signatureFailureDownDuration;
/// <summary>
/// 마지막 충전 차단 시 설정된 경직 시간 (BossPatternActionBase가 설정)
/// </summary>
@@ -345,24 +276,19 @@ namespace Colosseum.Enemy
&& value;
}
/// <summary>
/// 근접 패턴 사용 카운터를 갱신합니다.
/// </summary>
public void RegisterPatternUse(BossPatternData pattern)
public void IncrementBasicLoopCount(int count = 1)
{
if (pattern == null)
int appliedCount = Mathf.Max(0, count);
if (appliedCount <= 0)
return;
if (pattern.IsMelee)
{
meleePatternCounter++;
basicLoopCountSinceLastBigPattern++;
}
meleePatternCounter += appliedCount;
basicLoopCountSinceLastBigPattern += appliedCount;
}
if (pattern.Category == PatternCategory.Punish || pattern.IsBigPattern)
{
basicLoopCountSinceLastBigPattern = 0;
}
public void ResetBasicLoopCount()
{
basicLoopCountSinceLastBigPattern = 0;
}
/// <summary>
@@ -374,24 +300,6 @@ namespace Colosseum.Enemy
Debug.Log($"[{source}] {message}");
}
/// <summary>
/// 지정 패턴이 grace period를 통과했는지 반환합니다.
/// Punish/Melee/Utility는 항상 허용됩니다.
/// </summary>
public bool IsPatternGracePeriodAllowed(BossPatternData pattern)
{
if (pattern == null)
return false;
if (pattern.Category == PatternCategory.Punish)
return true;
if (pattern.IsMelee || pattern.TargetMode == TargetResolveMode.Utility)
return true;
return basicLoopCountSinceLastBigPattern >= basicLoopMinCountAfterBigPattern;
}
public bool IsPatternReady(BossPatternData pattern)
{
if (pattern == null || pattern.Steps == null || pattern.Steps.Count == 0)