fix: 드로그 패턴 애니메이션 재생 끊김 수정
- BT 재평가 중에도 패턴 실행 상태를 보존하도록 보스 패턴 액션과 런타임 상태를 조정했다. - 스킬 컨트롤러에서 동일 프레임 종료 판정을 막아 패턴 내 다음 스킬이 즉시 잘리는 문제를 수정했다. - 드로그 BT, 패턴/스킬 데이터, 애니메이션 클립과 컨트롤러를 현재 검증된 재생 구성으로 정리했다. - 자연 발동 기준으로 콤보-기본기2 재생 시간을 재검증해 클립 길이와 실제 재생 간격이 맞는 것을 확인했다.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e35d6eb3ae2c5a146801c9dd399acd52
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 7400000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -43628,7 +43628,7 @@ AnimationClip:
|
|||||||
m_KeepOriginalPositionY: 1
|
m_KeepOriginalPositionY: 1
|
||||||
m_KeepOriginalPositionXZ: 0
|
m_KeepOriginalPositionXZ: 0
|
||||||
m_HeightFromFeet: 0
|
m_HeightFromFeet: 0
|
||||||
m_Mirror: 1
|
m_Mirror: 0
|
||||||
m_EditorCurves: []
|
m_EditorCurves: []
|
||||||
m_EulerEditorCurves: []
|
m_EulerEditorCurves: []
|
||||||
m_HasGenericRootTransform: 0
|
m_HasGenericRootTransform: 0
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 94da51b9da4bad4129ba5e33e671db62
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 7400000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 4ff85a68bb491e143a001f3af82639ed
|
guid: 2ca3044b7e7a3ff4eb8d3d6bf75f5e92
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 7400000
|
mainObjectFileID: 7400000
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 8cfd11750543a4484bae82462b7c0351
|
guid: 6b11f2b53d826bba3ab9f8086a42de14
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 7400000
|
mainObjectFileID: 7400000
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: b8206d6d914a86cd9a169763c82f273e
|
guid: 156c90879bba0d7649e8b29224daa390
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 7400000
|
mainObjectFileID: 7400000
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 16c44854334d767d3af2fd774b89a809
|
guid: 6439cde8bc726bd1caad7d6e18a31416
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 7400000
|
mainObjectFileID: 7400000
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 82cf3119cd7b56e3e9d579cac94fc09d
|
guid: 606aec780e456217687074cbbf23a2c8
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 7400000
|
mainObjectFileID: 7400000
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 18b092b0aae73b9219db20623b0c3427
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 7400000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8f572193078ff9e229c1d39038620857
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 7400000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
118642
Assets/_Game/Animations/Anim_Drog_콤보-기본기3_2_1.anim
Normal file
118642
Assets/_Game/Animations/Anim_Drog_콤보-기본기3_2_1.anim
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 0b70d6464b876144c84f2410c0359a4f
|
guid: 16c44854334d767d3af2fd774b89a809
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 7400000
|
mainObjectFileID: 7400000
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 9678ad326a270e9aa9cb5ebf5fa00279
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 7400000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -161,7 +161,7 @@ AnimatorStateMachine:
|
|||||||
m_ChildStates:
|
m_ChildStates:
|
||||||
- serializedVersion: 1
|
- serializedVersion: 1
|
||||||
m_State: {fileID: -4652545120162758660}
|
m_State: {fileID: -4652545120162758660}
|
||||||
m_Position: {x: 290, y: 180, z: 0}
|
m_Position: {x: 480, y: 230, z: 0}
|
||||||
- serializedVersion: 1
|
- serializedVersion: 1
|
||||||
m_State: {fileID: -2487449162152911812}
|
m_State: {fileID: -2487449162152911812}
|
||||||
m_Position: {x: -220, y: 350, z: 0}
|
m_Position: {x: -220, y: 350, z: 0}
|
||||||
@@ -454,30 +454,6 @@ AnimatorController:
|
|||||||
m_IKPass: 0
|
m_IKPass: 0
|
||||||
m_SyncedLayerAffectsTiming: 0
|
m_SyncedLayerAffectsTiming: 0
|
||||||
m_Controller: {fileID: 9100000}
|
m_Controller: {fileID: 9100000}
|
||||||
- serializedVersion: 5
|
|
||||||
m_Name: Override
|
|
||||||
m_StateMachine: {fileID: -8724618498758723359}
|
|
||||||
m_Mask: {fileID: 31900000, guid: d878cc26c0d6449d2ad2c0ed02c73eca, type: 2}
|
|
||||||
m_Motions:
|
|
||||||
- serializedVersion: 2
|
|
||||||
m_State: {fileID: 0}
|
|
||||||
m_Motion: {fileID: -1601098376034012026, guid: 86ec0c0d77d3fcd47b879e206e9b492c, type: 3}
|
|
||||||
- serializedVersion: 2
|
|
||||||
m_State: {fileID: -4652545120162758660}
|
|
||||||
m_Motion: {fileID: 691025228808474260, guid: f24af721b97fadb4ba0f82937853e9f7, type: 3}
|
|
||||||
- serializedVersion: 2
|
|
||||||
m_State: {fileID: -2487449162152911812}
|
|
||||||
m_Motion: {fileID: 8640942340808133859, guid: 235e9fb2014c3044ba826dd0e71987a4, type: 3}
|
|
||||||
- serializedVersion: 2
|
|
||||||
m_State: {fileID: 0}
|
|
||||||
m_Motion: {fileID: 9143937929783346939, guid: 92dc2765bff93f540a4433ac13713d72, type: 3}
|
|
||||||
m_Behaviours: []
|
|
||||||
m_BlendingMode: 0
|
|
||||||
m_SyncedLayerIndex: 0
|
|
||||||
m_DefaultWeight: 0
|
|
||||||
m_IKPass: 0
|
|
||||||
m_SyncedLayerAffectsTiming: 0
|
|
||||||
m_Controller: {fileID: 9100000}
|
|
||||||
--- !u!1102 &1582555298472611487
|
--- !u!1102 &1582555298472611487
|
||||||
AnimatorState:
|
AnimatorState:
|
||||||
serializedVersion: 6
|
serializedVersion: 6
|
||||||
@@ -493,7 +469,7 @@ AnimatorState:
|
|||||||
- {fileID: 2459631991574308566}
|
- {fileID: 2459631991574308566}
|
||||||
m_StateMachineBehaviours: []
|
m_StateMachineBehaviours: []
|
||||||
m_Position: {x: 50, y: 50, z: 0}
|
m_Position: {x: 50, y: 50, z: 0}
|
||||||
m_IKOnFeet: 0
|
m_IKOnFeet: 1
|
||||||
m_WriteDefaultValues: 1
|
m_WriteDefaultValues: 1
|
||||||
m_Mirror: 0
|
m_Mirror: 0
|
||||||
m_SpeedParameterActive: 0
|
m_SpeedParameterActive: 0
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ MonoBehaviour:
|
|||||||
Skill: {fileID: 11400000, guid: ae7fc1b970b770680b95f69111f2b08a, type: 2}
|
Skill: {fileID: 11400000, guid: ae7fc1b970b770680b95f69111f2b08a, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
- Type: 0
|
- Type: 0
|
||||||
Skill: {fileID: 11400000, guid: e666c41a932cdd478a62552e12c64801, type: 2}
|
Skill: {fileID: 11400000, guid: e666c41a932cdd478a62552e12c64801, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
- Type: 1
|
- Type: 1
|
||||||
Skill: {fileID: 0}
|
Skill: {fileID: 0}
|
||||||
Duration: 0.1
|
Duration: 0.1
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ MonoBehaviour:
|
|||||||
Skill: {fileID: 11400000, guid: d8008b7d595f832798f900b884fb6ac2, type: 2}
|
Skill: {fileID: 11400000, guid: d8008b7d595f832798f900b884fb6ac2, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
- Type: 0
|
- Type: 0
|
||||||
Skill: {fileID: 11400000, guid: a42c075b82a2b40b3b1c4540bea4bd03, type: 2}
|
Skill: {fileID: 11400000, guid: a42c075b82a2b40b3b1c4540bea4bd03, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
cooldown: 3
|
cooldown: 3
|
||||||
minPhase: 1
|
minPhase: 1
|
||||||
skipJumpStepOnNoTarget: 0
|
skipJumpStepOnNoTarget: 0
|
||||||
|
|||||||
@@ -22,23 +22,23 @@ MonoBehaviour:
|
|||||||
Skill: {fileID: 11400000, guid: 78fa18c15c0ea5248bc6966b4b2c4e04, type: 2}
|
Skill: {fileID: 11400000, guid: 78fa18c15c0ea5248bc6966b4b2c4e04, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
- Type: 0
|
- Type: 0
|
||||||
Skill: {fileID: 11400000, guid: 03c4971dcffb2ea0eb36ac997ee2a1a0, type: 2}
|
Skill: {fileID: 11400000, guid: 03c4971dcffb2ea0eb36ac997ee2a1a0, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
- Type: 0
|
- Type: 0
|
||||||
Skill: {fileID: 11400000, guid: fc435c80b8f1348f889910629f8eec51, type: 2}
|
Skill: {fileID: 11400000, guid: fc435c80b8f1348f889910629f8eec51, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
cooldown: 3.25
|
cooldown: 3.25
|
||||||
minPhase: 1
|
minPhase: 1
|
||||||
skipJumpStepOnNoTarget: 0
|
skipJumpStepOnNoTarget: 0
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ MonoBehaviour:
|
|||||||
Skill: {fileID: 11400000, guid: a3d01db588247bc93861ea39572489f5, type: 2}
|
Skill: {fileID: 11400000, guid: a3d01db588247bc93861ea39572489f5, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
- Type: 0
|
- Type: 0
|
||||||
Skill: {fileID: 11400000, guid: 4d2a845524d535769b4e2583c6321ffe, type: 2}
|
Skill: {fileID: 11400000, guid: 4d2a845524d535769b4e2583c6321ffe, type: 2}
|
||||||
Duration: 0
|
Duration: 0
|
||||||
ChargeData:
|
ChargeData:
|
||||||
requiredDamageRatio: 0
|
requiredDamageRatio: 0.1
|
||||||
telegraphAbnormality: {fileID: 0}
|
telegraphAbnormality: {fileID: 0}
|
||||||
staggerDuration: 0
|
staggerDuration: 2
|
||||||
- Type: 1
|
- Type: 1
|
||||||
Skill: {fileID: 0}
|
Skill: {fileID: 0}
|
||||||
Duration: 0.1
|
Duration: 0.1
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ MonoBehaviour:
|
|||||||
baseTypes: 1
|
baseTypes: 1
|
||||||
animationClips:
|
animationClips:
|
||||||
- {fileID: 7400000, guid: 567a0c8cbb10eafa08807226645826e2, type: 2}
|
- {fileID: 7400000, guid: 567a0c8cbb10eafa08807226645826e2, type: 2}
|
||||||
- {fileID: 7400000, guid: 94da51b9da4bad4129ba5e33e671db62, type: 2}
|
|
||||||
animationSpeed: 1
|
animationSpeed: 1
|
||||||
useRootMotion: 1
|
useRootMotion: 1
|
||||||
ignoreRootMotionY: 1
|
ignoreRootMotionY: 1
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
|
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
|
||||||
m_Name: "Data_Skill_Drog_\uCF64\uBCF4-\uAE30\uBCF8\uAE301_3"
|
m_Name: "Data_Skill_Drog_\uCF64\uBCF4-\uAE30\uBCF8\uAE301_3"
|
||||||
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
|
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
|
||||||
skillName: "\uCF64\uBCF4-\uAE30\uBCF8\uAE301 2\uD0C0"
|
skillName: "\uCF64\uBCF4-\uAE30\uBCF8\uAE301 3"
|
||||||
description: "\uAE30\uBCF8\uAE30 \uCF64\uBCF41\uC758 \uD6C4\uC18D \uD0C0\uACA9\uC785\uB2C8\uB2E4."
|
description: "\uAE30\uBCF8\uAE30 \uCF64\uBCF41\uC758 \uD6C4\uC18D \uD0C0\uACA9\uC785\uB2C8\uB2E4."
|
||||||
icon: {fileID: 0}
|
icon: {fileID: 0}
|
||||||
skillRole: 1
|
skillRole: 1
|
||||||
activationType: 1
|
activationType: 1
|
||||||
baseTypes: 1
|
baseTypes: 1
|
||||||
animationClips:
|
animationClips:
|
||||||
- {fileID: 7400000, guid: 567a0c8cbb10eafa08807226645826e2, type: 2}
|
- {fileID: 7400000, guid: b948f6e859be42cf9ad570e16fd418f1, type: 2}
|
||||||
- {fileID: 7400000, guid: 94da51b9da4bad4129ba5e33e671db62, type: 2}
|
- {fileID: 7400000, guid: 2ca3044b7e7a3ff4eb8d3d6bf75f5e92, type: 2}
|
||||||
animationSpeed: 1
|
animationSpeed: 1
|
||||||
useRootMotion: 1
|
useRootMotion: 1
|
||||||
ignoreRootMotionY: 1
|
ignoreRootMotionY: 1
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ MonoBehaviour:
|
|||||||
activationType: 1
|
activationType: 1
|
||||||
baseTypes: 1
|
baseTypes: 1
|
||||||
animationClips:
|
animationClips:
|
||||||
- {fileID: 7400000, guid: 8cfd11750543a4484bae82462b7c0351, type: 2}
|
- {fileID: 7400000, guid: 6b11f2b53d826bba3ab9f8086a42de14, type: 2}
|
||||||
- {fileID: 7400000, guid: b8206d6d914a86cd9a169763c82f273e, type: 2}
|
- {fileID: 7400000, guid: 156c90879bba0d7649e8b29224daa390, type: 2}
|
||||||
- {fileID: 7400000, guid: 16c44854334d767d3af2fd774b89a809, type: 2}
|
- {fileID: 7400000, guid: 6439cde8bc726bd1caad7d6e18a31416, type: 2}
|
||||||
animationSpeed: 1
|
animationSpeed: 1
|
||||||
useRootMotion: 1
|
useRootMotion: 1
|
||||||
ignoreRootMotionY: 1
|
ignoreRootMotionY: 1
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ MonoBehaviour:
|
|||||||
activationType: 1
|
activationType: 1
|
||||||
baseTypes: 1
|
baseTypes: 1
|
||||||
animationClips:
|
animationClips:
|
||||||
- {fileID: 7400000, guid: 82cf3119cd7b56e3e9d579cac94fc09d, type: 2}
|
- {fileID: 7400000, guid: 606aec780e456217687074cbbf23a2c8, type: 2}
|
||||||
animationSpeed: 1
|
animationSpeed: 1
|
||||||
useRootMotion: 1
|
useRootMotion: 1
|
||||||
ignoreRootMotionY: 1
|
ignoreRootMotionY: 1
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ MonoBehaviour:
|
|||||||
activationType: 1
|
activationType: 1
|
||||||
baseTypes: 1
|
baseTypes: 1
|
||||||
animationClips:
|
animationClips:
|
||||||
- {fileID: 7400000, guid: 8f572193078ff9e229c1d39038620857, type: 2}
|
- {fileID: 7400000, guid: 16c44854334d767d3af2fd774b89a809, type: 2}
|
||||||
animationSpeed: 1
|
animationSpeed: 1
|
||||||
useRootMotion: 1
|
useRootMotion: 1
|
||||||
ignoreRootMotionY: 1
|
ignoreRootMotionY: 1
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ public abstract partial class BossPatternActionBase : Action
|
|||||||
private ChargeStepData activeChargeData;
|
private ChargeStepData activeChargeData;
|
||||||
private bool chargeTelegraphApplied;
|
private bool chargeTelegraphApplied;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 현재 액션 인스턴스가 진행 중인 패턴 실행 상태를 이미 보유하고 있는지 여부입니다.
|
||||||
|
/// BT 재평가 중 재진입할 때 기존 실행을 이어가기 위한 가드로 사용합니다.
|
||||||
|
/// </summary>
|
||||||
|
protected bool HasActivePatternExecutionState => activePattern != null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 액션 시작 시 실제로 실행할 패턴과 대상을 결정합니다.
|
/// 액션 시작 시 실제로 실행할 패턴과 대상을 결정합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -56,6 +62,10 @@ public abstract partial class BossPatternActionBase : Action
|
|||||||
protected override Status OnStart()
|
protected override Status OnStart()
|
||||||
{
|
{
|
||||||
ResolveReferences();
|
ResolveReferences();
|
||||||
|
|
||||||
|
if (ShouldPreserveExecutionState())
|
||||||
|
return Status.Running;
|
||||||
|
|
||||||
ClearRuntimeState();
|
ClearRuntimeState();
|
||||||
|
|
||||||
if (!IsReady())
|
if (!IsReady())
|
||||||
@@ -153,6 +163,9 @@ public abstract partial class BossPatternActionBase : Action
|
|||||||
|
|
||||||
protected override void OnEnd()
|
protected override void OnEnd()
|
||||||
{
|
{
|
||||||
|
if (ShouldPreserveExecutionState())
|
||||||
|
return;
|
||||||
|
|
||||||
ClearRuntimeState();
|
ClearRuntimeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,6 +402,20 @@ public abstract partial class BossPatternActionBase : Action
|
|||||||
waitEndTime = 0f;
|
waitEndTime = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// BT 관찰자 재평가로 노드가 다시 시작될 때 현재 패턴 실행 상태를 유지해야 하는지 판단합니다.
|
||||||
|
/// </summary>
|
||||||
|
private bool ShouldPreserveExecutionState()
|
||||||
|
{
|
||||||
|
if (!IsReady() || activePattern == null || runtimeState == null || !runtimeState.IsExecutingPattern)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (runtimeState.IsBehaviorSuppressed || bossEnemy.IsDead)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsFirstSkillStep(int stepIndex)
|
private bool IsFirstSkillStep(int stepIndex)
|
||||||
{
|
{
|
||||||
if (activePattern == null || activePattern.Steps == null)
|
if (activePattern == null || activePattern.Steps == null)
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ namespace Colosseum.AI.BehaviorActions.Actions
|
|||||||
|
|
||||||
protected override Status OnStart()
|
protected override Status OnStart()
|
||||||
{
|
{
|
||||||
|
if (HasActivePatternExecutionState)
|
||||||
|
return base.OnStart();
|
||||||
|
|
||||||
if (!TrySelectPattern(out selectedPattern))
|
if (!TrySelectPattern(out selectedPattern))
|
||||||
return Status.Failure;
|
return Status.Failure;
|
||||||
|
|
||||||
@@ -44,7 +47,9 @@ namespace Colosseum.AI.BehaviorActions.Actions
|
|||||||
|
|
||||||
protected override void OnEnd()
|
protected override void OnEnd()
|
||||||
{
|
{
|
||||||
|
if (!HasActivePatternExecutionState)
|
||||||
selectedPattern = null;
|
selectedPattern = null;
|
||||||
|
|
||||||
base.OnEnd();
|
base.OnEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ namespace Colosseum.Enemy
|
|||||||
[Header("Pattern Flow")]
|
[Header("Pattern Flow")]
|
||||||
[Tooltip("패턴 하나가 끝난 뒤 다음 패턴을 시작하기까지의 공통 텀")]
|
[Tooltip("패턴 하나가 끝난 뒤 다음 패턴을 시작하기까지의 공통 텀")]
|
||||||
[Min(0f)] [SerializeField] protected float commonPatternInterval = 0.35f;
|
[Min(0f)] [SerializeField] protected float commonPatternInterval = 0.35f;
|
||||||
|
[Tooltip("패턴 종료 후 Idle 자세가 잠깐 안착할 수 있도록 추가로 확보하는 시간")]
|
||||||
|
[Min(0f)] [SerializeField] protected float postPatternIdleSettleDuration = 0.12f;
|
||||||
|
|
||||||
[Header("Phase State")]
|
[Header("Phase State")]
|
||||||
[Tooltip("BT가 관리하는 최대 페이즈 수")]
|
[Tooltip("BT가 관리하는 최대 페이즈 수")]
|
||||||
@@ -62,6 +64,7 @@ namespace Colosseum.Enemy
|
|||||||
protected int currentPatternPhase = 1;
|
protected int currentPatternPhase = 1;
|
||||||
protected float currentPhaseStartTime;
|
protected float currentPhaseStartTime;
|
||||||
protected float nextPatternReadyTime;
|
protected float nextPatternReadyTime;
|
||||||
|
protected float lastPatternCompletedTime = float.NegativeInfinity;
|
||||||
protected BossPatternExecutionResult lastPatternExecutionResult;
|
protected BossPatternExecutionResult lastPatternExecutionResult;
|
||||||
protected BossPatternData lastExecutedPattern;
|
protected BossPatternData lastExecutedPattern;
|
||||||
protected BossPatternData activePattern;
|
protected BossPatternData activePattern;
|
||||||
@@ -100,6 +103,7 @@ namespace Colosseum.Enemy
|
|||||||
/// 패턴 종료 후 다음 패턴 시작까지 남은 공통 텀입니다.
|
/// 패턴 종료 후 다음 패턴 시작까지 남은 공통 텀입니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float RemainingPatternInterval => Mathf.Max(0f, nextPatternReadyTime - Time.time);
|
public float RemainingPatternInterval => Mathf.Max(0f, nextPatternReadyTime - Time.time);
|
||||||
|
public float RemainingPatternIdleSettleTime => Mathf.Max(0f, (lastPatternCompletedTime + Mathf.Max(0f, postPatternIdleSettleDuration)) - Time.time);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 마지막 패턴 실행 결과
|
/// 마지막 패턴 실행 결과
|
||||||
@@ -239,6 +243,7 @@ namespace Colosseum.Enemy
|
|||||||
activePattern = null;
|
activePattern = null;
|
||||||
currentPatternSkillStartsFromIdle = false;
|
currentPatternSkillStartsFromIdle = false;
|
||||||
currentPatternSkillReturnsToIdle = false;
|
currentPatternSkillReturnsToIdle = false;
|
||||||
|
lastPatternCompletedTime = Time.time;
|
||||||
|
|
||||||
if (pattern != null && IsTerminalPatternExecutionResult(result))
|
if (pattern != null && IsTerminalPatternExecutionResult(result))
|
||||||
StartCommonPatternInterval();
|
StartCommonPatternInterval();
|
||||||
@@ -338,6 +343,9 @@ namespace Colosseum.Enemy
|
|||||||
if (pattern == null || pattern.Steps == null || pattern.Steps.Count == 0)
|
if (pattern == null || pattern.Steps == null || pattern.Steps.Count == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (Time.time < lastPatternCompletedTime + Mathf.Max(0f, postPatternIdleSettleDuration))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!IsCommonPatternIntervalReady())
|
if (!IsCommonPatternIntervalReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -407,6 +415,7 @@ namespace Colosseum.Enemy
|
|||||||
currentPatternPhase = 1;
|
currentPatternPhase = 1;
|
||||||
currentPhaseStartTime = Time.time;
|
currentPhaseStartTime = Time.time;
|
||||||
nextPatternReadyTime = 0f;
|
nextPatternReadyTime = 0f;
|
||||||
|
lastPatternCompletedTime = float.NegativeInfinity;
|
||||||
lastPatternExecutionResult = BossPatternExecutionResult.None;
|
lastPatternExecutionResult = BossPatternExecutionResult.None;
|
||||||
lastExecutedPattern = null;
|
lastExecutedPattern = null;
|
||||||
lastReviveCaster = null;
|
lastReviveCaster = null;
|
||||||
|
|||||||
@@ -127,6 +127,10 @@ namespace Colosseum.Skills
|
|||||||
private Dictionary<SkillData, float> cooldownTracker = new Dictionary<SkillData, float>();
|
private Dictionary<SkillData, float> cooldownTracker = new Dictionary<SkillData, float>();
|
||||||
private AnimatorOverrideController runtimeOverrideController;
|
private AnimatorOverrideController runtimeOverrideController;
|
||||||
private int cachedRecoveryStateHash;
|
private int cachedRecoveryStateHash;
|
||||||
|
private float currentClipStartTime = -1f;
|
||||||
|
private float currentClipExpectedDuration = 0f;
|
||||||
|
private string currentClipDebugName = string.Empty;
|
||||||
|
private int currentClipStartFrame = -1;
|
||||||
|
|
||||||
|
|
||||||
public bool IsExecutingSkill => currentSkill != null;
|
public bool IsExecutingSkill => currentSkill != null;
|
||||||
@@ -292,7 +296,13 @@ namespace Colosseum.Skills
|
|||||||
// 애니메이션 종료 시 처리
|
// 애니메이션 종료 시 처리
|
||||||
if (stateInfo.normalizedTime >= 1f)
|
if (stateInfo.normalizedTime >= 1f)
|
||||||
{
|
{
|
||||||
|
if (Time.frameCount <= currentClipStartFrame)
|
||||||
|
return;
|
||||||
|
|
||||||
// 같은 반복 차수 내에서 다음 클립이 있으면 재생
|
// 같은 반복 차수 내에서 다음 클립이 있으면 재생
|
||||||
|
if (HasNextClipInSequence())
|
||||||
|
LogCurrentClipTiming("Advance");
|
||||||
|
|
||||||
if (TryPlayNextClipInSequence())
|
if (TryPlayNextClipInSequence())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -308,6 +318,7 @@ namespace Colosseum.Skills
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 모든 클립과 단계가 끝나면 종료
|
// 모든 클립과 단계가 끝나면 종료
|
||||||
|
LogCurrentClipTiming("Complete");
|
||||||
if (debugMode) Debug.Log($"[Skill] Animation complete: {currentSkill.SkillName}");
|
if (debugMode) Debug.Log($"[Skill] Animation complete: {currentSkill.SkillName}");
|
||||||
RestoreBaseControllerIfNeeded();
|
RestoreBaseControllerIfNeeded();
|
||||||
CompleteCurrentSkillExecution(SkillExecutionResult.Completed);
|
CompleteCurrentSkillExecution(SkillExecutionResult.Completed);
|
||||||
@@ -566,7 +577,8 @@ namespace Colosseum.Skills
|
|||||||
? currentLoadoutEntry.GetResolvedAnimationSpeed()
|
? currentLoadoutEntry.GetResolvedAnimationSpeed()
|
||||||
: currentSkill.AnimationSpeed;
|
: currentSkill.AnimationSpeed;
|
||||||
animator.speed = resolvedAnimationSpeed;
|
animator.speed = resolvedAnimationSpeed;
|
||||||
PlaySkillClip(currentPhaseAnimationClips[0], ShouldBlendIntoClip());
|
float enterTransitionDuration = ResolveSkillEnterTransitionDuration();
|
||||||
|
PlaySkillClip(currentPhaseAnimationClips[0], enterTransitionDuration > 0f, enterTransitionDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerImmediateSelfEffectsIfNeeded();
|
TriggerImmediateSelfEffectsIfNeeded();
|
||||||
@@ -588,7 +600,7 @@ namespace Colosseum.Skills
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
currentClipSequenceIndex = nextIndex;
|
currentClipSequenceIndex = nextIndex;
|
||||||
PlaySkillClip(currentPhaseAnimationClips[currentClipSequenceIndex], blendIn: false);
|
PlaySkillClip(currentPhaseAnimationClips[currentClipSequenceIndex], blendIn: false, transitionDuration: 0f);
|
||||||
|
|
||||||
if (debugMode)
|
if (debugMode)
|
||||||
{
|
{
|
||||||
@@ -598,6 +610,17 @@ namespace Colosseum.Skills
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 현재 시퀀스에 다음 클립이 남아 있는지 반환합니다.
|
||||||
|
/// </summary>
|
||||||
|
private bool HasNextClipInSequence()
|
||||||
|
{
|
||||||
|
if (currentSkill == null || currentPhaseAnimationClips == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return currentClipSequenceIndex + 1 < currentPhaseAnimationClips.Count;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 반복 시전이 남아 있으면 다음 차수를 시작합니다.
|
/// 반복 시전이 남아 있으면 다음 차수를 시작합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -616,7 +639,7 @@ namespace Colosseum.Skills
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 스킬 클립으로 Override Controller 생성 후 재생
|
/// 스킬 클립으로 Override Controller 생성 후 재생
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void PlaySkillClip(AnimationClip clip, bool blendIn)
|
private void PlaySkillClip(AnimationClip clip, bool blendIn, float transitionDuration)
|
||||||
{
|
{
|
||||||
if (baseSkillClip == null)
|
if (baseSkillClip == null)
|
||||||
{
|
{
|
||||||
@@ -630,19 +653,21 @@ namespace Colosseum.Skills
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecordCurrentClipTiming(clip);
|
||||||
|
|
||||||
if (debugMode)
|
if (debugMode)
|
||||||
{
|
{
|
||||||
Debug.Log($"[Skill] PlaySkillClip: {clip.name}, BaseClip: {baseSkillClip.name}");
|
Debug.Log($"[Skill] PlaySkillClip: {clip.name}, BaseClip: {baseSkillClip.name}, Blend={blendIn}, Transition={transitionDuration:F2}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blendIn)
|
if (blendIn)
|
||||||
animator.CrossFadeInFixedTime(GetSkillStateHash(), GetSkillEnterTransitionDuration(), 0, 0f);
|
animator.CrossFadeInFixedTime(GetSkillStateHash(), transitionDuration, 0, 0f);
|
||||||
else
|
else
|
||||||
animator.Play(GetSkillStateHash(), 0, 0f);
|
animator.Play(GetSkillStateHash(), 0, 0f);
|
||||||
|
|
||||||
// 클라이언트에 클립 동기화
|
// 클라이언트에 클립 동기화
|
||||||
if (IsServer && IsSpawned)
|
if (IsServer && IsSpawned)
|
||||||
PlaySkillClipClientRpc(registeredClips.IndexOf(clip), blendIn);
|
PlaySkillClipClientRpc(registeredClips.IndexOf(clip), blendIn, transitionDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -673,7 +698,7 @@ namespace Colosseum.Skills
|
|||||||
/// 클라이언트: override 컨트롤러 적용 + 스킬 상태 재생 (원자적 실행으로 타이밍 문제 해결)
|
/// 클라이언트: override 컨트롤러 적용 + 스킬 상태 재생 (원자적 실행으로 타이밍 문제 해결)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Rpc(SendTo.NotServer)]
|
[Rpc(SendTo.NotServer)]
|
||||||
private void PlaySkillClipClientRpc(int clipIndex, bool blendIn)
|
private void PlaySkillClipClientRpc(int clipIndex, bool blendIn, float transitionDuration)
|
||||||
{
|
{
|
||||||
if (baseSkillClip == null || animator == null || baseController == null) return;
|
if (baseSkillClip == null || animator == null || baseController == null) return;
|
||||||
if (clipIndex < 0 || clipIndex >= registeredClips.Count || registeredClips[clipIndex] == null)
|
if (clipIndex < 0 || clipIndex >= registeredClips.Count || registeredClips[clipIndex] == null)
|
||||||
@@ -685,7 +710,7 @@ namespace Colosseum.Skills
|
|||||||
if (!ApplyOverrideClip(registeredClips[clipIndex]))
|
if (!ApplyOverrideClip(registeredClips[clipIndex]))
|
||||||
return;
|
return;
|
||||||
if (blendIn)
|
if (blendIn)
|
||||||
animator.CrossFadeInFixedTime(GetSkillStateHash(), GetSkillEnterTransitionDuration(), 0, 0f);
|
animator.CrossFadeInFixedTime(GetSkillStateHash(), transitionDuration, 0, 0f);
|
||||||
else
|
else
|
||||||
animator.Play(GetSkillStateHash(), 0, 0f);
|
animator.Play(GetSkillStateHash(), 0, 0f);
|
||||||
}
|
}
|
||||||
@@ -825,6 +850,7 @@ namespace Colosseum.Skills
|
|||||||
lastCancelledSkillName = currentSkill.SkillName;
|
lastCancelledSkillName = currentSkill.SkillName;
|
||||||
lastCancelReason = reason;
|
lastCancelReason = reason;
|
||||||
|
|
||||||
|
LogCurrentClipTiming("Cancelled");
|
||||||
Debug.Log($"[Skill] Cancelled: {currentSkill.SkillName} / reason={reason}");
|
Debug.Log($"[Skill] Cancelled: {currentSkill.SkillName} / reason={reason}");
|
||||||
|
|
||||||
RestoreBaseController();
|
RestoreBaseController();
|
||||||
@@ -1171,7 +1197,7 @@ namespace Colosseum.Skills
|
|||||||
? currentLoadoutEntry.GetResolvedAnimationSpeed()
|
? currentLoadoutEntry.GetResolvedAnimationSpeed()
|
||||||
: currentSkill.AnimationSpeed;
|
: currentSkill.AnimationSpeed;
|
||||||
animator.speed = resolvedAnimationSpeed;
|
animator.speed = resolvedAnimationSpeed;
|
||||||
PlaySkillClip(currentPhaseAnimationClips[0], blendIn: false);
|
PlaySkillClip(currentPhaseAnimationClips[0], blendIn: false, transitionDuration: 0f);
|
||||||
|
|
||||||
if (debugMode)
|
if (debugMode)
|
||||||
Debug.Log($"[Skill] 해제 단계 시작: {currentSkill.SkillName}");
|
Debug.Log($"[Skill] 해제 단계 시작: {currentSkill.SkillName}");
|
||||||
@@ -1265,6 +1291,10 @@ namespace Colosseum.Skills
|
|||||||
currentIterationIndex = 0;
|
currentIterationIndex = 0;
|
||||||
loopHoldRequested = false;
|
loopHoldRequested = false;
|
||||||
cachedRecoveryStateHash = 0;
|
cachedRecoveryStateHash = 0;
|
||||||
|
currentClipStartTime = -1f;
|
||||||
|
currentClipExpectedDuration = 0f;
|
||||||
|
currentClipDebugName = string.Empty;
|
||||||
|
currentClipStartFrame = -1;
|
||||||
shouldBlendIntoCurrentSkill = true;
|
shouldBlendIntoCurrentSkill = true;
|
||||||
shouldRestoreToIdleAfterCurrentSkill = true;
|
shouldRestoreToIdleAfterCurrentSkill = true;
|
||||||
}
|
}
|
||||||
@@ -1288,6 +1318,38 @@ namespace Colosseum.Skills
|
|||||||
sustainController?.HandleSkillExecutionEnded();
|
sustainController?.HandleSkillExecutionEnded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 현재 클립의 예상 재생 시간을 기록합니다.
|
||||||
|
/// </summary>
|
||||||
|
private void RecordCurrentClipTiming(AnimationClip clip)
|
||||||
|
{
|
||||||
|
if (clip == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
currentClipStartTime = Time.time;
|
||||||
|
currentClipExpectedDuration = clip.length / Mathf.Max(0.0001f, animator != null ? animator.speed : 1f);
|
||||||
|
currentClipDebugName = clip.name;
|
||||||
|
currentClipStartFrame = Time.frameCount;
|
||||||
|
|
||||||
|
if (!debugMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Debug.Log($"[SkillTiming] Start: skill={currentSkill?.SkillName ?? "<null>"}, clip={currentClipDebugName}, t={currentClipStartTime:F3}, expected={currentClipExpectedDuration:F3}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 현재 클립의 실제 경과 시간을 로그로 남깁니다.
|
||||||
|
/// </summary>
|
||||||
|
private void LogCurrentClipTiming(string phase)
|
||||||
|
{
|
||||||
|
if (!debugMode || string.IsNullOrEmpty(currentClipDebugName) || currentClipStartTime < 0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float elapsed = Time.time - currentClipStartTime;
|
||||||
|
float delta = elapsed - currentClipExpectedDuration;
|
||||||
|
Debug.Log($"[SkillTiming] {phase}: skill={currentSkill?.SkillName ?? "<null>"}, clip={currentClipDebugName}, t={Time.time:F3}, elapsed={elapsed:F3}, expected={currentClipExpectedDuration:F3}, delta={delta:F3}");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 적 스킬이 시전 중일 때 대상 추적 정책을 적용합니다.
|
/// 적 스킬이 시전 중일 때 대상 추적 정책을 적용합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1460,29 +1522,46 @@ namespace Colosseum.Skills
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 현재 재생할 클립이 스킬 시작 블렌드 대상인지 반환합니다.
|
/// 현재 재생할 클립이 스킬 시작 블렌드 대상인지 반환합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool ShouldBlendIntoClip()
|
private float ResolveSkillEnterTransitionDuration()
|
||||||
{
|
{
|
||||||
if (isBossPatternBoundarySkill)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!shouldBlendIntoCurrentSkill)
|
if (!shouldBlendIntoCurrentSkill)
|
||||||
return false;
|
return 0f;
|
||||||
|
|
||||||
if (isPlayingReleasePhase)
|
if (isPlayingReleasePhase)
|
||||||
return false;
|
return 0f;
|
||||||
|
|
||||||
return currentClipSequenceIndex == 0 && currentIterationIndex == 1;
|
if (currentClipSequenceIndex != 0 || currentIterationIndex != 1)
|
||||||
|
return 0f;
|
||||||
|
|
||||||
|
if (!isBossPatternBoundarySkill)
|
||||||
|
return skillEnterTransitionDuration;
|
||||||
|
|
||||||
|
bool shouldBlendBossEntry = ShouldBlendBossPatternEntryFromCurrentState();
|
||||||
|
return shouldBlendBossEntry
|
||||||
|
? Mathf.Max(skillEnterTransitionDuration, bossPatternEnterTransitionDuration)
|
||||||
|
: 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 현재 스킬 진입에 사용할 전환 시간을 반환합니다.
|
/// 보스 패턴 첫 스킬이 이동 중 진입인지 판단합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private float GetSkillEnterTransitionDuration()
|
private bool ShouldBlendBossPatternEntryFromCurrentState()
|
||||||
{
|
{
|
||||||
if (isBossPatternBoundarySkill)
|
if (animator == null)
|
||||||
return bossPatternEnterTransitionDuration;
|
return false;
|
||||||
|
|
||||||
return skillEnterTransitionDuration;
|
if (animator.IsInTransition(0))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
AnimatorStateInfo currentState = animator.GetCurrentAnimatorStateInfo(0);
|
||||||
|
int moveStateHash = Animator.StringToHash($"{BaseLayerName}.{MoveStateName}");
|
||||||
|
if (currentState.fullPathHash == moveStateHash)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
UnityEngine.AI.NavMeshAgent agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
|
||||||
|
return agent != null
|
||||||
|
&& agent.enabled
|
||||||
|
&& agent.velocity.sqrMagnitude > 0.0025f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user