feat: 드로그 보스 리네임 및 기본 패턴 구현

This commit is contained in:
2026-03-21 12:29:29 +09:00
parent 671f8d8a25
commit d5d4b2f125
62 changed files with 793 additions and 61 deletions

View File

@@ -4739,7 +4739,7 @@ MonoBehaviour:
m_EditorClassIdentifier: Colosseum.Game::Colosseum.UI.ConnectionUI
ipAddress: 127.0.0.1
port: 7777
autoStartHostInEditor: 0
autoStartHostInEditor: 1
connectionStatus: Disconnected
--- !u!4 &854739757 stripped
Transform:
@@ -6796,6 +6796,19 @@ Transform:
m_CorrespondingSourceObject: {fileID: 7132605379903659868, guid: 5b4ac53b97612ae4392b84786de0d50d, type: 3}
m_PrefabInstance: {fileID: 1329389111}
m_PrefabAsset: {fileID: 0}
--- !u!134 &1236586838
PhysicsMaterial:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ' (Instance)'
serializedVersion: 2
m_DynamicFriction: 0.6
m_StaticFriction: 0.6
m_Bounciness: 0
m_FrictionCombine: 0
m_BounceCombine: 0
--- !u!1001 &1236816272
PrefabInstance:
m_ObjectHideFlags: 0
@@ -11397,19 +11410,6 @@ Transform:
m_CorrespondingSourceObject: {fileID: 1824081129582740912, guid: bf62c127a7934334d9b955503391f574, type: 3}
m_PrefabInstance: {fileID: 649018401}
m_PrefabAsset: {fileID: 0}
--- !u!134 &1976569495
PhysicsMaterial:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
serializedVersion: 2
m_DynamicFriction: 0.6
m_StaticFriction: 0.6
m_Bounciness: 0
m_FrictionCombine: 0
m_BounceCombine: 0
--- !u!1001 &1986213921
PrefabInstance:
m_ObjectHideFlags: 0
@@ -11482,18 +11482,18 @@ PrefabInstance:
- target: {fileID: -4476104823835307179, guid: 56986b707b0dc09439cb35ff2f87dcc9, type: 3}
propertyPath: m_Material
value:
objectReference: {fileID: 1976569495}
objectReference: {fileID: 1236586838}
- target: {fileID: 3122493901255878198, guid: 56986b707b0dc09439cb35ff2f87dcc9, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3122493901255878198, guid: 56986b707b0dc09439cb35ff2f87dcc9, type: 3}
propertyPath: m_LocalPosition.y
value: -0
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3122493901255878198, guid: 56986b707b0dc09439cb35ff2f87dcc9, type: 3}
propertyPath: m_LocalPosition.z
value: 15
value: 8
objectReference: {fileID: 0}
- target: {fileID: 3122493901255878198, guid: 56986b707b0dc09439cb35ff2f87dcc9, type: 3}
propertyPath: m_LocalRotation.w
@@ -11523,13 +11523,9 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5153439431748782209, guid: 56986b707b0dc09439cb35ff2f87dcc9, type: 3}
propertyPath: m_BaseOffset
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5581648761285601425, guid: 56986b707b0dc09439cb35ff2f87dcc9, type: 3}
propertyPath: m_Name
value: TestBoss
value: Drog
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-6758363554468061369
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5b27bb6d9a2c8d540a10dff10acc543e, type: 3}
m_Name: BT_TestBoss Debug Info
m_Name: BT_Drog Debug Info
m_EditorClassIdentifier: Unity.Behavior::Unity.Behavior.BehaviorGraphDebugInfo
m_CodeBreakPointsList: []
--- !u!114 &-6591390698989283165
@@ -23,7 +23,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2dd922ae02c94c87a66e46a10a7319b9, type: 3}
m_Name: BT_TestBoss Blackboard
m_Name: BT_Drog Blackboard
m_EditorClassIdentifier: Unity.Behavior.Authoring::Unity.Behavior.BehaviorBlackboardAuthoringAsset
AssetID:
m_Value0: 11861793134961942170
@@ -112,7 +112,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: db920e62f70f420bb33c771449926fa4, type: 3}
m_Name: BT_TestBoss
m_Name: BT_Drog
m_EditorClassIdentifier: Unity.Behavior::Unity.Behavior.BehaviorGraph
Graphs:
- rid: 8805855836547055693
@@ -595,7 +595,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bad8f2220607dac4db5082ff333fafb8, type: 3}
m_Name: BT_TestBoss
m_Name: BT_Drog
m_EditorClassIdentifier: Unity.Behavior.Authoring::Unity.Behavior.BehaviorAuthoringGraph
Blackboard: {fileID: -6591390698989283165}
m_Description:
@@ -2417,7 +2417,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5c02bb70996b49eba31d0c206e28da24, type: 3}
m_Name: BT_TestBoss Blackboard
m_Name: BT_Drog Blackboard
m_EditorClassIdentifier: Unity.Behavior::Unity.Behavior.RuntimeBlackboardAsset
VersionTimestamp: 639094519736977735
AssetID:
@@ -2483,3 +2483,4 @@ MonoBehaviour:
m_Value1: 14990413519379198129
Name: Die
m_Value: 0

View File

@@ -56,6 +56,13 @@ ModelImporter:
curves: []
events:
- time: 0.35211262
functionName: OnEffect
data:
objectReferenceParameter: {instanceID: 0}
floatParameter: 0
intParameter: 1
messageOptions: 0
- time: 0.3636364
functionName: OnEffect
data:
objectReferenceParameter: {instanceID: 0}

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1ecdc2379b078b246a0bd5c0fb58e346, type: 3}
m_Name: Data_Enemy_TestBoss
m_Name: Data_Enemy_Drog
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Enemy.EnemyData
enemyName: Boss The Test
description:
@@ -26,3 +26,4 @@ MonoBehaviour:
aggroRange: 10
attackRange: 2
attackCooldown: 1

View File

@@ -0,0 +1,20 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0ce956e0878565343974c31b8111c0c6, type: 3}
m_Name: "Data_Pattern_Drog_\uB2E4\uC6B4\uCD94\uAC00\uD0C0"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.AI.BossPatternData
patternName: "\uB2E4\uC6B4 \uCD94\uAC00\uD0C0"
steps:
- Type: 0
Skill: {fileID: 11400000, guid: fd7a5d5cc9494229b0c475e7f0cda218, type: 2}
Duration: 0
cooldown: 2.5

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fe5100f855d14c0faac44b6d4f2c771e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0ce956e0878565343974c31b8111c0c6, type: 3}
m_Name: "Data_Pattern_TestBoss_\uC57D2\uD0C0-\uC2A4\uC719"
m_Name: "Data_Pattern_Drog_\uC57D2\uD0C0-\uC2A4\uC719"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.AI.BossPatternData
patternName: "\uAE30\uBCF8 \uD328\uD134"
steps:
@@ -24,3 +24,4 @@ MonoBehaviour:
Skill: {fileID: 11400000, guid: 3acbf1c5ec71bef4bb13f8534605d554, type: 2}
Duration: 0.5
cooldown: 5

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0ce956e0878565343974c31b8111c0c6, type: 3}
m_Name: "Data_Pattern_TestBoss_\uC810\uD504"
m_Name: "Data_Pattern_Drog_\uC810\uD504"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.AI.BossPatternData
patternName: "\uAE30\uBCF8 \uD328\uD134"
steps:
@@ -24,3 +24,4 @@ MonoBehaviour:
Skill: {fileID: 11400000, guid: 16321efbd1f2498458683bac7605b054, type: 2}
Duration: 0
cooldown: 1

View File

@@ -0,0 +1,27 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
m_Name: "Data_Skill_Drog_\uB2E4\uC6B4\uCD94\uAC00\uD0C0"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
skillName: "\uB2E4\uC6B4 \uCD94\uAC00\uD0C0"
description:
icon: {fileID: 0}
skillClip: {fileID: -242498254790479478, guid: 585e8961b6c6e9f4ba96bdb4ffb2cbc3, type: 3}
endClip: {fileID: 3627526391332626453, guid: 39aaec38fc96c4842b972f1e991e5a46, type: 3}
animationSpeed: 1
useRootMotion: 1
ignoreRootMotionY: 1
jumpToTarget: 0
cooldown: 0
manaCost: 0
effects:
- {fileID: 11400000, guid: 0f134a897a7e4d0e98c8d9058b1d79d1, type: 2}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fd7a5d5cc9494229b0c475e7f0cda218
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
m_Name: "Data_Skill_TestBoss_\uC2A4\uC719"
m_Name: "Data_Skill_Drog_\uC2A4\uC719"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
skillName: "\uC2A4\uC719"
description:
@@ -23,3 +23,4 @@ MonoBehaviour:
manaCost: 0
effects:
- {fileID: 11400000, guid: 94b0f3305cea88c458a56783a486340e, type: 2}

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
m_Name: "Data_Skill_TestBoss_\uC624\uB978\uC190\uCE58\uAE30"
m_Name: "Data_Skill_Drog_\uC624\uB978\uC190\uCE58\uAE30"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
skillName: "\uC624\uB978\uC190\uCE58\uAE30"
description:
@@ -23,3 +23,4 @@ MonoBehaviour:
manaCost: 0
effects:
- {fileID: 11400000, guid: 86bf7e282c1639c4889910475aaccdef, type: 2}

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
m_Name: "Data_Skill_TestBoss_\uC624\uB978\uC190\uCE58\uAE302"
m_Name: "Data_Skill_Drog_\uC624\uB978\uC190\uCE58\uAE302"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
skillName: "\uC624\uB978\uC190\uCE58\uAE302"
description:
@@ -23,3 +23,5 @@ MonoBehaviour:
manaCost: 0
effects:
- {fileID: 11400000, guid: 87b064a0134987b4b9638e184ab07411, type: 2}
- {fileID: 11400000, guid: 0dba6dca651743bc84b0df42f9dbd290, type: 2}

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
m_Name: "Data_Skill_TestBoss_\uC810\uD504"
m_Name: "Data_Skill_Drog_\uC810\uD504"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
skillName: "\uC810\uD504"
description:
@@ -25,3 +25,4 @@ MonoBehaviour:
manaCost: 0
effects:
- {fileID: 0}

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
m_Name: "Data_Skill_TestBoss_\uC810\uD504\uC900\uBE44"
m_Name: "Data_Skill_Drog_\uC810\uD504\uC900\uBE44"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
skillName: "\uC810\uD504"
description:
@@ -25,3 +25,4 @@ MonoBehaviour:
manaCost: 0
effects:
- {fileID: 0}

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 94f0a76cebcac2f4fb5daf1b675fd79f, type: 3}
m_Name: "Data_Skill_TestBoss_\uC810\uD504\uCC29\uC9C0"
m_Name: "Data_Skill_Drog_\uC810\uD504\uCC29\uC9C0"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.SkillData
skillName: "\uC810\uD504"
description:
@@ -25,3 +25,4 @@ MonoBehaviour:
manaCost: 0
effects:
- {fileID: 11400000, guid: 11bd2d1ebdbfc2f4abf5a9d886615eb3, type: 2}

View File

@@ -0,0 +1,30 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6fd8c6f4c4454ecdb111d13dc8471024, type: 3}
m_Name: "Data_SkillEffect_Drog_\uB2E4\uC6B4\uCD94\uAC00\uD0C0_0_\uD53C\uACA9\uAC00\uC911\uB370\uBBF8\uC9C0"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.Effects.HitReactionDamageEffect
targetType: 1
targetTeam: 0
areaCenter: 0
areaShape: 0
targetLayers:
serializedVersion: 2
m_Bits: 4294967295
areaRadius: 3.25
fanOriginDistance: 1
fanRadius: 3
fanHalfAngle: 45
baseDamage: 1
damageType: 0
statScaling: 1
bonusAgainstDownedTarget: 1
downedDamageMultiplier: 1.5

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0f134a897a7e4d0e98c8d9058b1d79d1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 58efb3c775496fa40b801b21127a011e, type: 3}
m_Name: "Data_SkillEffect_TestBoss_\uC2A4\uC719_0_\uB370\uBBF8\uC9C0"
m_Name: "Data_SkillEffect_Drog_\uC2A4\uC719_0_\uB370\uBBF8\uC9C0"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.Effects.DamageEffect
targetType: 1
targetTeam: 0
@@ -26,3 +26,4 @@ MonoBehaviour:
baseDamage: 1
damageType: 0
statScaling: 1

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 58efb3c775496fa40b801b21127a011e, type: 3}
m_Name: "Data_SkillEffect_TestBoss_\uC624\uB978\uC190\uCE58\uAE302_0_\uB370\uBBF8\uC9C0"
m_Name: "Data_SkillEffect_Drog_\uC624\uB978\uC190\uCE58\uAE302_0_\uB370\uBBF8\uC9C0"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.Effects.DamageEffect
targetType: 1
targetTeam: 0
@@ -26,3 +26,4 @@ MonoBehaviour:
baseDamage: 1
damageType: 0
statScaling: 1

View File

@@ -0,0 +1,26 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41c96b54a96cdb84c9bda774775b0a1a, type: 3}
m_Name: "Data_SkillEffect_Drog_\uC624\uB978\uC190\uCE58\uAE302_1_\uB2E4\uC6B4"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.Effects.DownEffect
targetType: 1
targetTeam: 0
areaCenter: 0
areaShape: 1
targetLayers:
serializedVersion: 2
m_Bits: 4294967295
areaRadius: 3
fanOriginDistance: 0
fanRadius: 3
fanHalfAngle: 45
duration: 2.5

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0dba6dca651743bc84b0df42f9dbd290
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 58efb3c775496fa40b801b21127a011e, type: 3}
m_Name: "Data_SkillEffect_TestBoss_\uC624\uB978\uC190\uCE58\uAE30_0_\uB370\uBBF8\uC9C0"
m_Name: "Data_SkillEffect_Drog_\uC624\uB978\uC190\uCE58\uAE30_0_\uB370\uBBF8\uC9C0"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.Effects.DamageEffect
targetType: 1
targetTeam: 0
@@ -26,3 +26,4 @@ MonoBehaviour:
baseDamage: 1
damageType: 0
statScaling: 1

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 58efb3c775496fa40b801b21127a011e, type: 3}
m_Name: "Data_SkillEffect_TestBoss_\uC810\uD504_0_\uB370\uBBF8\uC9C0"
m_Name: "Data_SkillEffect_Drog_\uC810\uD504_0_\uB370\uBBF8\uC9C0"
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Skills.Effects.DamageEffect
targetType: 1
targetTeam: 0
@@ -26,3 +26,4 @@ MonoBehaviour:
baseDamage: 1
damageType: 0
statScaling: 1

View File

@@ -1,4 +1,4 @@
%YAML 1.1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1008926773928116
GameObject:
@@ -1364,7 +1364,7 @@ GameObject:
- component: {fileID: 4373196678005266}
- component: {fileID: 95998111322576624}
m_Layer: 0
m_Name: Model_Enemy_TestBoss
m_Name: Model_Enemy_Drog
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -3285,3 +3285,4 @@ Transform:
m_CorrespondingSourceObject: {fileID: 8583892753143838813, guid: 95219051c0a1142448e9ed4beee02fe1, type: 3}
m_PrefabInstance: {fileID: 8587889261130452289}
m_PrefabAsset: {fileID: 0}

View File

@@ -1929,11 +1929,12 @@ GameObject:
- component: {fileID: 5774766047967133809}
- component: {fileID: 8818883032728065057}
- component: {fileID: -2857689419101920665}
- component: {fileID: 1459274958342653187}
- component: {fileID: 7544406269366897481}
- component: {fileID: 4137653497738922896}
- component: {fileID: 2670434347080613863}
m_Layer: 6
m_Name: Prefab_Boss_TestBoss
m_Name: Prefab_Boss_Drog
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -2030,6 +2031,10 @@ MonoBehaviour:
animator: {fileID: 4019041888965840580}
navMeshAgent: {fileID: 5153439431748782209}
enemyData: {fileID: 11400000, guid: f21773b42c60c4b40b609966f09146aa, type: 2}
useThreatSystem: 1
damageThreatMultiplier: 1
threatDecayPerSecond: 0
retargetThreshold: 0
phases: []
initialBehaviorGraph: {fileID: -3933356984444701103, guid: 9ade9280028e9da4aa0151fe8e9ec454, type: 2}
phaseTransitionInvincibilityTime: 2
@@ -2149,6 +2154,8 @@ MonoBehaviour:
debugMode: 1
showAreaDebug: 1
debugDrawDuration: 1
lastCancelledSkillName:
lastCancelReason: 0
--- !u!114 &-2857689419101920665
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -2162,6 +2169,33 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Team
teamType: 2
--- !u!114 &1459274958342653187
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5581648761285601425}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c5b2d4ef2f1b4ee49b5f7f2c7175fd10, type: 3}
m_Name:
m_EditorClassIdentifier: Colosseum.Game::Colosseum.Enemy.DrogPatternController
ShowTopMostFoldoutHeaderGroup: 1
bossEnemy: {fileID: 6949205239376088310}
enemyBase: {fileID: 6949205239376088310}
skillController: {fileID: 8818883032728065057}
navMeshAgent: {fileID: 5153439431748782209}
mainPattern: {fileID: 11400000, guid: 5efd8123be76bf844875d386d9d5f73d, type: 2}
leapPattern: {fileID: 11400000, guid: 88e6cc7cab28baf4c8f8a742247000ec, type: 2}
downPunishPattern: {fileID: 11400000, guid: fe5100f855d14c0faac44b6d4f2c771e, type: 2}
phase2HealthThreshold: 0.75
phase3HealthThreshold: 0.4
targetRefreshInterval: 0.2
leapDistanceThreshold: 8
downPunishSearchRadius: 6
disableBehaviorGraph: 1
debugMode: 1
--- !u!114 &7544406269366897481
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -2177,6 +2211,7 @@ MonoBehaviour:
ShowTopMostFoldoutHeaderGroup: 1
characterStats: {fileID: 0}
networkController: {fileID: 0}
skillController: {fileID: 0}
--- !u!114 &4137653497738922896
MonoBehaviour:
m_ObjectHideFlags: 0

View File

@@ -33,6 +33,7 @@ namespace Colosseum.Enemy
// 컴포넌트
private BehaviorGraphAgent behaviorAgent;
private DrogPatternController drogPatternController;
// 페이즈 상태
private int currentPhaseIndex = 0;
@@ -77,8 +78,15 @@ namespace Colosseum.Enemy
behaviorAgent = gameObject.AddComponent<BehaviorGraphAgent>();
}
drogPatternController = GetComponent<DrogPatternController>();
// 초기 AI 설정
if (IsServer && initialBehaviorGraph != null)
if (IsServer && drogPatternController != null && drogPatternController.DisableBehaviorGraph)
{
behaviorAgent.enabled = false;
behaviorAgent.Graph = null;
}
else if (IsServer && initialBehaviorGraph != null)
{
behaviorAgent.Graph = initialBehaviorGraph;
}

View File

@@ -0,0 +1,408 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;
using Colosseum.AI;
using Colosseum.Player;
using Colosseum.Skills;
namespace Colosseum.Enemy
{
/// <summary>
/// 드로그 전용 패턴 선택 컨트롤러입니다.
/// 기본 루프, 도약, 다운 추가타 같은 고우선 패턴을 직접 선택합니다.
/// </summary>
[DisallowMultipleComponent]
[RequireComponent(typeof(BossEnemy))]
[RequireComponent(typeof(SkillController))]
public class DrogPatternController : NetworkBehaviour
{
[Header("References")]
[SerializeField] private BossEnemy bossEnemy;
[SerializeField] private EnemyBase enemyBase;
[SerializeField] private SkillController skillController;
[SerializeField] private UnityEngine.AI.NavMeshAgent navMeshAgent;
[Header("Pattern Data")]
[Tooltip("기본 근접 압박 패턴")]
[SerializeField] private BossPatternData mainPattern;
[Tooltip("먼 대상 징벌용 도약 패턴")]
[SerializeField] private BossPatternData leapPattern;
[Tooltip("다운 대상이 있을 때 우선 발동하는 광역 추가타 패턴")]
[SerializeField] private BossPatternData downPunishPattern;
[Header("Phase Thresholds")]
[Tooltip("2페이즈 진입 체력 비율")]
[Range(0f, 1f)] [SerializeField] private float phase2HealthThreshold = 0.75f;
[Tooltip("3페이즈 진입 체력 비율")]
[Range(0f, 1f)] [SerializeField] private float phase3HealthThreshold = 0.4f;
[Header("Targeting")]
[Tooltip("타겟 재탐색 주기")]
[Min(0.05f)] [SerializeField] private float targetRefreshInterval = 0.2f;
[Tooltip("도약 패턴을 고려하기 시작하는 거리")]
[Min(0f)] [SerializeField] private float leapDistanceThreshold = 8f;
[Tooltip("다운 추가타를 고려할 최대 반경")]
[Min(0f)] [SerializeField] private float downPunishSearchRadius = 6f;
[Header("Behavior")]
[Tooltip("드로그 전용 컨트롤러 사용 시 기존 BehaviorGraph를 비활성화할지 여부")]
[SerializeField] private bool disableBehaviorGraph = true;
[Tooltip("디버그 로그 출력 여부")]
[SerializeField] private bool debugMode = false;
private readonly Dictionary<BossPatternData, float> patternCooldownTracker = new Dictionary<BossPatternData, float>();
private Coroutine activePatternCoroutine;
private GameObject currentTarget;
private float nextTargetRefreshTime;
/// <summary>
/// 드로그 컨트롤러 사용 시 BehaviorGraph를 비활성화할지 여부
/// </summary>
public bool DisableBehaviorGraph => disableBehaviorGraph;
/// <summary>
/// 현재 전용 패턴 실행 중인지 여부
/// </summary>
public bool IsExecutingPattern => activePatternCoroutine != null;
/// <summary>
/// 현재 드로그 패턴 페이즈
/// </summary>
public int CurrentPatternPhase
{
get
{
float healthRatio = bossEnemy != null && bossEnemy.MaxHealth > 0f
? bossEnemy.CurrentHealth / bossEnemy.MaxHealth
: 1f;
if (healthRatio <= phase3HealthThreshold)
return 3;
if (healthRatio <= phase2HealthThreshold)
return 2;
return 1;
}
}
private void Awake()
{
ResolveReferences();
}
public override void OnNetworkSpawn()
{
ResolveReferences();
if (!IsServer)
{
enabled = false;
}
}
private void Update()
{
if (!IsServer)
return;
ResolveReferences();
if (bossEnemy == null || enemyBase == null || skillController == null)
return;
if (bossEnemy.IsDead || bossEnemy.IsTransitioning)
return;
RefreshTargetIfNeeded();
UpdateMovement();
if (activePatternCoroutine != null || skillController.IsPlayingAnimation)
return;
if (TryStartDownPunishPattern())
return;
TryStartMainPattern();
}
private bool TryStartDownPunishPattern()
{
if (!IsPatternReady(downPunishPattern))
return false;
GameObject downedTarget = FindNearestDownedTarget();
if (downedTarget == null)
return false;
StartPattern(downPunishPattern, downedTarget);
return true;
}
private bool TryStartMainPattern()
{
if (currentTarget == null)
return false;
float distanceToTarget = Vector3.Distance(transform.position, currentTarget.transform.position);
if (distanceToTarget >= leapDistanceThreshold && IsPatternReady(leapPattern))
{
StartPattern(leapPattern, currentTarget);
return true;
}
float attackRange = enemyBase.Data != null ? enemyBase.Data.AttackRange : 2f;
if (distanceToTarget <= attackRange + 0.25f && IsPatternReady(mainPattern))
{
StartPattern(mainPattern, currentTarget);
return true;
}
return false;
}
private void StartPattern(BossPatternData pattern, GameObject target)
{
if (pattern == null || activePatternCoroutine != null)
return;
if (debugMode)
{
string targetName = target != null ? target.name : "None";
Debug.Log($"[DrogPattern] 패턴 시작: {pattern.PatternName} / Target={targetName} / Phase={CurrentPatternPhase}");
}
activePatternCoroutine = StartCoroutine(RunPatternCoroutine(pattern, target));
}
private IEnumerator RunPatternCoroutine(BossPatternData pattern, GameObject target)
{
StopMovement();
bool completed = true;
BossPatternData chainedPattern = null;
GameObject chainedTarget = null;
for (int i = 0; i < pattern.Steps.Count; i++)
{
PatternStep step = pattern.Steps[i];
if (step.Type == PatternStepType.Wait)
{
yield return new WaitForSeconds(step.Duration);
continue;
}
if (step.Skill == null)
{
completed = false;
Debug.LogWarning($"[DrogPattern] 패턴 스텝 스킬이 비어 있습니다. Pattern={pattern.PatternName}, Index={i}");
break;
}
if (step.Skill.JumpToTarget && target != null)
{
enemyBase?.SetJumpTarget(target.transform.position);
}
if (!skillController.ExecuteSkill(step.Skill))
{
completed = false;
if (debugMode)
{
Debug.LogWarning($"[DrogPattern] 스킬 실행 실패: {step.Skill.SkillName}");
}
break;
}
yield return new WaitUntil(() => skillController == null || !skillController.IsPlayingAnimation || bossEnemy == null || bossEnemy.IsDead);
if (bossEnemy == null || bossEnemy.IsDead)
{
completed = false;
break;
}
if (pattern != downPunishPattern && TryPrepareDownPunishChain(out chainedTarget))
{
chainedPattern = downPunishPattern;
break;
}
}
if (completed)
{
patternCooldownTracker[pattern] = Time.time + pattern.Cooldown;
}
activePatternCoroutine = null;
if (chainedPattern != null && chainedTarget != null && bossEnemy != null && !bossEnemy.IsDead)
{
StartPattern(chainedPattern, chainedTarget);
}
}
private bool IsPatternReady(BossPatternData pattern)
{
if (pattern == null || pattern.Steps == null || pattern.Steps.Count == 0)
return false;
if (!patternCooldownTracker.TryGetValue(pattern, out float readyTime))
return true;
return Time.time >= readyTime;
}
private void RefreshTargetIfNeeded()
{
if (Time.time < nextTargetRefreshTime)
return;
nextTargetRefreshTime = Time.time + targetRefreshInterval;
GameObject highestThreatTarget = enemyBase.GetHighestThreatTarget(currentTarget, null, enemyBase.Data != null ? enemyBase.Data.AggroRange : Mathf.Infinity);
currentTarget = highestThreatTarget != null ? highestThreatTarget : FindNearestLivingPlayer();
}
private void UpdateMovement()
{
if (navMeshAgent == null || !navMeshAgent.enabled)
return;
if (activePatternCoroutine != null || (skillController != null && skillController.IsPlayingAnimation))
{
StopMovement();
return;
}
if (currentTarget == null)
{
StopMovement();
return;
}
float attackRange = enemyBase.Data != null ? enemyBase.Data.AttackRange : 2f;
float distanceToTarget = Vector3.Distance(transform.position, currentTarget.transform.position);
if (distanceToTarget <= attackRange)
{
StopMovement();
return;
}
navMeshAgent.isStopped = false;
navMeshAgent.SetDestination(currentTarget.transform.position);
}
private void StopMovement()
{
if (navMeshAgent == null || !navMeshAgent.enabled)
return;
navMeshAgent.isStopped = true;
navMeshAgent.ResetPath();
}
private GameObject FindNearestDownedTarget()
{
HitReactionController[] hitReactionControllers = FindObjectsByType<HitReactionController>(FindObjectsSortMode.None);
GameObject bestTarget = null;
float bestDistance = float.MaxValue;
for (int i = 0; i < hitReactionControllers.Length; i++)
{
HitReactionController controller = hitReactionControllers[i];
if (controller == null || !controller.IsDowned)
continue;
GameObject candidate = controller.gameObject;
if (candidate == null || !candidate.activeInHierarchy || Team.IsSameTeam(gameObject, candidate))
continue;
float distance = Vector3.Distance(transform.position, candidate.transform.position);
if (distance > downPunishSearchRadius || distance >= bestDistance)
continue;
bestDistance = distance;
bestTarget = candidate;
}
return bestTarget;
}
private bool TryPrepareDownPunishChain(out GameObject downedTarget)
{
downedTarget = null;
if (!IsPatternReady(downPunishPattern))
return false;
downedTarget = FindNearestDownedTarget();
if (downedTarget == null)
return false;
if (debugMode)
{
Debug.Log($"[DrogPattern] 다운 대상 감지, 다운 추가타 연계 준비: {downedTarget.name}");
}
return true;
}
private GameObject FindNearestLivingPlayer()
{
PlayerNetworkController[] players = FindObjectsByType<PlayerNetworkController>(FindObjectsSortMode.None);
GameObject bestTarget = null;
float bestDistance = float.MaxValue;
float aggroRange = enemyBase.Data != null ? enemyBase.Data.AggroRange : Mathf.Infinity;
for (int i = 0; i < players.Length; i++)
{
PlayerNetworkController player = players[i];
if (player == null || player.IsDead || !player.gameObject.activeInHierarchy)
continue;
GameObject candidate = player.gameObject;
if (Team.IsSameTeam(gameObject, candidate))
continue;
float distance = Vector3.Distance(transform.position, candidate.transform.position);
if (distance > aggroRange || distance >= bestDistance)
continue;
bestDistance = distance;
bestTarget = candidate;
}
return bestTarget;
}
private void ResolveReferences()
{
if (bossEnemy == null)
bossEnemy = GetComponent<BossEnemy>();
if (enemyBase == null)
enemyBase = GetComponent<EnemyBase>();
if (skillController == null)
skillController = GetComponent<SkillController>();
if (navMeshAgent == null)
navMeshAgent = GetComponent<UnityEngine.AI.NavMeshAgent>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c5b2d4ef2f1b4ee49b5f7f2c7175fd10
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -30,7 +30,11 @@ namespace Colosseum.Skills.Effects
return;
}
if (!target.TryGetComponent(out HitReactionController hitReactionController))
HitReactionController hitReactionController = target.GetComponent<HitReactionController>();
if (hitReactionController == null)
hitReactionController = target.GetComponentInParent<HitReactionController>();
if (hitReactionController == null)
{
Debug.LogWarning($"[DownEffect] HitReactionController not found on target: {target.name}");
return;

View File

@@ -0,0 +1,93 @@
using UnityEngine;
using Colosseum.Combat;
using Colosseum.Player;
using Colosseum.Stats;
using Colosseum.Weapons;
namespace Colosseum.Skills.Effects
{
/// <summary>
/// 피격 제어 상태에 따라 추가 피해를 줄 수 있는 대미지 효과입니다.
/// 현재는 다운 상태인 대상에게 추가 배율을 적용합니다.
/// </summary>
[CreateAssetMenu(fileName = "HitReactionDamageEffect", menuName = "Colosseum/Skills/Effects/HitReaction Damage")]
public class HitReactionDamageEffect : SkillEffect
{
[Header("Damage Settings")]
[Min(0f)] [SerializeField] private float baseDamage = 10f;
[SerializeField] private DamageType damageType = DamageType.Physical;
[Tooltip("스탯 계수 (1.0 = 100%)")]
[Min(0f)] [SerializeField] private float statScaling = 1f;
[Header("Hit Reaction Bonus")]
[Tooltip("다운 상태인 대상에게 추가 배율을 적용할지 여부")]
[SerializeField] private bool bonusAgainstDownedTarget = true;
[Tooltip("다운 상태 대상에게 적용되는 추가 피해 배율")]
[Min(1f)] [SerializeField] private float downedDamageMultiplier = 1.5f;
protected override void ApplyEffect(GameObject caster, GameObject target)
{
if (target == null)
return;
IDamageable damageable = target.GetComponent<IDamageable>();
if (damageable == null)
return;
float totalDamage = CalculateDamage(caster);
HitReactionController hitReactionController = target.GetComponent<HitReactionController>();
if (hitReactionController == null)
hitReactionController = target.GetComponentInParent<HitReactionController>();
if (bonusAgainstDownedTarget
&& hitReactionController != null
&& hitReactionController.IsDowned)
{
totalDamage *= downedDamageMultiplier;
}
damageable.TakeDamage(totalDamage, caster);
}
/// <summary>
/// 시전자 스탯 기반 대미지 계산
/// 공식: baseDamage + (statDamage * scaling)
/// </summary>
private float CalculateDamage(GameObject caster)
{
if (damageType == DamageType.True)
{
return baseDamage;
}
CharacterStats stats = caster != null ? caster.GetComponent<CharacterStats>() : null;
if (stats == null)
{
return baseDamage;
}
float statDamage = damageType switch
{
DamageType.Physical => stats.PhysicalDamage,
DamageType.Magical => stats.MagicDamage,
DamageType.Ranged => stats.Dexterity.FinalValue * 2f,
_ => 0f,
};
float baseTotal = baseDamage + (statDamage * statScaling);
return baseTotal * GetDamageMultiplier(caster);
}
/// <summary>
/// 시전자의 무기 데미지 배율 조회
/// </summary>
private float GetDamageMultiplier(GameObject caster)
{
WeaponEquipment weaponEquipment = caster != null ? caster.GetComponent<WeaponEquipment>() : null;
return weaponEquipment != null ? weaponEquipment.DamageMultiplier : 1f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6fd8c6f4c4454ecdb111d13dc8471024
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -28,13 +28,21 @@ namespace Colosseum.Skills.Effects
Vector3 knockbackVelocity = direction * force + Vector3.up * upwardForce;
if (target.TryGetComponent<HitReactionController>(out var hitReactionController))
HitReactionController hitReactionController = target.GetComponent<HitReactionController>();
if (hitReactionController == null)
hitReactionController = target.GetComponentInParent<HitReactionController>();
if (hitReactionController != null)
{
hitReactionController.ApplyKnockback(knockbackVelocity, duration);
return;
}
if (target.TryGetComponent<PlayerMovement>(out var playerMovement))
PlayerMovement playerMovement = target.GetComponent<PlayerMovement>();
if (playerMovement == null)
playerMovement = target.GetComponentInParent<PlayerMovement>();
if (playerMovement != null)
{
playerMovement.ApplyForcedMovement(knockbackVelocity, duration);
}