diff --git a/Assets/0.SCENE/MainGame.unity b/Assets/0.SCENE/MainGame.unity
index 666e92c0..2413d4bd 100644
--- a/Assets/0.SCENE/MainGame.unity
+++ b/Assets/0.SCENE/MainGame.unity
@@ -157294,6 +157294,50 @@ Transform:
m_CorrespondingSourceObject: {fileID: 4342764212392476, guid: 4278c6284d6d0874e930abe05bd1e995, type: 3}
m_PrefabInstance: {fileID: 288143037}
m_PrefabAsset: {fileID: 0}
+--- !u!1 &1467171476
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1467171478}
+ - component: {fileID: 1467171477}
+ m_Layer: 0
+ m_Name: BossDataManger
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &1467171477
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1467171476}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: c23a9c1b76724ab459bf32a732f6a2f7, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!4 &1467171478
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1467171476}
+ serializedVersion: 2
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &1467480949
PrefabInstance:
m_ObjectHideFlags: 0
@@ -219472,6 +219516,100 @@ Transform:
m_CorrespondingSourceObject: {fileID: 4917135111635402, guid: 4fb7e29eb03a19e4099b10ed3f307852, type: 3}
m_PrefabInstance: {fileID: 2078546377}
m_PrefabAsset: {fileID: 0}
+--- !u!1001 &2078726753
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ serializedVersion: 3
+ m_TransformParent: {fileID: 0}
+ m_Modifications:
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 22.611275
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 7.2501984
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalPosition.z
+ value: 14.457466
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalRotation.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalRotation.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalRotation.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 919132149155446097, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ propertyPath: m_Name
+ value: BossMonster3
+ objectReference: {fileID: 0}
+ m_RemovedComponents: []
+ m_RemovedGameObjects: []
+ m_AddedGameObjects: []
+ m_AddedComponents:
+ - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ insertIndex: -1
+ addedObject: {fileID: 2078726755}
+ m_SourcePrefab: {fileID: 100100000, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+--- !u!1 &2078726754 stripped
+GameObject:
+ m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 42503441aeeebad428b07b02a39d6598, type: 3}
+ m_PrefabInstance: {fileID: 2078726753}
+ m_PrefabAsset: {fileID: 0}
+--- !u!114 &2078726755
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2078726754}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 04f39bf969074e6488f84b47bd517dc9, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ optimizationDistance: 40
+ maxHP: 100
+ attackDamage: 10
+ expReward: 10
+ moveSpeed: 3.5
+ myWeapon: {fileID: 0}
+ Monster_Idle: Monster_Idle
+ Monster_GetDamage: Monster_GetDamage
+ Monster_Die: Monster_Die
+ attackRestDuration: 1.5
+ hitSound: {fileID: 0}
+ deathSound: {fileID: 0}
+ deathEffectPrefab: {fileID: 0}
+ hitEffect: {fileID: 0}
+ impactSpawnPoint: {fileID: 0}
+ counterSystem: {fileID: 0}
+ patternInterval: 3
--- !u!1001 &2078921403
PrefabInstance:
m_ObjectHideFlags: 0
@@ -228052,6 +228190,7 @@ SceneRoots:
- {fileID: 317692096}
- {fileID: 2004000787}
- {fileID: 850992421}
+ - {fileID: 1467171478}
- {fileID: 1800120326328798950}
- {fileID: 4755848957906863847}
- {fileID: 398512784}
@@ -228073,3 +228212,4 @@ SceneRoots:
- {fileID: 200768984}
- {fileID: 1759137305}
- {fileID: 198901434}
+ - {fileID: 2078726753}
diff --git a/Assets/1.myPrefab/MyMonster/BossMonster 3D model.prefab b/Assets/1.myPrefab/MyMonster/BossMonster 3D model.prefab
new file mode 100644
index 00000000..a2b437dd
--- /dev/null
+++ b/Assets/1.myPrefab/MyMonster/BossMonster 3D model.prefab
@@ -0,0 +1,101 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1001 &566391006787012280
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ serializedVersion: 3
+ m_TransformParent: {fileID: 0}
+ m_Modifications:
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 21.990122
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 8.148115
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalPosition.z
+ value: 12.154666
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalRotation.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalRotation.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalRotation.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: -8679921383154817045, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 919132149155446097, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_Name
+ value: BossMonster 3D model
+ objectReference: {fileID: 0}
+ - target: {fileID: 5866666021909216657, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ propertyPath: m_Controller
+ value:
+ objectReference: {fileID: 9100000, guid: b207531287111e74d890e730f7278dfa, type: 2}
+ m_RemovedComponents: []
+ m_RemovedGameObjects: []
+ m_AddedGameObjects: []
+ m_AddedComponents:
+ - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ insertIndex: -1
+ addedObject: {fileID: 8863122437628348909}
+ m_SourcePrefab: {fileID: 100100000, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+--- !u!1 &800884610308848617 stripped
+GameObject:
+ m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 1cbe1e69b0d0be345be0872afa3e381e, type: 3}
+ m_PrefabInstance: {fileID: 566391006787012280}
+ m_PrefabAsset: {fileID: 0}
+--- !u!114 &8863122437628348909
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 800884610308848617}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 04f39bf969074e6488f84b47bd517dc9, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ optimizationDistance: 40
+ maxHP: 100
+ attackDamage: 10
+ expReward: 10
+ moveSpeed: 3.5
+ myWeapon: {fileID: 0}
+ Monster_Idle: Monster_Idle
+ Monster_GetDamage: Monster_GetDamage
+ Monster_Die: Monster_Die
+ attackRestDuration: 1.5
+ hitSound: {fileID: 0}
+ deathSound: {fileID: 0}
+ deathEffectPrefab: {fileID: 0}
+ hitEffect: {fileID: 0}
+ impactSpawnPoint: {fileID: 0}
+ counterSystem: {fileID: 0}
+ patternInterval: 3
+ bossHealthBar: {fileID: 0}
diff --git a/Assets/1.myPrefab/MyMonster/BossMonster 3D model.prefab.meta b/Assets/1.myPrefab/MyMonster/BossMonster 3D model.prefab.meta
new file mode 100644
index 00000000..2521b3ee
--- /dev/null
+++ b/Assets/1.myPrefab/MyMonster/BossMonster 3D model.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: bbcb1e950f1b5a24881632ef960a27aa
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/1.myPrefab/MyMonster/BossMonsterAnimater.controller b/Assets/1.myPrefab/MyMonster/BossMonsterAnimater.controller
new file mode 100644
index 00000000..78363cd2
--- /dev/null
+++ b/Assets/1.myPrefab/MyMonster/BossMonsterAnimater.controller
@@ -0,0 +1,43 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!91 &9100000
+AnimatorController:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name: BossMonsterAnimater
+ serializedVersion: 5
+ m_AnimatorParameters: []
+ m_AnimatorLayers:
+ - serializedVersion: 5
+ m_Name: Base Layer
+ m_StateMachine: {fileID: 7444453749730313805}
+ m_Mask: {fileID: 0}
+ m_Motions: []
+ m_Behaviours: []
+ m_BlendingMode: 0
+ m_SyncedLayerIndex: -1
+ m_DefaultWeight: 0
+ m_IKPass: 0
+ m_SyncedLayerAffectsTiming: 0
+ m_Controller: {fileID: 9100000}
+--- !u!1107 &7444453749730313805
+AnimatorStateMachine:
+ serializedVersion: 6
+ m_ObjectHideFlags: 1
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name: Base Layer
+ m_ChildStates: []
+ m_ChildStateMachines: []
+ m_AnyStateTransitions: []
+ m_EntryTransitions: []
+ m_StateMachineTransitions: {}
+ m_StateMachineBehaviours: []
+ m_AnyStatePosition: {x: 50, y: 20, z: 0}
+ m_EntryPosition: {x: 50, y: 120, z: 0}
+ m_ExitPosition: {x: 510, y: 310, z: 0}
+ m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
+ m_DefaultState: {fileID: 0}
diff --git a/Assets/1.myPrefab/MyMonster/BossMonsterAnimater.controller.meta b/Assets/1.myPrefab/MyMonster/BossMonsterAnimater.controller.meta
new file mode 100644
index 00000000..051c9cc5
--- /dev/null
+++ b/Assets/1.myPrefab/MyMonster/BossMonsterAnimater.controller.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b207531287111e74d890e730f7278dfa
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 9100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/1.myPrefab/MyMonster/RushMonster2.prefab b/Assets/1.myPrefab/MyMonster/RushMonster2.prefab
index 79a067e2..19e52fa0 100644
--- a/Assets/1.myPrefab/MyMonster/RushMonster2.prefab
+++ b/Assets/1.myPrefab/MyMonster/RushMonster2.prefab
@@ -900,6 +900,7 @@ MonoBehaviour:
prepareTime: 3
dropItemPrefabs:
- {fileID: 791703799912573729, guid: e9867839af14eb14ca3d49ee41fc5390, type: 3}
+ - {fileID: 1171483609561952824, guid: 5d18660a7620e4e48bb1462c7e0e1187, type: 3}
dropChance: 100
chargeAnimation: Run-run
prepareAnimation: Run-wait
diff --git a/Assets/1.myPrefab/New Random Stat Card Data 1.asset b/Assets/1.myPrefab/New Random Stat Card Data 1.asset
index 548c9f4e..4fc69279 100644
--- a/Assets/1.myPrefab/New Random Stat Card Data 1.asset
+++ b/Assets/1.myPrefab/New Random Stat Card Data 1.asset
@@ -13,6 +13,7 @@ MonoBehaviour:
m_Name: New Random Stat Card Data 1
m_EditorClassIdentifier:
icon: {fileID: 21300000, guid: 15546573e2e8b0c489f921128d1e5073, type: 3}
- possibleStats: 0200000000000000
+ requiredObsessionLevel: 1
+ possibleStats: 020000000000000001000000
minValue: -30
maxValue: 1
diff --git a/Assets/1.myPrefab/New Random Stat Card Data.asset b/Assets/1.myPrefab/New Random Stat Card Data.asset
index 5ec0c0bf..ef467ef2 100644
--- a/Assets/1.myPrefab/New Random Stat Card Data.asset
+++ b/Assets/1.myPrefab/New Random Stat Card Data.asset
@@ -13,6 +13,7 @@ MonoBehaviour:
m_Name: New Random Stat Card Data
m_EditorClassIdentifier:
icon: {fileID: 21300000, guid: 15546573e2e8b0c489f921128d1e5073, type: 3}
- possibleStats: 03000000010000000000000002000000
+ requiredObsessionLevel: 1
+ possibleStats: 020000000100000000000000
minValue: -10
maxValue: 1
diff --git a/Assets/1.myPrefab/Player.prefab b/Assets/1.myPrefab/Player.prefab
index 18b98899..aa21d6b8 100644
--- a/Assets/1.myPrefab/Player.prefab
+++ b/Assets/1.myPrefab/Player.prefab
@@ -1231,6 +1231,9 @@ PrefabInstance:
insertIndex: -1
addedObject: {fileID: 7115393052906583336}
m_AddedComponents:
+ - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
+ insertIndex: -1
+ addedObject: {fileID: -903076858900737616}
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
insertIndex: -1
addedObject: {fileID: 8017155627325348063}
@@ -1270,6 +1273,19 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 76cee5628aa6b874c96342f004fa138b, type: 3}
m_PrefabInstance: {fileID: 1112926104530361804}
m_PrefabAsset: {fileID: 0}
+--- !u!114 &-903076858900737616
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 265854990890279069}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 320dac90fad4bd94dbdc466f5f2458cd, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ windowDuration: 10
--- !u!114 &8017155627325348063
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -1367,6 +1383,7 @@ MonoBehaviour:
stats: {fileID: 395629277865203624}
animator: {fileID: 6781151982184439901}
attackScript: {fileID: 0}
+ bossPattern: {fileID: 0}
isInvincible: 0
--- !u!114 &7686364893196566162
MonoBehaviour:
diff --git a/Assets/3D Assets/BossMonster 3D model.fbx b/Assets/3D Assets/BossMonster 3D model.fbx
new file mode 100644
index 00000000..3e3074ed
Binary files /dev/null and b/Assets/3D Assets/BossMonster 3D model.fbx differ
diff --git a/Assets/3D Assets/BossMonster 3D model.fbx.meta b/Assets/3D Assets/BossMonster 3D model.fbx.meta
new file mode 100644
index 00000000..d8fc4f3f
--- /dev/null
+++ b/Assets/3D Assets/BossMonster 3D model.fbx.meta
@@ -0,0 +1,109 @@
+fileFormatVersion: 2
+guid: 1cbe1e69b0d0be345be0872afa3e381e
+ModelImporter:
+ serializedVersion: 22200
+ internalIDToNameTable: []
+ externalObjects: {}
+ materials:
+ materialImportMode: 2
+ materialName: 0
+ materialSearch: 1
+ materialLocation: 1
+ animations:
+ legacyGenerateAnimations: 4
+ bakeSimulation: 0
+ resampleCurves: 1
+ optimizeGameObjects: 0
+ removeConstantScaleCurves: 0
+ motionNodeName:
+ rigImportErrors:
+ rigImportWarnings:
+ animationImportErrors:
+ animationImportWarnings:
+ animationRetargetingWarnings:
+ animationDoRetargetingWarnings: 0
+ importAnimatedCustomProperties: 0
+ importConstraints: 0
+ animationCompression: 3
+ animationRotationError: 0.5
+ animationPositionError: 0.5
+ animationScaleError: 0.5
+ animationWrapMode: 0
+ extraExposedTransformPaths: []
+ extraUserProperties: []
+ clipAnimations: []
+ isReadable: 0
+ meshes:
+ lODScreenPercentages: []
+ globalScale: 1
+ meshCompression: 0
+ addColliders: 0
+ useSRGBMaterialColor: 1
+ sortHierarchyByName: 1
+ importPhysicalCameras: 1
+ importVisibility: 1
+ importBlendShapes: 1
+ importCameras: 1
+ importLights: 1
+ nodeNameCollisionStrategy: 1
+ fileIdsGeneration: 2
+ swapUVChannels: 0
+ generateSecondaryUV: 0
+ useFileUnits: 1
+ keepQuads: 0
+ weldVertices: 1
+ bakeAxisConversion: 0
+ preserveHierarchy: 0
+ skinWeightsMode: 0
+ maxBonesPerVertex: 4
+ minBoneWeight: 0.001
+ optimizeBones: 1
+ meshOptimizationFlags: -1
+ indexFormat: 0
+ secondaryUVAngleDistortion: 8
+ secondaryUVAreaDistortion: 15.000001
+ secondaryUVHardAngle: 88
+ secondaryUVMarginMethod: 1
+ secondaryUVMinLightmapResolution: 40
+ secondaryUVMinObjectScale: 1
+ secondaryUVPackMargin: 4
+ useFileScale: 1
+ strictVertexDataChecks: 0
+ tangentSpace:
+ normalSmoothAngle: 60
+ normalImportMode: 0
+ tangentImportMode: 3
+ normalCalculationMode: 4
+ legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
+ blendShapeNormalImportMode: 1
+ normalSmoothingSource: 0
+ referencedClips: []
+ importAnimation: 1
+ humanDescription:
+ serializedVersion: 3
+ human: []
+ skeleton: []
+ armTwist: 0.5
+ foreArmTwist: 0.5
+ upperLegTwist: 0.5
+ legTwist: 0.5
+ armStretch: 0.05
+ legStretch: 0.05
+ feetSpacing: 0
+ globalScale: 1
+ rootMotionBoneName:
+ hasTranslationDoF: 0
+ hasExtraRoot: 1
+ skeletonHasParents: 1
+ lastHumanDescriptionAvatarSource: {instanceID: 0}
+ autoGenerateAvatarMappingIfUnspecified: 1
+ animationType: 3
+ humanoidOversampling: 1
+ avatarSetup: 1
+ addHumanoidExtraRootOnlyWhenUsingAvatar: 1
+ importBlendShapeDeformPercent: 1
+ remapMaterialsIfMaterialImportModeIsNone: 0
+ additionalBone: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/3D Assets/material0_basecolor.jpg b/Assets/3D Assets/material0_basecolor.jpg
new file mode 100644
index 00000000..b2f973d4
Binary files /dev/null and b/Assets/3D Assets/material0_basecolor.jpg differ
diff --git a/Assets/3D Assets/material0_basecolor.jpg.meta b/Assets/3D Assets/material0_basecolor.jpg.meta
new file mode 100644
index 00000000..9d0fdaee
--- /dev/null
+++ b/Assets/3D Assets/material0_basecolor.jpg.meta
@@ -0,0 +1,114 @@
+fileFormatVersion: 2
+guid: bb7a32e0d6762f34f881755d070ffcf8
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 0
+ wrapV: 0
+ wrapW: 0
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 0
+ spriteTessellationDetail: -1
+ textureType: 0
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID:
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/4.PlayerAnimation/ThrowAnimation_Boss_BoyFBX.fbx b/Assets/4.PlayerAnimation/ThrowAnimation_Boss_BoyFBX.fbx
new file mode 100644
index 00000000..9733dd5f
Binary files /dev/null and b/Assets/4.PlayerAnimation/ThrowAnimation_Boss_BoyFBX.fbx differ
diff --git a/Assets/4.PlayerAnimation/ThrowAnimation_Boss_BoyFBX.fbx.meta b/Assets/4.PlayerAnimation/ThrowAnimation_Boss_BoyFBX.fbx.meta
new file mode 100644
index 00000000..761dbe2e
--- /dev/null
+++ b/Assets/4.PlayerAnimation/ThrowAnimation_Boss_BoyFBX.fbx.meta
@@ -0,0 +1,991 @@
+fileFormatVersion: 2
+guid: 04227e99d65ec83448222e5a50c69dae
+ModelImporter:
+ serializedVersion: 22200
+ internalIDToNameTable: []
+ externalObjects: {}
+ materials:
+ materialImportMode: 2
+ materialName: 0
+ materialSearch: 1
+ materialLocation: 1
+ animations:
+ legacyGenerateAnimations: 4
+ bakeSimulation: 0
+ resampleCurves: 1
+ optimizeGameObjects: 0
+ removeConstantScaleCurves: 0
+ motionNodeName:
+ rigImportErrors:
+ rigImportWarnings:
+ animationImportErrors:
+ animationImportWarnings: "\nClip 'Take 001' has import animation warnings that
+ might lower retargeting quality:\nNote: Activate translation DOF on avatar
+ to improve retargeting quality.\n\t'Bip001 Spine' has translation animation
+ that will be discarded.\n\t'Bip001 Spine1' has translation animation that will
+ be discarded.\n\t'Bip001 Spine2' has translation animation that will be discarded.\n\t'Bip001
+ Neck' has translation animation that will be discarded.\n\t'Bip001 Head' has
+ translation animation that will be discarded.\n\t'Bip001 L Clavicle' has translation
+ animation that will be discarded.\n\t'Bip001 L UpperArm' has translation animation
+ that will be discarded.\n\t'Bip001 L Forearm' has translation animation that
+ will be discarded.\n\t'Bip001 L Hand' has translation animation that will be
+ discarded.\n\t'Bip001 L Finger0' has translation animation that will be discarded.\n\t'Bip001
+ L Finger01' has translation animation that will be discarded.\n\t'Bip001 L
+ Finger02' has translation animation that will be discarded.\n\t'Bip001 L Finger1'
+ has translation animation that will be discarded.\n\t'Bip001 L Finger11' has
+ translation animation that will be discarded.\n\t'Bip001 L Finger12' has translation
+ animation that will be discarded.\n\t'Bip001 L Finger2' has translation animation
+ that will be discarded.\n\t'Bip001 L Finger21' has translation animation that
+ will be discarded.\n\t'Bip001 L Finger22' has translation animation that will
+ be discarded.\n\t'Bip001 L Finger3' has translation animation that will be
+ discarded.\n\t'Bip001 L Finger31' has translation animation that will be discarded.\n\t'Bip001
+ L Finger32' has translation animation that will be discarded.\n\t'Bip001 L
+ Finger4' has translation animation that will be discarded.\n\t'Bip001 L Finger41'
+ has translation animation that will be discarded.\n\t'Bip001 L Finger42' has
+ translation animation that will be discarded.\n\t'Bip001 R Clavicle' has translation
+ animation that will be discarded.\n\t'Bip001 R UpperArm' has translation animation
+ that will be discarded.\n\t'Bip001 R Forearm' has translation animation that
+ will be discarded.\n\t'Bip001 R Hand' has translation animation that will be
+ discarded.\n\t'Bip001 R Finger0' has translation animation that will be discarded.\n\t'Bip001
+ R Finger01' has translation animation that will be discarded.\n\t'Bip001 R
+ Finger02' has translation animation that will be discarded.\n\t'Bip001 R Finger1'
+ has translation animation that will be discarded.\n\t'Bip001 R Finger11' has
+ translation animation that will be discarded.\n\t'Bip001 R Finger12' has translation
+ animation that will be discarded.\n\t'Bip001 R Finger2' has translation animation
+ that will be discarded.\n\t'Bip001 R Finger21' has translation animation that
+ will be discarded.\n\t'Bip001 R Finger22' has translation animation that will
+ be discarded.\n\t'Bip001 R Finger3' has translation animation that will be
+ discarded.\n\t'Bip001 R Finger31' has translation animation that will be discarded.\n\t'Bip001
+ R Finger32' has translation animation that will be discarded.\n\t'Bip001 R
+ Finger4' has translation animation that will be discarded.\n\t'Bip001 R Finger41'
+ has translation animation that will be discarded.\n\t'Bip001 R Finger42' has
+ translation animation that will be discarded.\n\t'Bip001 L Thigh' has translation
+ animation that will be discarded.\n\t'Bip001 L Calf' has translation animation
+ that will be discarded.\n\t'Bip001 L Foot' has translation animation that will
+ be discarded.\n\t'Bip001 L Toe0' has translation animation that will be discarded.\n\t'Bip001
+ R Thigh' has translation animation that will be discarded.\n\t'Bip001 R Calf'
+ has translation animation that will be discarded.\n\t'Bip001 R Foot' has translation
+ animation that will be discarded.\n\t'Bip001 R Toe0' has translation animation
+ that will be discarded.\n"
+ animationRetargetingWarnings:
+ animationDoRetargetingWarnings: 0
+ importAnimatedCustomProperties: 0
+ importConstraints: 0
+ animationCompression: 3
+ animationRotationError: 0.5
+ animationPositionError: 0.5
+ animationScaleError: 0.5
+ animationWrapMode: 0
+ extraExposedTransformPaths: []
+ extraUserProperties: []
+ clipAnimations:
+ - serializedVersion: 16
+ name: Take 001
+ takeName: Take 001
+ internalID: 1827226128182048838
+ firstFrame: 0
+ lastFrame: 204
+ wrapMode: 0
+ orientationOffsetY: 0
+ level: 0
+ cycleOffset: 0
+ loop: 0
+ hasAdditiveReferencePose: 0
+ loopTime: 0
+ loopBlend: 0
+ loopBlendOrientation: 0
+ loopBlendPositionY: 1
+ loopBlendPositionXZ: 0
+ keepOriginalOrientation: 1
+ keepOriginalPositionY: 1
+ keepOriginalPositionXZ: 1
+ heightFromFeet: 0
+ mirror: 0
+ bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
+ curves: []
+ events: []
+ transformMask: []
+ maskType: 3
+ maskSource: {instanceID: 0}
+ additiveReferencePoseFrame: 0
+ isReadable: 0
+ meshes:
+ lODScreenPercentages: []
+ globalScale: 1
+ meshCompression: 0
+ addColliders: 0
+ useSRGBMaterialColor: 1
+ sortHierarchyByName: 1
+ importPhysicalCameras: 1
+ importVisibility: 1
+ importBlendShapes: 1
+ importCameras: 1
+ importLights: 1
+ nodeNameCollisionStrategy: 1
+ fileIdsGeneration: 2
+ swapUVChannels: 0
+ generateSecondaryUV: 0
+ useFileUnits: 1
+ keepQuads: 0
+ weldVertices: 1
+ bakeAxisConversion: 0
+ preserveHierarchy: 0
+ skinWeightsMode: 0
+ maxBonesPerVertex: 4
+ minBoneWeight: 0.001
+ optimizeBones: 1
+ meshOptimizationFlags: -1
+ indexFormat: 0
+ secondaryUVAngleDistortion: 8
+ secondaryUVAreaDistortion: 15.000001
+ secondaryUVHardAngle: 88
+ secondaryUVMarginMethod: 1
+ secondaryUVMinLightmapResolution: 40
+ secondaryUVMinObjectScale: 1
+ secondaryUVPackMargin: 4
+ useFileScale: 1
+ strictVertexDataChecks: 0
+ tangentSpace:
+ normalSmoothAngle: 60
+ normalImportMode: 0
+ tangentImportMode: 3
+ normalCalculationMode: 4
+ legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
+ blendShapeNormalImportMode: 1
+ normalSmoothingSource: 0
+ referencedClips: []
+ importAnimation: 1
+ humanDescription:
+ serializedVersion: 3
+ human:
+ - boneName: Bip001
+ humanName: Hips
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Thigh
+ humanName: LeftUpperLeg
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Thigh
+ humanName: RightUpperLeg
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Calf
+ humanName: LeftLowerLeg
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Calf
+ humanName: RightLowerLeg
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Foot
+ humanName: LeftFoot
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Foot
+ humanName: RightFoot
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 Spine
+ humanName: Spine
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 Spine1
+ humanName: Chest
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 Neck
+ humanName: Neck
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 Head
+ humanName: Head
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Clavicle
+ humanName: LeftShoulder
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Clavicle
+ humanName: RightShoulder
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L UpperArm
+ humanName: LeftUpperArm
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R UpperArm
+ humanName: RightUpperArm
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Forearm
+ humanName: LeftLowerArm
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Forearm
+ humanName: RightLowerArm
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Hand
+ humanName: LeftHand
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Hand
+ humanName: RightHand
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Toe0
+ humanName: LeftToes
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Toe0
+ humanName: RightToes
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger1
+ humanName: Left Thumb Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger11
+ humanName: Left Thumb Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger12
+ humanName: Left Thumb Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger0
+ humanName: Left Index Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger01
+ humanName: Left Index Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger02
+ humanName: Left Index Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger4
+ humanName: Left Middle Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger41
+ humanName: Left Middle Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger42
+ humanName: Left Middle Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger3
+ humanName: Left Ring Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger31
+ humanName: Left Ring Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger32
+ humanName: Left Ring Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger2
+ humanName: Left Little Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger21
+ humanName: Left Little Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 L Finger22
+ humanName: Left Little Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger1
+ humanName: Right Thumb Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger11
+ humanName: Right Thumb Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger12
+ humanName: Right Thumb Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger0
+ humanName: Right Index Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger01
+ humanName: Right Index Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger02
+ humanName: Right Index Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger2
+ humanName: Right Middle Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger21
+ humanName: Right Middle Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger22
+ humanName: Right Middle Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger3
+ humanName: Right Ring Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger31
+ humanName: Right Ring Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger32
+ humanName: Right Ring Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger4
+ humanName: Right Little Proximal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger41
+ humanName: Right Little Intermediate
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 R Finger42
+ humanName: Right Little Distal
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ - boneName: Bip001 Spine2
+ humanName: UpperChest
+ limit:
+ min: {x: 0, y: 0, z: 0}
+ max: {x: 0, y: 0, z: 0}
+ value: {x: 0, y: 0, z: 0}
+ length: 0
+ modified: 0
+ skeleton:
+ - name: ThrowAnimation_Boss_BoyFBX(Clone)
+ parentName:
+ position: {x: 0, y: 0, z: 0}
+ rotation: {x: 0, y: 0, z: 0, w: 1}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Socks
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: -0, y: 0, z: -0.000000038146972}
+ rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Eye
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Head
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Gloves
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: -0, y: 0, z: -0.00000014185905}
+ rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Shoes
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Jacket
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Hair
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Pants
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Bip001
+ parentName: ThrowAnimation_Boss_BoyFBX(Clone)
+ position: {x: 0.000089325615, y: 0.8913384, z: 0.0001307253}
+ rotation: {x: -0.34501126, y: 0.5415012, z: 0.58973247, w: 0.48985636}
+ scale: {x: 0.99999994, y: 1, z: 1}
+ - name: Bip001 Footsteps
+ parentName: Bip001
+ position: {x: -0.17585585, y: -0.057175994, z: -0.8414508}
+ rotation: {x: -0.10242095, y: 0.034104656, z: -0.79990304, w: 0.59034055}
+ scale: {x: 1.0000001, y: 1.0000004, z: 1.0000001}
+ - name: Bip001 Pelvis
+ parentName: Bip001
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: -0.39331752, y: 0.63804, z: 0.44154865, w: 0.4931948}
+ scale: {x: 0.99999994, y: 0.9999999, z: 1.0000001}
+ - name: Bip001 Spine
+ parentName: Bip001
+ position: {x: 0.0000824356, y: 0.0000013160706, z: 0.0769754}
+ rotation: {x: 0.39331853, y: -0.6380391, z: -0.44154996, w: -0.49319398}
+ scale: {x: 1.0000004, y: 1.0000005, z: 1.0000002}
+ - name: Bip001 Spine1
+ parentName: Bip001 Spine
+ position: {x: -0.109362714, y: -0.00007510185, z: 0.000002260208}
+ rotation: {x: -0.000000074505806, y: 0.00000017881393, z: -0, w: 1}
+ scale: {x: 1, y: 0.99999994, z: 1}
+ - name: Bip001 Spine2
+ parentName: Bip001 Spine1
+ position: {x: -0.09437401, y: -0.00016386986, z: 0.000004997253}
+ rotation: {x: -0, y: -0, z: -0, w: 1}
+ scale: {x: 0.99999994, y: 1, z: 0.9999999}
+ - name: Bip001 Neck
+ parentName: Bip001 Spine2
+ position: {x: -0.30066803, y: -0.019272458, z: -0.000000107884404}
+ rotation: {x: -0.000000059604645, y: 0.000000059604645, z: -0, w: 1}
+ scale: {x: 1, y: 0.99999994, z: 1.0000002}
+ - name: Bip001 Head
+ parentName: Bip001 Neck
+ position: {x: -0.06684417, y: -0.000000038146972, z: 0}
+ rotation: {x: -0.00000008940697, y: -0.00000005960464, z: -0.000000029802358, w: 1}
+ scale: {x: 1.0000007, y: 1.0000007, z: 1.0000013}
+ - name: Bip001 HeadNub
+ parentName: Bip001 Head
+ position: {x: -0.22498488, y: 0, z: 0}
+ rotation: {x: -2.3283064e-10, y: -8.6736174e-19, z: 0.0000000037252903, w: 1}
+ scale: {x: 0.9999999, y: 0.9999999, z: 0.99999994}
+ - name: Bip001 L Clavicle
+ parentName: Bip001 Spine2
+ position: {x: -0.23186554, y: -0.0068668723, z: 0.03048319}
+ rotation: {x: -0.705454, y: -0.057321876, z: 0.7041411, w: 0.05687063}
+ scale: {x: 1.0000002, y: 1.0000001, z: 0.99999994}
+ - name: Bip001 L UpperArm
+ parentName: Bip001 L Clavicle
+ position: {x: -0.15688339, y: -0.000000007152557, z: 0}
+ rotation: {x: -0.00019042748, y: 0.0049661174, z: 0.1179365, w: 0.99300873}
+ scale: {x: 0.99999994, y: 1.0000002, z: 1.0000007}
+ - name: Bip001 L Forearm
+ parentName: Bip001 L UpperArm
+ position: {x: -0.2145063, y: 0, z: 0.000000038146972}
+ rotation: {x: 0.000000029802322, y: 0.000000035652192, z: 0.0013483746, w: 0.99999917}
+ scale: {x: 1, y: 0.9999998, z: 1}
+ - name: Bip001 L Hand
+ parentName: Bip001 L Forearm
+ position: {x: -0.23720428, y: -0.000000019073486, z: 0}
+ rotation: {x: -0.4447016, y: 0.06362462, z: -0.3355158, w: 0.8280227}
+ scale: {x: 1, y: 1.0000011, z: 1.0000004}
+ - name: Bip001 L Finger0
+ parentName: Bip001 L Hand
+ position: {x: -0.02183136, y: 0.014335327, z: -0.031267326}
+ rotation: {x: 0.4188472, y: 0.10403948, z: -0.066113874, w: 0.899651}
+ scale: {x: 0.9999998, y: 0.99999994, z: 1.0000001}
+ - name: Bip001 L Finger01
+ parentName: Bip001 L Finger0
+ position: {x: -0.029194182, y: 0.000000019073486, z: 0.000000019073486}
+ rotation: {x: 0.000000089406946, y: 0.000000014901158, z: -0.000000014901158, w: 1}
+ scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001}
+ - name: Bip001 L Finger02
+ parentName: Bip001 L Finger01
+ position: {x: -0.025641555, y: -0.000000019073486, z: 0}
+ rotation: {x: 0.000000029802305, y: -0.000000044703484, z: -0.00000013411041, w: 1}
+ scale: {x: 1.0000002, y: 1.0000007, z: 1}
+ - name: Bip001 L Finger0Nub
+ parentName: Bip001 L Finger02
+ position: {x: -0.024530564, y: 0, z: 0.000000038146972}
+ rotation: {x: -0.000000011175871, y: 0, z: -0, w: 1}
+ scale: {x: 1, y: 1, z: 1}
+ - name: Bip001 L Finger2
+ parentName: Bip001 L Hand
+ position: {x: -0.08869598, y: -0.0009292602, z: -0.008032665}
+ rotation: {x: -0.0088504525, y: 0.10908988, z: -0.00029446918, w: 0.9939925}
+ scale: {x: 1.0000001, y: 0.9999998, z: 1}
+ - name: Bip001 L Finger21
+ parentName: Bip001 L Finger2
+ position: {x: -0.035237882, y: 0.000000019073486, z: 0}
+ rotation: {x: -0.000000033061948, y: -0.00000014528631, z: 2.6193445e-10, w: 1}
+ scale: {x: 1.0000004, y: 0.99999994, z: 1.0000004}
+ - name: Bip001 L Finger22
+ parentName: Bip001 L Finger21
+ position: {x: -0.028829575, y: -0.000000038146972, z: 0}
+ rotation: {x: 0.000000033061948, y: 0.00000014528631, z: 0.0000000010622896, w: 1}
+ scale: {x: 1.0000006, y: 1.0000002, z: 1.0000001}
+ - name: Bip001 L Finger2Nub
+ parentName: Bip001 L Finger22
+ position: {x: -0.022979412, y: 0, z: 0}
+ rotation: {x: 0.0000000074505815, y: 0.000000016763805, z: -0.000000007450581, w: 1}
+ scale: {x: 1, y: 0.9999999, z: 0.99999994}
+ - name: Bip001 L Finger1
+ parentName: Bip001 L Hand
+ position: {x: -0.08566628, y: 0.0019595718, z: -0.030115388}
+ rotation: {x: 0.042771712, y: -0.08654338, z: 0.16646817, w: 0.9813099}
+ scale: {x: 1, y: 0.99999994, z: 1}
+ - name: Bip001 L Finger11
+ parentName: Bip001 L Finger1
+ position: {x: -0.03399338, y: 0.000000009536743, z: -0.000000009536743}
+ rotation: {x: 0.0000000037252894, y: -0.000000033527606, z: -0.000000028521747, w: 1}
+ scale: {x: 1.0000002, y: 0.99999994, z: 1.0000001}
+ - name: Bip001 L Finger12
+ parentName: Bip001 L Finger11
+ position: {x: -0.024710998, y: 0.000000019073486, z: -0.000000009536743}
+ rotation: {x: -0, y: -0, z: 1.2490004e-16, w: 1}
+ scale: {x: 1.0000001, y: 0.99999994, z: 1.0000004}
+ - name: Bip001 L Finger1Nub
+ parentName: Bip001 L Finger12
+ position: {x: -0.02008175, y: 0, z: 0}
+ rotation: {x: -0.0000000037252907, y: -0.000000013038517, z: -4.857227e-17, w: 1}
+ scale: {x: 0.9999999, y: 0.9999998, z: 0.9999998}
+ - name: Bip001 L Finger3
+ parentName: Bip001 L Hand
+ position: {x: -0.08759277, y: 0.000010223388, z: 0.012853202}
+ rotation: {x: -0.01829287, y: 0.107390136, z: -0.0058450163, w: 0.99403155}
+ scale: {x: 1, y: 0.9999998, z: 0.99999994}
+ - name: Bip001 L Finger31
+ parentName: Bip001 L Finger3
+ position: {x: -0.034347076, y: 0.000000019073486, z: 0.000000009536743}
+ rotation: {x: -0.00000002793967, y: 0.00000005960463, z: -1.16415294e-10, w: 1}
+ scale: {x: 1.0000006, y: 0.9999998, z: 0.9999998}
+ - name: Bip001 L Finger32
+ parentName: Bip001 L Finger31
+ position: {x: -0.028483544, y: -0.000000076293944, z: 0}
+ rotation: {x: 0.00000002793967, y: -0.00000005960463, z: 1.16415294e-10, w: 1}
+ scale: {x: 0.99999994, y: 1.0000001, z: 1.0000005}
+ - name: Bip001 L Finger3Nub
+ parentName: Bip001 L Finger32
+ position: {x: -0.022639636, y: 0, z: 0.000000019073486}
+ rotation: {x: 9.3132246e-10, y: 0.0000000091968095, z: -8.5651955e-18, w: 1}
+ scale: {x: 1.0000001, y: 1, z: 1.0000001}
+ - name: Bip001 L Finger4
+ parentName: Bip001 L Hand
+ position: {x: -0.07877823, y: 0.0028040314, z: 0.030893011}
+ rotation: {x: -0.029101618, y: 0.10210211, z: -0.018447932, w: 0.994177}
+ scale: {x: 1.0000002, y: 0.99999994, z: 1}
+ - name: Bip001 L Finger41
+ parentName: Bip001 L Finger4
+ position: {x: -0.027974395, y: -0.000000019073486, z: 0}
+ rotation: {x: 0.00000007264315, y: 0.00000005960463, z: 0.000000010011715, w: 1}
+ scale: {x: 1.0000004, y: 0.9999998, z: 1.0000005}
+ - name: Bip001 L Finger42
+ parentName: Bip001 L Finger41
+ position: {x: -0.021889571, y: -0.000000038146972, z: -0.000000019073486}
+ rotation: {x: -0.00000007264315, y: -0.00000005960463, z: -0.000000009080393, w: 1}
+ scale: {x: 1, y: 0.99999994, z: 1.0000005}
+ - name: Bip001 L Finger4Nub
+ parentName: Bip001 L Finger42
+ position: {x: -0.01619625, y: 0, z: 0}
+ rotation: {x: 3.2065286e-17, y: -0.000000009837096, z: 0.0000000032596292, w: 1}
+ scale: {x: 0.9999999, y: 1, z: 1}
+ - name: Bip001 L ForeTwist
+ parentName: Bip001 L Forearm
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: 1.57776e-11, y: 0.000000011699727, z: -0.0000000114087015, w: 1}
+ scale: {x: 1.0000004, y: 1.0000007, z: 1.0000006}
+ - name: Bip001 R Clavicle
+ parentName: Bip001 Spine2
+ position: {x: -0.23186538, y: -0.0068666814, z: -0.030483061}
+ rotation: {x: 0.70322347, y: 0.05756271, z: 0.70635873, w: 0.056750953}
+ scale: {x: 1.0000002, y: 1.0000001, z: 0.99999994}
+ - name: Bip001 R UpperArm
+ parentName: Bip001 R Clavicle
+ position: {x: -0.15688334, y: -0.0000000023841857, z: -0.00000015258789}
+ rotation: {x: 0.00096321857, y: -0.0035985468, z: -0.04355907, w: -0.99904394}
+ scale: {x: 1.0000002, y: 1, z: 1.0000005}
+ - name: Bip001 R Forearm
+ parentName: Bip001 R UpperArm
+ position: {x: -0.21450637, y: 0, z: 0}
+ rotation: {x: 0.000000024707944, y: -9.749783e-10, z: 0.0007118039, w: 0.9999998}
+ scale: {x: 0.99999994, y: 0.9999998, z: 0.99999994}
+ - name: Bip001 R Hand
+ parentName: Bip001 R Forearm
+ position: {x: -0.23720436, y: -0.000000019073486, z: 0.000000038146972}
+ rotation: {x: -0.61243856, y: 0.08376613, z: 0.005410347, w: -0.78604895}
+ scale: {x: 1.0000002, y: 1.0000007, z: 1}
+ - name: Bip001 R Finger0
+ parentName: Bip001 R Hand
+ position: {x: -0.021831436, y: 0.014335327, z: 0.031267323}
+ rotation: {x: -0.4211995, y: 0.11073542, z: 0.04821671, w: 0.8988904}
+ scale: {x: 1.0000001, y: 0.99999994, z: 1}
+ - name: Bip001 R Finger01
+ parentName: Bip001 R Finger0
+ position: {x: -0.029194182, y: 0, z: 0}
+ rotation: {x: 0.00000014901158, y: -0.00000005960463, z: 0.000000044703473, w: 1}
+ scale: {x: 1.0000001, y: 1.0000002, z: 1}
+ - name: Bip001 R Finger02
+ parentName: Bip001 R Finger01
+ position: {x: -0.025641555, y: -0.000000009536743, z: 0.000000038146972}
+ rotation: {x: -0.00000008940697, y: -7.105425e-15, z: -0.00000014156096, w: 1}
+ scale: {x: 1.0000004, y: 1.0000002, z: 1.0000007}
+ - name: Bip001 R Finger0Nub
+ parentName: Bip001 R Finger02
+ position: {x: -0.024530487, y: -0.000000009536743, z: -0.000000019073486}
+ rotation: {x: 0.000000014901161, y: 0.0000000037252907, z: 1, w: 5.7211802e-18}
+ scale: {x: -0.99999994, y: -0.9999999, z: -0.99999994}
+ - name: Bip001 R Finger2
+ parentName: Bip001 R Hand
+ position: {x: -0.08869598, y: -0.0009292602, z: 0.00803266}
+ rotation: {x: 0.007193503, y: -0.025448194, z: 0.015477205, w: 0.99953043}
+ scale: {x: 1, y: 1.0000002, z: 1}
+ - name: Bip001 R Finger21
+ parentName: Bip001 R Finger2
+ position: {x: -0.035238035, y: -0.000000076293944, z: 0}
+ rotation: {x: -0.000000027939667, y: -0.0000000018626445, z: 0.00000006149637, w: 1}
+ scale: {x: 0.9999998, y: 0.9999997, z: 0.9999999}
+ - name: Bip001 R Finger22
+ parentName: Bip001 R Finger21
+ position: {x: -0.028829575, y: 0.000000057220458, z: 0}
+ rotation: {x: -0.0000000623986, y: 0.000000027939677, z: -0.0000001464359, w: 1}
+ scale: {x: 0.99999994, y: 1.0000001, z: 1.0000001}
+ - name: Bip001 R Finger2Nub
+ parentName: Bip001 R Finger22
+ position: {x: -0.022979354, y: -0.000000019073486, z: 0}
+ rotation: {x: -0.0000000037252899, y: 0.000000009313224, z: 1, w: -2.653788e-17}
+ scale: {x: -1.0000001, y: -1.0000001, z: -1.0000001}
+ - name: Bip001 R Finger1
+ parentName: Bip001 R Hand
+ position: {x: -0.08566628, y: 0.0019595337, z: 0.030115388}
+ rotation: {x: -0.041125704, y: 0.34547937, z: 0.109422445, w: 0.93111724}
+ scale: {x: 1, y: 1, z: 0.99999994}
+ - name: Bip001 R Finger11
+ parentName: Bip001 R Finger1
+ position: {x: -0.0339933, y: 0.000000038146972, z: -0.0000000047683715}
+ rotation: {x: 0.000000022351735, y: -0.000000083819, z: -0.000000033527602, w: 1}
+ scale: {x: 1.0000001, y: 1, z: 1}
+ - name: Bip001 R Finger12
+ parentName: Bip001 R Finger11
+ position: {x: -0.02471115, y: -0.000000019073486, z: -0.0000000047683715}
+ rotation: {x: -0, y: -0, z: -1.6792123e-15, w: 1}
+ scale: {x: 1.0000005, y: 1.0000004, z: 0.9999999}
+ - name: Bip001 R Finger1Nub
+ parentName: Bip001 R Finger12
+ position: {x: -0.02008171, y: 0.000000019073486, z: 0.0000000047683715}
+ rotation: {x: 5.702705e-26, y: -9.3132246e-10, z: 1, w: -6.123234e-17}
+ scale: {x: -1.0000001, y: -1.0000001, z: -1.0000001}
+ - name: Bip001 R Finger3
+ parentName: Bip001 R Hand
+ position: {x: -0.08759277, y: 0.000010223388, z: -0.012853216}
+ rotation: {x: 0.018083032, y: -0.039043806, z: 0.00067552907, w: 0.9990737}
+ scale: {x: 1.0000002, y: 1, z: 0.99999994}
+ - name: Bip001 R Finger31
+ parentName: Bip001 R Finger3
+ position: {x: -0.034347076, y: 0.000000038146972, z: 0.000000009536743}
+ rotation: {x: -0.00000009313222, y: 0.000000026077023, z: -0.00000011612424, w: 1}
+ scale: {x: 1.0000002, y: 1.0000001, z: 1.0000001}
+ - name: Bip001 R Finger32
+ parentName: Bip001 R Finger31
+ position: {x: -0.02848358, y: -0.000000038146972, z: -0.000000014305114}
+ rotation: {x: 0.00000009126957, y: 0.000000063329914, z: 0.00000008475033, w: 1}
+ scale: {x: 1.0000001, y: 0.99999994, z: 0.9999998}
+ - name: Bip001 R Finger3Nub
+ parentName: Bip001 R Finger32
+ position: {x: -0.022639694, y: -0.000000057220458, z: -0.0000000047683715}
+ rotation: {x: -6.8432476e-25, y: 0.000000011175871, z: 1, w: -6.123234e-17}
+ scale: {x: -1, y: -1, z: -1}
+ - name: Bip001 R Finger4
+ parentName: Bip001 R Hand
+ position: {x: -0.07877823, y: 0.002803955, z: -0.030893024}
+ rotation: {x: 0.029447902, y: -0.033610202, z: -0.008080942, w: 0.9989685}
+ scale: {x: 1, y: 0.99999994, z: 0.9999998}
+ - name: Bip001 R Finger41
+ parentName: Bip001 R Finger4
+ position: {x: -0.027974471, y: 0.000000038146972, z: -0.000000009536743}
+ rotation: {x: -0.00000002793967, y: 0.000000029802315, z: 0.0000000032596283, w: 1}
+ scale: {x: 1.0000004, y: 1.0000005, z: 0.9999999}
+ - name: Bip001 R Finger42
+ parentName: Bip001 R Finger41
+ position: {x: -0.021889495, y: 0.000000019073486, z: 0}
+ rotation: {x: 0.000000029802315, y: -0.000000029802315, z: -9.3132235e-10, w: 1}
+ scale: {x: 1.0000001, y: 0.99999994, z: 1.0000001}
+ - name: Bip001 R Finger4Nub
+ parentName: Bip001 R Finger42
+ position: {x: -0.016196288, y: -0.000000038146972, z: -0.000000009536743}
+ rotation: {x: -2.2810825e-25, y: -0.0000000037252903, z: 1, w: 6.123234e-17}
+ scale: {x: -1.0000001, y: -1, z: -1}
+ - name: Bip001 R ForeTwist
+ parentName: Bip001 R Forearm
+ position: {x: -0, y: 0, z: 0}
+ rotation: {x: 3.1121772e-12, y: 0.0000000070867827, z: 0.000000023297616, w: 1}
+ scale: {x: 1.0000011, y: 1.0000005, z: 1.0000007}
+ - name: Bip001 R Thigh
+ parentName: Bip001
+ position: {x: -0.000000057220458, y: -0.08523403, z: 0.00000015258789}
+ rotation: {x: 0.4414919, y: -0.4932458, z: 0.39339268, w: 0.6379936}
+ scale: {x: 1.0000004, y: 1.0000002, z: 1.0000004}
+ - name: Bip001 R Calf
+ parentName: Bip001 R Thigh
+ position: {x: -0.36894354, y: 0, z: 0}
+ rotation: {x: 0.00000011920929, y: -0.00000011920929, z: 0.0006225109, w: 0.9999999}
+ scale: {x: 1.0000002, y: 1.0000004, z: 1.0000001}
+ - name: Bip001 R Foot
+ parentName: Bip001 R Calf
+ position: {x: -0.4258783, y: -0.000000009536743, z: 0}
+ rotation: {x: -0.0000015199186, y: 0.000000089406974, z: -0.00073921686, w: 0.99999976}
+ scale: {x: 1.0000005, y: 1.0000004, z: 1.0000006}
+ - name: Bip001 R Toe0
+ parentName: Bip001 R Foot
+ position: {x: -0.08415353, y: 0.11247517, z: 0}
+ rotation: {x: 0.000000059604645, y: 0.000000029802322, z: -0.7071068, w: 0.7071068}
+ scale: {x: 0.99999994, y: 1.0000001, z: 1}
+ - name: Bip001 R Toe0Nub
+ parentName: Bip001 R Toe0
+ position: {x: -0.063924685, y: 0.0000000011920929, z: 0.000000019073486}
+ rotation: {x: -0.0000000037252903, y: -0.0000000095278665, z: 5.8207626e-11, w: 1}
+ scale: {x: 1, y: 1, z: 1.0000001}
+ - name: Bip001 L Thigh
+ parentName: Bip001
+ position: {x: -0, y: 0.08523406, z: -0.000000076293944}
+ rotation: {x: 0.44171643, y: -0.49304473, z: 0.3931021, w: 0.63817257}
+ scale: {x: 1, y: 1.0000002, z: 1.0000004}
+ - name: Bip001 L Calf
+ parentName: Bip001 L Thigh
+ position: {x: -0.36894354, y: -0.0000000047683715, z: 0}
+ rotation: {x: 0.000000029802322, y: -0.000000029802322, z: 0.0006225109, w: 0.9999998}
+ scale: {x: 1.0000006, y: 1.0000004, z: 1.0000002}
+ - name: Bip001 L Foot
+ parentName: Bip001 L Calf
+ position: {x: -0.42587817, y: 0.0000000047683715, z: 0}
+ rotation: {x: -0, y: 0.000000014901161, z: -0.00028386712, w: 1}
+ scale: {x: 0.9999997, y: 1, z: 0.99999976}
+ - name: Bip001 L Toe0
+ parentName: Bip001 L Foot
+ position: {x: -0.08415352, y: 0.11247517, z: 0}
+ rotation: {x: -0.0000001192093, y: -0.00000005960465, z: -0.7071068, w: 0.7071068}
+ scale: {x: 1.0000001, y: 1.0000002, z: 1.0000002}
+ - name: Bip001 L Toe0Nub
+ parentName: Bip001 L Toe0
+ position: {x: -0.0639247, y: -5.9604643e-10, z: 0.000000019073486}
+ rotation: {x: 6.975825e-10, y: 4.271461e-26, z: 1, w: -6.123234e-17}
+ scale: {x: -0.99999994, y: -0.99999994, z: -1}
+ armTwist: 0.5
+ foreArmTwist: 0.5
+ upperLegTwist: 0.5
+ legTwist: 0.5
+ armStretch: 0.05
+ legStretch: 0.05
+ feetSpacing: 0
+ globalScale: 1
+ rootMotionBoneName:
+ hasTranslationDoF: 0
+ hasExtraRoot: 1
+ skeletonHasParents: 1
+ lastHumanDescriptionAvatarSource: {instanceID: 0}
+ autoGenerateAvatarMappingIfUnspecified: 1
+ animationType: 3
+ humanoidOversampling: 1
+ avatarSetup: 1
+ addHumanoidExtraRootOnlyWhenUsingAvatar: 1
+ importBlendShapeDeformPercent: 1
+ remapMaterialsIfMaterialImportModeIsNone: 0
+ additionalBone: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/5.Enemy Animation/BossAnimation'.meta b/Assets/5.Enemy Animation/BossAnimation'.meta
new file mode 100644
index 00000000..549ba783
--- /dev/null
+++ b/Assets/5.Enemy Animation/BossAnimation'.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8b8446902f8367e448f85dab277f598f
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Epic Toon FX/Upgrade/ETFX URP Upgrade (6000.0.11f1).unitypackage.meta b/Assets/Epic Toon FX/Upgrade/ETFX URP Upgrade (6000.0.11f1).unitypackage.meta
new file mode 100644
index 00000000..ffa13bfe
--- /dev/null
+++ b/Assets/Epic Toon FX/Upgrade/ETFX URP Upgrade (6000.0.11f1).unitypackage.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 5f14e783a5ba44a45a317ffae28af4e7
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Epic Toon FX/Upgrade/Legacy/ETFX URP Upgrade (2020.3.45f1).unitypackage.meta b/Assets/Epic Toon FX/Upgrade/Legacy/ETFX URP Upgrade (2020.3.45f1).unitypackage.meta
new file mode 100644
index 00000000..a9c2e213
--- /dev/null
+++ b/Assets/Epic Toon FX/Upgrade/Legacy/ETFX URP Upgrade (2020.3.45f1).unitypackage.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 3d7c4217783978e4abe6496ac71eee94
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI.meta b/Assets/Scripts/Enemy/BossAI.meta
new file mode 100644
index 00000000..32f4c621
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f548a77d5fa24ee45862ea98298a00d9
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterConfig.cs b/Assets/Scripts/Enemy/BossAI/BossCounterConfig.cs
new file mode 100644
index 00000000..fdd6bd33
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterConfig.cs
@@ -0,0 +1,77 @@
+using UnityEngine;
+
+///
+/// 보스 카운터 시스템의 임계치, 가중치, 감소(Decay) 설정을 담는 ScriptableObject.
+/// Inspector에서 밸런싱을 위해 쉽게 조정할 수 있습니다.
+///
+/// [사용법] Project 창에서 우클릭 → Create → Boss/Counter Config
+///
+[CreateAssetMenu(fileName = "BossCounterConfig", menuName = "Boss/Counter Config")]
+public class BossCounterConfig : ScriptableObject
+{
+ [Header("══ 기본 임계치 (첫 런 / 잠금 해제 전) ══")]
+ [Tooltip("회피 카운터 발동 조건: 10초 내 회피 횟수")]
+ public int dodgeThreshold = 5;
+
+ [Tooltip("조준 카운터 발동 조건: 10초 내 조준 유지 시간(초)")]
+ public float aimThreshold = 4.0f;
+
+ [Tooltip("관통 카운터 발동 조건: 10초 내 관통 비율")]
+ [Range(0f, 1f)]
+ public float pierceThreshold = 0.6f;
+
+ [Tooltip("관통 비율 판단을 위한 최소 발사 횟수")]
+ public int minShotsForPierceCheck = 3;
+
+ [Header("══ 잠금 해제 후 임계치 감소 ══")]
+ [Tooltip("잠금 해제된 카운터의 임계치 감소 비율 (0.8 = 20% 낮아짐)")]
+ [Range(0.5f, 1.0f)]
+ public float unlockedThresholdMultiplier = 0.8f;
+
+ [Header("══ 가중치 설정 (확률 가중치 방식) ══")]
+ [Tooltip("카운터 발동 시 해당 카운터 패턴에 추가되는 가중치")]
+ public float counterWeightBonus = 3f;
+
+ [Tooltip("카운터 발동 시 보조 패턴에 추가되는 가중치")]
+ public float counterSubWeightBonus = 2f;
+
+ [Header("══ Decay(감소) 설정 ══")]
+ [Tooltip("카운터 모드 유지 시간(초). 이 시간 동안 조건 미충족 시 비활성화")]
+ public float counterDecayTime = 8f;
+
+ [Header("══ 빈도 제한 ══")]
+ [Tooltip("카운터 패턴 선택 확률 상한 (0.25 = 최대 25%)")]
+ [Range(0.1f, 0.5f)]
+ public float maxCounterFrequency = 0.25f;
+
+ [Tooltip("카운터 패턴 발동 후 쿨타임(초)")]
+ public float counterCooldown = 5f;
+
+ [Header("══ 습관 변경 보상 ══")]
+ [Tooltip("플레이어가 이전 런에서 발동된 카운터 습관을 이번 런에서 안 보이면, 보스 일반 패턴 난이도 감소 비율")]
+ [Range(0f, 0.3f)]
+ public float habitChangeRewardRatio = 0.15f;
+
+ // ═══════════════════════════════════════════
+ // 임계치 조회 (잠금 해제 여부 반영)
+ // ═══════════════════════════════════════════
+
+ /// 현재 유효 임계치 반환 (잠금 해제 시 낮아짐)
+ public int GetEffectiveDodgeThreshold(bool isUnlocked)
+ {
+ if (!isUnlocked) return dodgeThreshold;
+ return Mathf.Max(2, Mathf.RoundToInt(dodgeThreshold * unlockedThresholdMultiplier));
+ }
+
+ public float GetEffectiveAimThreshold(bool isUnlocked)
+ {
+ if (!isUnlocked) return aimThreshold;
+ return aimThreshold * unlockedThresholdMultiplier;
+ }
+
+ public float GetEffectivePierceThreshold(bool isUnlocked)
+ {
+ if (!isUnlocked) return pierceThreshold;
+ return pierceThreshold * unlockedThresholdMultiplier;
+ }
+}
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterConfig.cs.meta b/Assets/Scripts/Enemy/BossAI/BossCounterConfig.cs.meta
new file mode 100644
index 00000000..2de0098e
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 127d57ae132759d4f8233580c8075e39
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterDebugPanel.cs b/Assets/Scripts/Enemy/BossAI/BossCounterDebugPanel.cs
new file mode 100644
index 00000000..60ae8c9d
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterDebugPanel.cs
@@ -0,0 +1,93 @@
+using UnityEngine;
+
+///
+/// 개발 중 보스 카운터 시스템을 테스트하기 위한 디버그 패널.
+/// 빌드 시 자동으로 비활성화됩니다.
+///
+public class BossCounterDebugPanel : MonoBehaviour
+{
+ [SerializeField] private BossCounterSystem counterSystem;
+ [SerializeField] private bool showDebugGUI = true;
+
+ #if UNITY_EDITOR || DEVELOPMENT_BUILD
+
+ private void OnGUI()
+ {
+ if (!showDebugGUI) return;
+
+ GUILayout.BeginArea(new Rect(10, 10, 400, 500));
+ GUILayout.BeginVertical("box");
+
+ GUILayout.Label("═══ 보스 카운터 디버그 ═══", GUI.skin.box);
+
+ // ── 플레이어 행동 데이터 ──
+ var tracker = PlayerBehaviorTracker.Instance;
+ if (tracker != null)
+ {
+ GUILayout.Label("── 플레이어 행동 (10초 윈도우) ──");
+ GUILayout.Label($" 회피 횟수: {tracker.DodgeCount}");
+ GUILayout.Label($" 조준 시간: {tracker.AimHoldTime:F1}s");
+ GUILayout.Label($" 관통 비율: {tracker.PierceRatio:P0} ({tracker.TotalShotsInWindow}발)");
+ }
+
+ GUILayout.Space(5);
+
+ // ── 카운터 상태 ──
+ if (counterSystem != null)
+ {
+ GUILayout.Label("── 카운터 모드 ──");
+ var actives = counterSystem.GetActiveCounters();
+ GUILayout.Label($" 활성 카운터: {(actives.Count > 0 ? string.Join(", ", actives) : "없음")}");
+ GUILayout.Label($" 습관 변경 보상: {(counterSystem.IsHabitChangeRewarded ? "ON" : "OFF")}");
+ }
+
+ GUILayout.Space(5);
+
+ // ── 영구 데이터 ──
+ var persistence = BossCounterPersistence.Instance;
+ if (persistence != null)
+ {
+ GUILayout.Label("── 영구 잠금 해제 ──");
+ GUILayout.Label($" 회피: {(persistence.IsUnlocked(CounterType.Dodge) ? "✓" : "✗")} (발동 {persistence.Data.dodgeCounterActivations}회)");
+ GUILayout.Label($" 조준: {(persistence.IsUnlocked(CounterType.Aim) ? "✓" : "✗")} (발동 {persistence.Data.aimCounterActivations}회)");
+ GUILayout.Label($" 관통: {(persistence.IsUnlocked(CounterType.Pierce) ? "✓" : "✗")} (발동 {persistence.Data.pierceCounterActivations}회)");
+ }
+
+ GUILayout.Space(10);
+
+ // ── 수동 트리거 버튼 ──
+ GUILayout.Label("── 수동 테스트 ──");
+
+ if (tracker != null)
+ {
+ GUILayout.BeginHorizontal();
+ if (GUILayout.Button("회피 x5")) { for (int i = 0; i < 5; i++) tracker.RecordDodge(); }
+ if (GUILayout.Button("발사(일반)")) { tracker.RecordShot(false); }
+ if (GUILayout.Button("발사(관통)")) { tracker.RecordShot(true); }
+ GUILayout.EndHorizontal();
+ }
+
+ if (counterSystem != null)
+ {
+ if (GUILayout.Button("패턴 선택 테스트"))
+ {
+ string pattern = counterSystem.SelectBossPattern();
+ Debug.Log($"[디버그] 선택된 패턴: {pattern}");
+ }
+ }
+
+ if (persistence != null)
+ {
+ GUILayout.Space(5);
+ if (GUILayout.Button("영구 데이터 초기화"))
+ {
+ persistence.ResetAllData();
+ }
+ }
+
+ GUILayout.EndVertical();
+ GUILayout.EndArea();
+ }
+
+ #endif
+}
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterDebugPanel.cs.meta b/Assets/Scripts/Enemy/BossAI/BossCounterDebugPanel.cs.meta
new file mode 100644
index 00000000..8f00ef7d
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterDebugPanel.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ccdc3124c64881747b53b7b469a36e10
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterFeedback.cs b/Assets/Scripts/Enemy/BossAI/BossCounterFeedback.cs
new file mode 100644
index 00000000..ca6f380f
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterFeedback.cs
@@ -0,0 +1,189 @@
+using System.Collections;
+using UnityEngine;
+using UnityEngine.UI;
+using TMPro;
+
+///
+/// 보스 카운터 시스템의 연출/UI를 담당합니다.
+/// 카운터 발동 시 보스 대사, 화면 효과 등을 처리합니다.
+///
+/// "...또 그 수법이냐" 같은 대사로 "보스가 기억한다"는 서사 전달.
+///
+public class BossCounterFeedback : MonoBehaviour
+{
+ [Header("참조")]
+ [SerializeField] private BossCounterSystem counterSystem;
+
+ [Header("UI 요소 (선택)")]
+ [SerializeField] private TextMeshProUGUI bossDialogueText;
+ [SerializeField] private CanvasGroup dialogueCanvasGroup;
+ [SerializeField] private float dialogueDisplayDuration = 3f;
+ [SerializeField] private float dialogueFadeDuration = 0.5f;
+
+ [Header("카운터별 보스 대사")]
+ [SerializeField] private string[] dodgeCounterDialogues = new string[]
+ {
+ "...또 도망치려는 건가.",
+ "네 발은 이미 읽었다.",
+ "아무리 피해도 소용없어."
+ };
+
+ [SerializeField] private string[] aimCounterDialogues = new string[]
+ {
+ "그렇게 오래 노려봐야...",
+ "느린 조준은 빈틈이지.",
+ "시간을 줄 생각은 없다."
+ };
+
+ [SerializeField] private string[] pierceCounterDialogues = new string[]
+ {
+ "그 화살은 더 이상 통하지 않아.",
+ "관통? 이번엔 막아주지.",
+ "같은 수를 반복하다니."
+ };
+
+ [SerializeField] private string[] habitChangeDialogues = new string[]
+ {
+ "...다른 수를 쓰는 건가.",
+ "흥, 조금은 배운 모양이군.",
+ "이번엔 다르군... 재밌어."
+ };
+
+ // ── 잠금 해제 여부에 따른 첫 발동 대사 ──
+ [Header("첫 잠금 해제 시 대사 (서사 강조)")]
+ [SerializeField] private string[] firstUnlockDialogues = new string[]
+ {
+ "...기억했다. 네 버릇을.",
+ "이제 알겠어. 네 전투 방식이.",
+ "한 번이면 충분해. 패턴을 읽었다."
+ };
+
+ private Coroutine dialogueCoroutine;
+
+ private void OnEnable()
+ {
+ if (counterSystem != null)
+ {
+ counterSystem.OnCounterActivated.AddListener(OnCounterActivated);
+ counterSystem.OnCounterDeactivated.AddListener(OnCounterDeactivated);
+ counterSystem.OnHabitChangeRewarded.AddListener(OnHabitChangeRewarded);
+ }
+ }
+
+ private void OnDisable()
+ {
+ if (counterSystem != null)
+ {
+ counterSystem.OnCounterActivated.RemoveListener(OnCounterActivated);
+ counterSystem.OnCounterDeactivated.RemoveListener(OnCounterDeactivated);
+ counterSystem.OnHabitChangeRewarded.RemoveListener(OnHabitChangeRewarded);
+ }
+ }
+
+ // ═══════════════════════════════════════════
+ // 이벤트 핸들러
+ // ═══════════════════════════════════════════
+
+ private void OnCounterActivated(CounterType type)
+ {
+ var persistence = BossCounterPersistence.Instance;
+
+ // 첫 잠금 해제인지 확인 (총 발동 횟수가 1이면 방금 처음 잠금 해제된 것)
+ bool isFirstUnlock = false;
+ if (persistence != null)
+ {
+ int activations = type switch
+ {
+ CounterType.Dodge => persistence.Data.dodgeCounterActivations,
+ CounterType.Aim => persistence.Data.aimCounterActivations,
+ CounterType.Pierce => persistence.Data.pierceCounterActivations,
+ _ => 0
+ };
+ isFirstUnlock = (activations <= 1);
+ }
+
+ // 대사 선택
+ string dialogue;
+ if (isFirstUnlock)
+ {
+ dialogue = firstUnlockDialogues[Random.Range(0, firstUnlockDialogues.Length)];
+ }
+ else
+ {
+ dialogue = type switch
+ {
+ CounterType.Dodge => dodgeCounterDialogues[Random.Range(0, dodgeCounterDialogues.Length)],
+ CounterType.Aim => aimCounterDialogues[Random.Range(0, aimCounterDialogues.Length)],
+ CounterType.Pierce => pierceCounterDialogues[Random.Range(0, pierceCounterDialogues.Length)],
+ _ => ""
+ };
+ }
+
+ ShowDialogue(dialogue);
+
+ // TODO: 여기에 추가 연출 넣기
+ // - 보스 전용 애니메이션 트리거 (예: animator.SetTrigger("CounterReady"))
+ // - 보스 주변 이펙트 (파티클, 오라 등)
+ // - 카메라 연출 (줌인, 슬로모션 등)
+ // - 사운드 효과
+ Debug.Log($"[BossCounterFeedback] {type} 카운터 연출 재생" +
+ (isFirstUnlock ? " (첫 잠금 해제!)" : ""));
+ }
+
+ private void OnCounterDeactivated(CounterType type)
+ {
+ // 카운터 해제 시 연출 (이펙트 종료 등)
+ Debug.Log($"[BossCounterFeedback] {type} 카운터 연출 종료");
+ }
+
+ private void OnHabitChangeRewarded()
+ {
+ string dialogue = habitChangeDialogues[Random.Range(0, habitChangeDialogues.Length)];
+ ShowDialogue(dialogue);
+
+ Debug.Log("[BossCounterFeedback] 습관 변경 보상 연출!");
+ }
+
+ // ═══════════════════════════════════════════
+ // 대사 표시
+ // ═══════════════════════════════════════════
+
+ private void ShowDialogue(string text)
+ {
+ if (bossDialogueText == null || dialogueCanvasGroup == null) return;
+
+ if (dialogueCoroutine != null)
+ StopCoroutine(dialogueCoroutine);
+
+ dialogueCoroutine = StartCoroutine(DialogueRoutine(text));
+ }
+
+ private IEnumerator DialogueRoutine(string text)
+ {
+ bossDialogueText.text = text;
+ dialogueCanvasGroup.alpha = 0f;
+
+ // 페이드 인
+ float t = 0f;
+ while (t < dialogueFadeDuration)
+ {
+ t += Time.deltaTime;
+ dialogueCanvasGroup.alpha = t / dialogueFadeDuration;
+ yield return null;
+ }
+ dialogueCanvasGroup.alpha = 1f;
+
+ // 유지
+ yield return new WaitForSeconds(dialogueDisplayDuration);
+
+ // 페이드 아웃
+ t = 0f;
+ while (t < dialogueFadeDuration)
+ {
+ t += Time.deltaTime;
+ dialogueCanvasGroup.alpha = 1f - (t / dialogueFadeDuration);
+ yield return null;
+ }
+ dialogueCanvasGroup.alpha = 0f;
+ }
+}
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterFeedback.cs.meta b/Assets/Scripts/Enemy/BossAI/BossCounterFeedback.cs.meta
new file mode 100644
index 00000000..83e31b06
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterFeedback.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0c7bf8a7166b27040a70563b18bd6b3e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterPersistence.cs b/Assets/Scripts/Enemy/BossAI/BossCounterPersistence.cs
new file mode 100644
index 00000000..d75ca940
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterPersistence.cs
@@ -0,0 +1,139 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+///
+/// 런 간 영구 저장되는 보스 카운터 잠금 해제 데이터.
+/// "보스가 플레이어를 기억한다"는 서사를 담당합니다.
+///
+/// 핵심 규칙:
+/// - 잠금 해제는 영구 (런이 끝나도 유지)
+/// - 발동은 조건부 (해당 런에서 플레이어가 습관을 보여야만 활성화)
+/// - 잠금 해제된 카운터는 임계치가 약간 낮아짐 (보스가 "이미 알고 있으니 더 빨리 눈치챔")
+///
+[System.Serializable]
+public class BossCounterSaveData
+{
+ public bool dodgeCounterUnlocked = false;
+ public bool aimCounterUnlocked = false;
+ public bool pierceCounterUnlocked = false;
+
+ /// 각 카운터가 발동된 총 횟수 (연출/난이도 스케일링에 활용 가능)
+ public int dodgeCounterActivations = 0;
+ public int aimCounterActivations = 0;
+ public int pierceCounterActivations = 0;
+}
+
+///
+/// 보스 카운터 영구 데이터를 관리합니다.
+/// PlayerPrefs 기반으로 런 간 저장/로드합니다.
+///
+public class BossCounterPersistence : MonoBehaviour
+{
+ public static BossCounterPersistence Instance { get; private set; }
+
+ private const string SAVE_KEY = "BossCounterData";
+
+ public BossCounterSaveData Data { get; private set; }
+
+ private void Awake()
+ {
+ if (Instance != null && Instance != this)
+ {
+ Destroy(gameObject);
+ return;
+ }
+ Instance = this;
+ DontDestroyOnLoad(gameObject);
+ Load();
+ }
+
+ // ═══════════════════════════════════════════
+ // 잠금 해제
+ // ═══════════════════════════════════════════
+
+ /// 특정 카운터 타입을 영구 잠금 해제
+ public void UnlockCounter(CounterType type)
+ {
+ switch (type)
+ {
+ case CounterType.Dodge:
+ if (!Data.dodgeCounterUnlocked)
+ {
+ Data.dodgeCounterUnlocked = true;
+ Debug.Log("[BossCounter] 회피 카운터 영구 잠금 해제!");
+ }
+ break;
+ case CounterType.Aim:
+ if (!Data.aimCounterUnlocked)
+ {
+ Data.aimCounterUnlocked = true;
+ Debug.Log("[BossCounter] 조준 카운터 영구 잠금 해제!");
+ }
+ break;
+ case CounterType.Pierce:
+ if (!Data.pierceCounterUnlocked)
+ {
+ Data.pierceCounterUnlocked = true;
+ Debug.Log("[BossCounter] 관통 카운터 영구 잠금 해제!");
+ }
+ break;
+ }
+ Save();
+ }
+
+ /// 카운터가 잠금 해제되어 있는지 확인
+ public bool IsUnlocked(CounterType type)
+ {
+ return type switch
+ {
+ CounterType.Dodge => Data.dodgeCounterUnlocked,
+ CounterType.Aim => Data.aimCounterUnlocked,
+ CounterType.Pierce => Data.pierceCounterUnlocked,
+ _ => false
+ };
+ }
+
+ /// 카운터 발동 횟수 기록
+ public void RecordActivation(CounterType type)
+ {
+ switch (type)
+ {
+ case CounterType.Dodge: Data.dodgeCounterActivations++; break;
+ case CounterType.Aim: Data.aimCounterActivations++; break;
+ case CounterType.Pierce: Data.pierceCounterActivations++; break;
+ }
+ Save();
+ }
+
+ // ═══════════════════════════════════════════
+ // 저장 / 로드 / 리셋
+ // ═══════════════════════════════════════════
+
+ public void Save()
+ {
+ string json = JsonUtility.ToJson(Data);
+ PlayerPrefs.SetString(SAVE_KEY, json);
+ PlayerPrefs.Save();
+ }
+
+ public void Load()
+ {
+ if (PlayerPrefs.HasKey(SAVE_KEY))
+ {
+ string json = PlayerPrefs.GetString(SAVE_KEY);
+ Data = JsonUtility.FromJson(json);
+ }
+ else
+ {
+ Data = new BossCounterSaveData();
+ }
+ }
+
+ /// 모든 영구 데이터 초기화 (디버그/뉴게임+)
+ public void ResetAllData()
+ {
+ Data = new BossCounterSaveData();
+ PlayerPrefs.DeleteKey(SAVE_KEY);
+ Debug.Log("[BossCounter] 모든 보스 기억 데이터 초기화됨");
+ }
+}
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterPersistence.cs.meta b/Assets/Scripts/Enemy/BossAI/BossCounterPersistence.cs.meta
new file mode 100644
index 00000000..ec736c3e
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterPersistence.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c23a9c1b76724ab459bf32a732f6a2f7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterSystem.cs b/Assets/Scripts/Enemy/BossAI/BossCounterSystem.cs
new file mode 100644
index 00000000..333e3bbc
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterSystem.cs
@@ -0,0 +1,356 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Events;
+
+///
+/// 보스 카운터 시스템 메인 컨트롤러.
+///
+/// 핵심 흐름:
+/// 1. PlayerBehaviorTracker에서 실시간 행동 데이터를 읽음
+/// 2. 임계치 판단 → 카운터 모드 ON/OFF (잠금 해제 여부에 따라 임계치 다름)
+/// 3. 가중치 기반으로 보스 패턴 선택
+/// 4. 첫 발동 시 해당 카운터를 영구 잠금 해제
+/// 5. 플레이어가 습관을 바꾸면 보상 (난이도 완화)
+///
+public class BossCounterSystem : MonoBehaviour
+{
+ [Header("참조")]
+ [SerializeField] private BossCounterConfig config;
+
+ [Header("이벤트 (연출/UI 연동)")]
+ [Tooltip("카운터 모드가 활성화될 때 발생 (CounterType 전달)")]
+ public UnityEvent OnCounterActivated;
+
+ [Tooltip("카운터 모드가 비활성화될 때 발생")]
+ public UnityEvent OnCounterDeactivated;
+
+ [Tooltip("보스가 카운터 패턴을 선택했을 때 발생 (패턴 이름 전달)")]
+ public UnityEvent OnCounterPatternSelected;
+
+ [Tooltip("플레이어가 습관을 바꿔서 보상받을 때 발생")]
+ public UnityEvent OnHabitChangeRewarded;
+
+ // ── 카운터 모드 상태 ──
+ private Dictionary activeCounters = new Dictionary()
+ {
+ { CounterType.Dodge, false },
+ { CounterType.Aim, false },
+ { CounterType.Pierce, false }
+ };
+
+ // ── Decay 타이머 ──
+ private Dictionary counterTimers = new Dictionary()
+ {
+ { CounterType.Dodge, 0f },
+ { CounterType.Aim, 0f },
+ { CounterType.Pierce, 0f }
+ };
+
+ // ── 쿨타임 ──
+ private float lastCounterPatternTime = -100f;
+
+ // ── 습관 변경 보상 추적 ──
+ private HashSet previousRunCounters = new HashSet();
+ private HashSet currentRunActivatedCounters = new HashSet();
+ private bool habitChangeRewardGranted = false;
+
+ // ── 보스 패턴 가중치 정의 ──
+ [System.Serializable]
+ public class BossPattern
+ {
+ public string patternName;
+ public float baseWeight = 1f;
+ [Tooltip("이 패턴이 카운터 패턴인 경우 해당 타입")]
+ public CounterType counterType = CounterType.None;
+ [Tooltip("카운터 발동 시 보조적으로 가중치가 올라가는 타입")]
+ public CounterType subCounterType = CounterType.None;
+ }
+
+ [Header("보스 패턴 목록")]
+ [SerializeField] private List bossPatterns = new List();
+
+ // ═══════════════════════════════════════════
+ // 초기화
+ // ═══════════════════════════════════════════
+
+ ///
+ /// 보스 전투 시작 시 호출. 이전 런에서 발동된 카운터 정보를 기반으로 초기화.
+ ///
+ public void InitializeBattle()
+ {
+ // 이전 런에서 잠금 해제된 카운터들을 기록 (습관 변경 보상 판단용)
+ previousRunCounters.Clear();
+ currentRunActivatedCounters.Clear();
+ habitChangeRewardGranted = false;
+
+ var persistence = BossCounterPersistence.Instance;
+ if (persistence != null)
+ {
+ if (persistence.Data.dodgeCounterActivations > 0 && persistence.IsUnlocked(CounterType.Dodge))
+ previousRunCounters.Add(CounterType.Dodge);
+ if (persistence.Data.aimCounterActivations > 0 && persistence.IsUnlocked(CounterType.Aim))
+ previousRunCounters.Add(CounterType.Aim);
+ if (persistence.Data.pierceCounterActivations > 0 && persistence.IsUnlocked(CounterType.Pierce))
+ previousRunCounters.Add(CounterType.Pierce);
+ }
+
+ // 모든 카운터 모드 OFF
+ foreach (var type in new[] { CounterType.Dodge, CounterType.Aim, CounterType.Pierce })
+ {
+ activeCounters[type] = false;
+ counterTimers[type] = 0f;
+ }
+
+ lastCounterPatternTime = -100f;
+
+ Debug.Log($"[BossCounter] 전투 시작. 이전 런 카운터: [{string.Join(", ", previousRunCounters)}]");
+ }
+
+ // ═══════════════════════════════════════════
+ // 매 프레임 업데이트
+ // ═══════════════════════════════════════════
+
+ private void Update()
+ {
+ if (PlayerBehaviorTracker.Instance == null) return;
+
+ EvaluateCounters();
+ DecayCounters();
+ CheckHabitChangeReward();
+ }
+
+ /// 플레이어 행동 데이터를 읽고 카운터 모드 ON/OFF 판단
+ private void EvaluateCounters()
+ {
+ var tracker = PlayerBehaviorTracker.Instance;
+ var persistence = BossCounterPersistence.Instance;
+
+ // ── 회피 카운터 ──
+ bool dodgeUnlocked = persistence != null && persistence.IsUnlocked(CounterType.Dodge);
+ int dodgeThreshold = config.GetEffectiveDodgeThreshold(dodgeUnlocked);
+
+ if (tracker.DodgeCount >= dodgeThreshold)
+ {
+ // 잠금 해제 안 된 상태면 첫 발동 시 잠금 해제 (첫 런에서도 발동 가능)
+ // 잠금 해제된 상태면 더 낮은 임계치로 발동
+ ActivateCounter(CounterType.Dodge);
+ }
+
+ // ── 조준 카운터 ──
+ bool aimUnlocked = persistence != null && persistence.IsUnlocked(CounterType.Aim);
+ float aimThreshold = config.GetEffectiveAimThreshold(aimUnlocked);
+
+ if (tracker.AimHoldTime >= aimThreshold)
+ {
+ ActivateCounter(CounterType.Aim);
+ }
+
+ // ── 관통 카운터 ──
+ bool pierceUnlocked = persistence != null && persistence.IsUnlocked(CounterType.Pierce);
+ float pierceThreshold = config.GetEffectivePierceThreshold(pierceUnlocked);
+
+ if (tracker.TotalShotsInWindow >= config.minShotsForPierceCheck
+ && tracker.PierceRatio >= pierceThreshold)
+ {
+ ActivateCounter(CounterType.Pierce);
+ }
+ }
+
+ private void ActivateCounter(CounterType type)
+ {
+ counterTimers[type] = config.counterDecayTime;
+
+ if (!activeCounters[type])
+ {
+ activeCounters[type] = true;
+ currentRunActivatedCounters.Add(type);
+
+ // 영구 잠금 해제
+ var persistence = BossCounterPersistence.Instance;
+ if (persistence != null)
+ {
+ persistence.UnlockCounter(type);
+ persistence.RecordActivation(type);
+ }
+
+ OnCounterActivated?.Invoke(type);
+ Debug.Log($"[BossCounter] {type} 카운터 활성화!");
+ }
+ }
+
+ /// 시간이 지나면 카운터 모드 자동 해제
+ private void DecayCounters()
+ {
+ foreach (var type in new[] { CounterType.Dodge, CounterType.Aim, CounterType.Pierce })
+ {
+ if (!activeCounters[type]) continue;
+
+ counterTimers[type] -= Time.deltaTime;
+ if (counterTimers[type] <= 0f)
+ {
+ activeCounters[type] = false;
+ OnCounterDeactivated?.Invoke(type);
+ Debug.Log($"[BossCounter] {type} 카운터 Decay로 비활성화");
+ }
+ }
+ }
+
+ // ═══════════════════════════════════════════
+ // 습관 변경 보상
+ // ═══════════════════════════════════════════
+
+ ///
+ /// 이전 런에서 카운터 당한 습관을 이번 런에서 보이지 않으면 보상.
+ /// 전투 중반(30초 이후) 한 번 체크.
+ ///
+ private float battleTimer = 0f;
+ private const float HABIT_CHECK_TIME = 30f;
+
+ private void CheckHabitChangeReward()
+ {
+ if (habitChangeRewardGranted || previousRunCounters.Count == 0) return;
+
+ battleTimer += Time.deltaTime;
+ if (battleTimer < HABIT_CHECK_TIME) return;
+
+ // 이전 런에서 발동된 카운터 중, 이번 런에서 아직 발동 안 된 것이 있으면 보상
+ foreach (var prevCounter in previousRunCounters)
+ {
+ if (!currentRunActivatedCounters.Contains(prevCounter))
+ {
+ habitChangeRewardGranted = true;
+ OnHabitChangeRewarded?.Invoke();
+ Debug.Log($"[BossCounter] 플레이어가 {prevCounter} 습관을 바꿈! 보상 부여");
+ break;
+ }
+ }
+ }
+
+ // ═══════════════════════════════════════════
+ // 패턴 선택 (보스 AI에서 호출)
+ // ═══════════════════════════════════════════
+
+ ///
+ /// 현재 카운터 상태를 반영하여 보스 패턴을 가중치 랜덤으로 선택합니다.
+ /// 보스 AI의 패턴 선택 시점에 호출하세요.
+ ///
+ /// 선택된 패턴 이름
+ public string SelectBossPattern()
+ {
+ if (bossPatterns.Count == 0)
+ {
+ Debug.LogWarning("[BossCounter] 보스 패턴이 등록되지 않았습니다!");
+ return "";
+ }
+
+ // 가중치 계산
+ float[] weights = new float[bossPatterns.Count];
+ float totalWeight = 0f;
+ float counterWeight = 0f;
+
+ for (int i = 0; i < bossPatterns.Count; i++)
+ {
+ weights[i] = bossPatterns[i].baseWeight;
+
+ // 카운터 패턴 가중치 증가
+ if (bossPatterns[i].counterType != CounterType.None
+ && activeCounters.ContainsKey(bossPatterns[i].counterType)
+ && activeCounters[bossPatterns[i].counterType])
+ {
+ // 쿨타임 체크
+ if (Time.time - lastCounterPatternTime >= config.counterCooldown)
+ {
+ weights[i] += config.counterWeightBonus;
+ }
+ }
+
+ // 보조 카운터 가중치
+ if (bossPatterns[i].subCounterType != CounterType.None
+ && activeCounters.ContainsKey(bossPatterns[i].subCounterType)
+ && activeCounters[bossPatterns[i].subCounterType])
+ {
+ weights[i] += config.counterSubWeightBonus;
+ }
+
+ // 습관 변경 보상: 일반 패턴 가중치 감소 (= 난이도 완화)
+ if (habitChangeRewardGranted && bossPatterns[i].counterType == CounterType.None)
+ {
+ weights[i] *= (1f - config.habitChangeRewardRatio);
+ }
+
+ totalWeight += weights[i];
+
+ if (bossPatterns[i].counterType != CounterType.None)
+ counterWeight += weights[i];
+ }
+
+ // 빈도 상한 체크: 카운터 패턴 총 비율이 maxCounterFrequency를 넘지 않도록
+ if (totalWeight > 0f && counterWeight / totalWeight > config.maxCounterFrequency)
+ {
+ float allowedCounterWeight = (totalWeight - counterWeight) * config.maxCounterFrequency / (1f - config.maxCounterFrequency);
+ float scale = allowedCounterWeight / counterWeight;
+
+ for (int i = 0; i < bossPatterns.Count; i++)
+ {
+ if (bossPatterns[i].counterType != CounterType.None)
+ {
+ float bonus = weights[i] - bossPatterns[i].baseWeight;
+ weights[i] = bossPatterns[i].baseWeight + bonus * scale;
+ }
+ }
+
+ // 총 가중치 재계산
+ totalWeight = 0f;
+ for (int i = 0; i < weights.Length; i++)
+ totalWeight += weights[i];
+ }
+
+ // 가중치 랜덤 선택
+ float roll = Random.Range(0f, totalWeight);
+ float cumulative = 0f;
+
+ for (int i = 0; i < bossPatterns.Count; i++)
+ {
+ cumulative += weights[i];
+ if (roll <= cumulative)
+ {
+ string selected = bossPatterns[i].patternName;
+
+ // 카운터 패턴이면 쿨타임 기록
+ if (bossPatterns[i].counterType != CounterType.None)
+ {
+ lastCounterPatternTime = Time.time;
+ }
+
+ OnCounterPatternSelected?.Invoke(selected);
+ return selected;
+ }
+ }
+
+ return bossPatterns[bossPatterns.Count - 1].patternName;
+ }
+
+ // ═══════════════════════════════════════════
+ // 외부 조회
+ // ═══════════════════════════════════════════
+
+ /// 특정 카운터 모드가 현재 활성 상태인지 확인
+ public bool IsCounterActive(CounterType type)
+ {
+ return activeCounters.ContainsKey(type) && activeCounters[type];
+ }
+
+ /// 현재 활성화된 모든 카운터 타입 반환
+ public List GetActiveCounters()
+ {
+ var result = new List();
+ foreach (var kvp in activeCounters)
+ {
+ if (kvp.Value) result.Add(kvp.Key);
+ }
+ return result;
+ }
+
+ /// 습관 변경 보상이 활성화되었는지 확인
+ public bool IsHabitChangeRewarded => habitChangeRewardGranted;
+}
diff --git a/Assets/Scripts/Enemy/BossAI/BossCounterSystem.cs.meta b/Assets/Scripts/Enemy/BossAI/BossCounterSystem.cs.meta
new file mode 100644
index 00000000..ede5862d
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossCounterSystem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5e36870a705f4fd44923bc5704c4a93b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI/BossMonster.cs b/Assets/Scripts/Enemy/BossAI/BossMonster.cs
new file mode 100644
index 00000000..cf2984a8
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossMonster.cs
@@ -0,0 +1,222 @@
+using UnityEngine;
+using System.Collections;
+
+public class NorcielBoss : MonsterClass
+{
+ [Header("--- 🧠 두뇌 연결 ---")]
+ [SerializeField] private BossCounterSystem counterSystem;
+
+ [Header("--- ⚔️ 패턴 설정 ---")]
+ [SerializeField] private float patternInterval = 3f; // 공격 간격
+
+ [Header("--- 📊 UI 연결 ---")]
+ [SerializeField] private GameObject bossHealthBar; // 보스 체력바 UI (평소엔 꺼둠)
+
+ // 내부 변수
+ private float _timer;
+ private Rigidbody rb;
+ private bool isBattleStarted = false; // 전투 시작 여부 체크
+ private Transform target; // 플레이어 타겟
+
+ protected override void Awake()
+ {
+ base.Awake();
+ rb = GetComponent();
+ }
+
+ protected override void Init()
+ {
+ // 1. 기본 변수 초기화
+ _timer = patternInterval;
+
+ // 플레이어 찾기 (Tag: Player)
+ GameObject playerObj = GameObject.FindWithTag("Player");
+ if (playerObj != null)
+ {
+ target = playerObj.transform;
+ }
+ else
+ {
+ var playerScript = FindObjectOfType();
+ if (playerScript != null) target = playerScript.transform;
+ }
+
+ // 2. 전투 시작 전 상태 설정 (봉인)
+ isBattleStarted = false;
+
+ // 움직임 끄기
+ if (agent != null)
+ {
+ agent.enabled = false;
+ agent.isStopped = true;
+ }
+
+ // 체력바 숨기기
+ if (bossHealthBar != null) bossHealthBar.SetActive(false);
+ }
+
+ protected override void ExecuteAILogic()
+ {
+ // ⭐ 전투 미시작 or 타겟 없음 -> 정지
+ if (!isBattleStarted || target == null) return;
+
+ // 1. 공격 쿨타임 체크
+ _timer -= Time.deltaTime;
+
+ // 쿨타임 끝 + 공격중 아님 + 피격중 아님 + 살아있음 -> 공격 시도
+ if (_timer <= 0 && !isAttacking && !isHit && !isDead)
+ {
+ _timer = patternInterval;
+ DecideAttack();
+ }
+
+ // 2. 이동 및 애니메이션 처리 (평소 상태)
+ if (!isAttacking && agent.enabled)
+ {
+ agent.SetDestination(target.position);
+
+ // ──────── ⭐ [핵심] 이동 애니메이션 동기화 ────────
+ if (animator != null)
+ {
+ // 현재 이동 속도를 가져와서 애니메이터에 전달 (0 ~ 3.5 ~ ...)
+ // Animator의 Blend Tree가 이 값을 받아 Idle/Walk/Run을 섞어줌
+ float currentSpeed = agent.velocity.magnitude;
+ animator.SetFloat("Speed", currentSpeed);
+ }
+ // ──────────────────────────────────────────────
+
+ // 사거리 안으로 들어왔거나 너무 가까우면 멈춤
+ if (agent.remainingDistance <= agent.stoppingDistance)
+ {
+ agent.isStopped = true;
+
+ // 몸을 플레이어 쪽으로 돌리기
+ Vector3 dir = target.position - transform.position;
+ dir.y = 0;
+ if (dir != Vector3.zero)
+ {
+ transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), Time.deltaTime * 5f);
+ }
+ }
+ else
+ {
+ agent.isStopped = false;
+ }
+ }
+ }
+
+ // ════════════════════════════════════════
+ // 🎬 전투 입장 시스템 (외부 호출용)
+ // ════════════════════════════════════════
+
+ public void StartBossBattle()
+ {
+ if (isBattleStarted) return;
+ StartCoroutine(BattleStartRoutine());
+ }
+
+ private IEnumerator BattleStartRoutine()
+ {
+ // 포효 (스트링 방식)
+ if (animator != null) animator.Play("Roar");
+
+ Debug.Log("😈 보스: 감히 내 영역에 들어오다니! (전투 시작)");
+
+ if (bossHealthBar != null) bossHealthBar.SetActive(true);
+ if (counterSystem != null) counterSystem.InitializeBattle();
+
+ yield return new WaitForSeconds(2.0f); // 포효 끝날 때까지 대기
+
+ isBattleStarted = true;
+ if (agent != null) agent.enabled = true;
+ }
+
+ // ════════════════════════════════════════
+ // 🧠 AI 판단 및 공격 실행
+ // ════════════════════════════════════════
+
+ private void DecideAttack()
+ {
+ // 이동 애니메이션 잠시 0으로 (미끄러짐 방지)
+ if (animator != null) animator.SetFloat("Speed", 0f);
+
+ string patternName = (counterSystem != null) ? counterSystem.SelectBossPattern() : "Normal";
+ Debug.Log($"🤖 보스 AI 결정: {patternName}");
+
+ switch (patternName)
+ {
+ case "DashAttack":
+ StartCoroutine(Pattern_DashAttack());
+ break;
+ case "Smash":
+ StartCoroutine(Pattern_SmashAttack());
+ break;
+ case "ShieldWall":
+ StartCoroutine(Pattern_ShieldWall());
+ break;
+ default:
+ StartCoroutine(Pattern_NormalShoot());
+ break;
+ }
+ }
+
+ // ════════════════════════════════════════
+ // ⚔️ 공격 패턴 코루틴 (스트링 방식)
+ // ════════════════════════════════════════
+
+ private IEnumerator Pattern_DashAttack()
+ {
+ OnAttackStart();
+
+ if (animator != null) animator.Play("Skill_Dash_Ready");
+ yield return new WaitForSeconds(0.5f);
+
+ // 돌진 (물리 이동)
+ if (agent != null) agent.enabled = false;
+ if (rb != null)
+ {
+ rb.isKinematic = false;
+ rb.velocity = transform.forward * 20f;
+ }
+
+ if (animator != null) animator.Play("Skill_Dash_Go");
+ yield return new WaitForSeconds(1.0f);
+
+ // 복구
+ if (rb != null)
+ {
+ rb.velocity = Vector3.zero;
+ rb.isKinematic = true;
+ }
+
+ if (agent != null && isBattleStarted) agent.enabled = true;
+ OnAttackEnd();
+ }
+
+ private IEnumerator Pattern_SmashAttack()
+ {
+ OnAttackStart();
+ if (animator != null) animator.Play("Skill_Smash_Charge");
+ yield return new WaitForSeconds(1.2f);
+
+ if (animator != null) animator.Play("Skill_Smash_Impact");
+ yield return new WaitForSeconds(1.0f);
+ OnAttackEnd();
+ }
+
+ private IEnumerator Pattern_ShieldWall()
+ {
+ OnAttackStart();
+ if (animator != null) animator.Play("Skill_Shield");
+ yield return new WaitForSeconds(2.0f);
+ OnAttackEnd();
+ }
+
+ private IEnumerator Pattern_NormalShoot()
+ {
+ OnAttackStart();
+ if (animator != null) animator.Play("Attack_Shoot");
+ yield return new WaitForSeconds(1.0f);
+ OnAttackEnd();
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Enemy/BossAI/BossMonster.cs.meta b/Assets/Scripts/Enemy/BossAI/BossMonster.cs.meta
new file mode 100644
index 00000000..204d96e2
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossMonster.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 04f39bf969074e6488f84b47bd517dc9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI/BossZoneTrigger.cs b/Assets/Scripts/Enemy/BossAI/BossZoneTrigger.cs
new file mode 100644
index 00000000..2d4677dc
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossZoneTrigger.cs
@@ -0,0 +1,29 @@
+using UnityEngine;
+
+public class BossZoneTrigger : MonoBehaviour
+{
+ [SerializeField] private NorcielBoss boss; //
+ [SerializeField] private GameObject fogWall; // Ա Ȱ ()
+
+ private bool hasTriggered = false;
+
+ private void OnTriggerEnter(Collider other)
+ {
+ // ̹ ߵ߰ų, ÷̾ ƴϸ
+ if (hasTriggered) return;
+
+ if (other.CompareTag("Player"))
+ {
+ hasTriggered = true;
+
+ // 1.
+ if (boss != null) boss.StartBossBattle();
+
+ // 2. Ա ()
+ if (fogWall != null) fogWall.SetActive(true);
+
+ // 3. ƮŴ
+ // gameObject.SetActive(false); // ٷ Ȱ
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Enemy/BossAI/BossZoneTrigger.cs.meta b/Assets/Scripts/Enemy/BossAI/BossZoneTrigger.cs.meta
new file mode 100644
index 00000000..c35a8a33
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/BossZoneTrigger.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 086f3fc0675122448a8950f910dc4864
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy/BossAI/CounterType.cs b/Assets/Scripts/Enemy/BossAI/CounterType.cs
new file mode 100644
index 00000000..cab44c60
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/CounterType.cs
@@ -0,0 +1,10 @@
+///
+/// 보스 카운터 패턴 타입 열거형
+///
+public enum CounterType
+{
+ None,
+ Dodge, // 회피 남발 카운터
+ Aim, // 정조준 과다 카운터
+ Pierce // 관통 화살 편중 카운터
+}
diff --git a/Assets/Scripts/Enemy/BossAI/CounterType.cs.meta b/Assets/Scripts/Enemy/BossAI/CounterType.cs.meta
new file mode 100644
index 00000000..e39ed0d8
--- /dev/null
+++ b/Assets/Scripts/Enemy/BossAI/CounterType.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: eb38b1f2aa504c74c9f597c141d6ba47
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Player/Combat/BossCounterConfig.asset b/Assets/Scripts/Player/Combat/BossCounterConfig.asset
new file mode 100644
index 00000000..1b3fd727
--- /dev/null
+++ b/Assets/Scripts/Player/Combat/BossCounterConfig.asset
@@ -0,0 +1,25 @@
+%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: 127d57ae132759d4f8233580c8075e39, type: 3}
+ m_Name: BossCounterConfig
+ m_EditorClassIdentifier:
+ dodgeThreshold: 5
+ aimThreshold: 4
+ pierceThreshold: 0.6
+ minShotsForPierceCheck: 3
+ unlockedThresholdMultiplier: 0.8
+ counterWeightBonus: 3
+ counterSubWeightBonus: 2
+ counterDecayTime: 8
+ maxCounterFrequency: 0.25
+ counterCooldown: 5
+ habitChangeRewardRatio: 0.15
diff --git a/Assets/Scripts/Player/Combat/BossCounterConfig.asset.meta b/Assets/Scripts/Player/Combat/BossCounterConfig.asset.meta
new file mode 100644
index 00000000..11dabedf
--- /dev/null
+++ b/Assets/Scripts/Player/Combat/BossCounterConfig.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4c6a2993f687f65409c4ece370872444
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Player/Controller/PlayerBehaviorTracker.cs b/Assets/Scripts/Player/Controller/PlayerBehaviorTracker.cs
new file mode 100644
index 00000000..44cb5543
--- /dev/null
+++ b/Assets/Scripts/Player/Controller/PlayerBehaviorTracker.cs
@@ -0,0 +1,147 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+///
+/// 플레이어의 전투 행동을 슬라이딩 윈도우(최근 N초) 기반으로 추적합니다.
+/// 보스 AI가 이 데이터를 읽어 카운터 패턴 발동 여부를 판단합니다.
+///
+public class PlayerBehaviorTracker : MonoBehaviour
+{
+ public static PlayerBehaviorTracker Instance { get; private set; }
+
+ [Header("슬라이딩 윈도우 설정")]
+ [Tooltip("행동 추적 윈도우 크기(초)")]
+ [SerializeField] private float windowDuration = 10f;
+
+ // ── 내부 기록용 타임스탬프 리스트 ──
+ private List dodgeTimestamps = new List();
+ private List aimStartTimes = new List();
+ private List aimEndTimes = new List();
+ private List pierceShotTimestamps = new List();
+ private List totalShotTimestamps = new List();
+
+ // ── 현재 조준 상태 ──
+ private bool isAiming = false;
+ private float currentAimStartTime;
+
+ // ── 외부에서 읽는 프로퍼티 ──
+ public int DodgeCount => CountInWindow(dodgeTimestamps);
+ public float AimHoldTime => CalculateAimHoldTime();
+ public float PierceRatio => CalculatePierceRatio();
+ public int TotalShotsInWindow => CountInWindow(totalShotTimestamps);
+
+ private void Awake()
+ {
+ if (Instance != null && Instance != this)
+ {
+ Destroy(gameObject);
+ return;
+ }
+ Instance = this;
+ }
+
+ // ═══════════════════════════════════════════
+ // 외부에서 호출하는 이벤트 기록 메서드
+ // ═══════════════════════════════════════════
+
+ /// 플레이어가 회피(대시/구르기)를 수행했을 때 호출
+ public void RecordDodge()
+ {
+ dodgeTimestamps.Add(Time.time);
+ }
+
+ /// 플레이어가 조준을 시작했을 때 호출
+ public void RecordAimStart()
+ {
+ if (!isAiming)
+ {
+ isAiming = true;
+ currentAimStartTime = Time.time;
+ }
+ }
+
+ /// 플레이어가 조준을 해제했을 때 호출
+ public void RecordAimEnd()
+ {
+ if (isAiming)
+ {
+ isAiming = false;
+ aimStartTimes.Add(currentAimStartTime);
+ aimEndTimes.Add(Time.time);
+ }
+ }
+
+ /// 화살 발사 시 호출. isPierce=true면 관통 화살
+ public void RecordShot(bool isPierce)
+ {
+ totalShotTimestamps.Add(Time.time);
+ if (isPierce)
+ {
+ pierceShotTimestamps.Add(Time.time);
+ }
+ }
+
+ // ═══════════════════════════════════════════
+ // 런 리셋 (새 런 시작 시 호출)
+ // ═══════════════════════════════════════════
+
+ /// 새 런 시작 시 모든 행동 기록을 초기화
+ public void ResetForNewRun()
+ {
+ dodgeTimestamps.Clear();
+ aimStartTimes.Clear();
+ aimEndTimes.Clear();
+ pierceShotTimestamps.Clear();
+ totalShotTimestamps.Clear();
+ isAiming = false;
+ }
+
+ // ═══════════════════════════════════════════
+ // 내부 계산
+ // ═══════════════════════════════════════════
+
+ private int CountInWindow(List timestamps)
+ {
+ float cutoff = Time.time - windowDuration;
+ // 오래된 항목 제거
+ timestamps.RemoveAll(t => t < cutoff);
+ return timestamps.Count;
+ }
+
+ private float CalculateAimHoldTime()
+ {
+ float cutoff = Time.time - windowDuration;
+ float total = 0f;
+
+ // 완료된 조준 세션
+ for (int i = aimStartTimes.Count - 1; i >= 0; i--)
+ {
+ if (aimEndTimes[i] < cutoff)
+ {
+ aimStartTimes.RemoveAt(i);
+ aimEndTimes.RemoveAt(i);
+ continue;
+ }
+ float start = Mathf.Max(aimStartTimes[i], cutoff);
+ total += aimEndTimes[i] - start;
+ }
+
+ // 현재 조준 중인 시간도 포함
+ if (isAiming)
+ {
+ float start = Mathf.Max(currentAimStartTime, cutoff);
+ total += Time.time - start;
+ }
+
+ return total;
+ }
+
+ private float CalculatePierceRatio()
+ {
+ int totalShots = CountInWindow(totalShotTimestamps);
+ if (totalShots == 0) return 0f;
+
+ int pierceShots = CountInWindow(pierceShotTimestamps);
+ return (float)pierceShots / totalShots;
+ }
+}
diff --git a/Assets/Scripts/Player/Controller/PlayerBehaviorTracker.cs.meta b/Assets/Scripts/Player/Controller/PlayerBehaviorTracker.cs.meta
new file mode 100644
index 00000000..12fa47d9
--- /dev/null
+++ b/Assets/Scripts/Player/Controller/PlayerBehaviorTracker.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 320dac90fad4bd94dbdc466f5f2458cd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UI/HUD/HP Ui bar.cs b/Assets/Scripts/UI/HUD/HP Ui bar.cs
index 79ca770c..507a02a5 100644
--- a/Assets/Scripts/UI/HUD/HP Ui bar.cs
+++ b/Assets/Scripts/UI/HUD/HP Ui bar.cs
@@ -53,4 +53,4 @@ public class HPUibar : MonoBehaviour
else if (healthSource is EnemyHealth eh) eh.OnHealthChanged -= UpdateUI;
else if (healthSource is MonsterClass mc) mc.OnHealthChanged -= UpdateUI;
}
-}
\ No newline at end of file
+}