From 877d2f5fef442bc20c9e8d93e0261bd3462c4d16 Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 30 Jul 2026 16:02:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(enemy):=20=E5=98=B2=E9=A3=8E=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E5=88=B0=E6=96=B0=E8=BD=A8=E2=80=94=E2=80=94=E8=83=BD?= =?UTF-8?q?=E5=8A=9B=E8=B5=84=E4=BA=A7=20+=20=E5=AF=B9=E8=B1=A1=E6=A0=91?= =?UTF-8?q?=20+=20=E5=BC=80=E6=88=98=E8=A7=A6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删 5 个空 BossSkillSO,用向导重建 6 个 EnemyAbilitySO(含入场演出)。 预制体经放置工具重新产出:EnemyAiBrain(_definitionId=ChaoFeng) + BossPhaseAbilityGate + 6 个能力组件,不再有 BossSkillExecutor。 TestRoomA 加开战触发区。三件自检 0 error,EditMode 260/260。 首次真正跑通两条脚手架,暴露并修掉三个它们的缺陷: 1. 放置工具漏挂 EnemyLocomotion(PlaceChaoFeng 及其余 7 个敌人放置入口)。 EnemyBase.Awake 找不到它即报错且 Locomotion 为 null, AiStateFragments.ApplyLocomotion 直接 NRE、AiRuntime 构造失败—— Boss 建不出决策层,完全不动。已在所有敌人放置入口补齐。 2. 向导把空中阶段的 wind_stone 建成 requiresGrounded=true(SO 默认值)。 Boss 浮空后 IsGrounded 恒 false,选招器把它滤掉,空中阶段站着不打。 能力定义表加 grounded 列,阶段 1 的招显式置 false。 3. BossPhaseAbilityGate.ApplyPhase 只在 EnterPhase 与 OnSpawn 调用, 直接摆场景里的 Boss 两条路径都不走,开局后续阶段的招仍在候选池里。 BossBase.Start 补一次初始阶段应用。 另:Phase1_Tornado_HitBox 确认零消费者(龙卷判定随弹体走), 从放置工具删除其创建与伤害源绑定; EnemyBrainContext.UseAbility 对解析不到的能力 id 改为 LogError, 不再静默返回 false(CLAUDE.md 第 6 条); 新增 PlaceBossFightTrigger 脚手架(此前无对应创建入口,属裸建)。 播放模式实测状态序列(TestRoomA,玩家走进触发区): Wait →(Engaged) Intro → Ground⇄GroundAttack →(hp<50%) PhaseTransition → Air⇄AirAttack,浮空生效,阶段门按阶段换池,全程 0 报错。 动画 Clip 未接入,PlayClipAbility 空 clip 立即完成,故只验证了状态流转, 判定时序待美术接入后再校。 Co-Authored-By: Claude Opus 5 (1M context) --- .../Abilities/ABL_ChaoFeng_Boomerang.asset | 47 +- .../Abilities/ABL_ChaoFeng_FanCombo.asset | 55 +- .../Abilities/ABL_ChaoFeng_Intro.asset | 44 ++ .../Abilities/ABL_ChaoFeng_Intro.asset.meta | 8 + .../Abilities/ABL_ChaoFeng_TornadoLarge.asset | 47 +- .../Abilities/ABL_ChaoFeng_TornadoSmall.asset | 47 +- .../Abilities/ABL_ChaoFeng_WindStone.asset | 47 +- .../Enemies/ChaoFeng/ENM_ChaoFeng.prefab | 500 ++++++++++++++---- Assets/_Game/Scenes/Testings/TestRoomA.unity | 167 ++++++ .../Editor/Character/CharacterWizardWindow.cs | 33 +- .../Editor/Scene/SceneObjectPlacerTool.cs | 94 +++- .../Enemies/AIBrain/EnemyBrainContext.cs | 18 +- Assets/_Game/Scripts/Enemies/Boss/BossBase.cs | 10 + 13 files changed, 844 insertions(+), 273 deletions(-) create mode 100644 Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Intro.asset create mode 100644 Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Intro.asset.meta diff --git a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Boomerang.asset b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Boomerang.asset index 1743b35a..9874de88 100644 --- a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Boomerang.asset +++ b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Boomerang.asset @@ -9,32 +9,29 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: de92221c7c3fb4a42a7cd122a8f97632, type: 3} + m_Script: {fileID: 11500000, guid: fc81345eb5294d643b4242eac215c5fc, type: 3} m_Name: ABL_ChaoFeng_Boomerang m_EditorClassIdentifier: - skillId: boomerang - displayName: Boomerang - designNote: - category: 0 - skillType: 0 - availablePhaseIndices: 00000000 - attackPatterns: [] - vulnerabilityWindows: [] - interactionTags: 0 - sequenceOnHit: {fileID: 0} - sequenceOnMiss: {fileID: 0} - counterResponses: [] - arenaEvents: [] - resourceCost: - resourceId: - cost: 0 - minRequired: 0 - buildsRage: 0 - poiseWindow: - Level: 0 - NormalizedStart: 0 - NormalizedEnd: 0 - skillAnimation: + abilityId: boomerang + designNote: "\u9636\u6BB5 0 \u62DB\u5F0F\uFF1B\u9636\u6BB5\u53EF\u7528\u6027\u7531 + BossPhaseAbilityGate \u914D\u7F6E" + attackSequence: [] + cooldown: 4 + telegraphVfxKey: + telegraphDuration: 0 + interruptOnHurt: 1 + interruptOnStagger: 1 + preferredMinRange: 0 + preferredMaxRange: 5 + requiresLineOfSight: 1 + requiresGrounded: 1 + exclusionGroup: + priority: 0 + category: 1 + weight: 1 + rangeRadius: 9 + rangeOffset: {x: 0, y: 0} + clip: _FadeDuration: 0.25 _Speed: 1 _Events: @@ -43,8 +40,6 @@ MonoBehaviour: _Names: [] _Clip: {fileID: 0} _NormalizedStartTime: NaN - cooldown: 0 - weight: 1 references: version: 2 RefIds: [] diff --git a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_FanCombo.asset b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_FanCombo.asset index 73349e44..e94519cb 100644 --- a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_FanCombo.asset +++ b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_FanCombo.asset @@ -9,42 +9,25 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: de92221c7c3fb4a42a7cd122a8f97632, type: 3} + m_Script: {fileID: 11500000, guid: 9050afa76362dff469c64fbb48c9ff8d, type: 3} m_Name: ABL_ChaoFeng_FanCombo m_EditorClassIdentifier: - skillId: fan_combo - displayName: FanCombo - designNote: - category: 0 - skillType: 0 - availablePhaseIndices: 00000000 - attackPatterns: [] - vulnerabilityWindows: [] - interactionTags: 0 - sequenceOnHit: {fileID: 0} - sequenceOnMiss: {fileID: 0} - counterResponses: [] - arenaEvents: [] - resourceCost: - resourceId: - cost: 0 - minRequired: 0 - buildsRage: 0 - poiseWindow: - Level: 0 - NormalizedStart: 0 - NormalizedEnd: 0 - skillAnimation: - _FadeDuration: 0.25 - _Speed: 1 - _Events: - _NormalizedTimes: [] - _Callbacks: [] - _Names: [] - _Clip: {fileID: 0} - _NormalizedStartTime: NaN - cooldown: 0 + abilityId: fan_combo + designNote: "\u9636\u6BB5 0 \u62DB\u5F0F\uFF1B\u9636\u6BB5\u53EF\u7528\u6027\u7531 + BossPhaseAbilityGate \u914D\u7F6E" + attackSequence: [] + cooldown: 2.5 + telegraphVfxKey: + telegraphDuration: 0 + interruptOnHurt: 1 + interruptOnStagger: 1 + preferredMinRange: 0 + preferredMaxRange: 5 + requiresLineOfSight: 1 + requiresGrounded: 1 + exclusionGroup: + priority: 0 + category: 1 weight: 1.5 - references: - version: 2 - RefIds: [] + rangeRadius: 2.5 + rangeOffset: {x: 0, y: 0} diff --git a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Intro.asset b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Intro.asset new file mode 100644 index 00000000..78c68fc7 --- /dev/null +++ b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Intro.asset @@ -0,0 +1,44 @@ +%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: fc81345eb5294d643b4242eac215c5fc, type: 3} + m_Name: ABL_ChaoFeng_Intro + m_EditorClassIdentifier: + abilityId: chaofeng_intro + designNote: "\u5165\u573A\u6F14\u51FA\uFF0C\u4E0D\u8FDB\u9009\u62DB\u6C60" + attackSequence: [] + cooldown: 0 + telegraphVfxKey: + telegraphDuration: 0 + interruptOnHurt: 1 + interruptOnStagger: 1 + preferredMinRange: 0 + preferredMaxRange: 5 + requiresLineOfSight: 1 + requiresGrounded: 1 + exclusionGroup: + priority: 0 + category: 0 + weight: 0 + rangeRadius: 0 + rangeOffset: {x: 0, y: 0} + clip: + _FadeDuration: 0.25 + _Speed: 1 + _Events: + _NormalizedTimes: [] + _Callbacks: [] + _Names: [] + _Clip: {fileID: 0} + _NormalizedStartTime: NaN + references: + version: 2 + RefIds: [] diff --git a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Intro.asset.meta b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Intro.asset.meta new file mode 100644 index 00000000..48329828 --- /dev/null +++ b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_Intro.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eddeb2d9e64934d4eab9acf5efd8902e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_TornadoLarge.asset b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_TornadoLarge.asset index eaf3aee3..60bc52e4 100644 --- a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_TornadoLarge.asset +++ b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_TornadoLarge.asset @@ -9,32 +9,29 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: de92221c7c3fb4a42a7cd122a8f97632, type: 3} + m_Script: {fileID: 11500000, guid: fc81345eb5294d643b4242eac215c5fc, type: 3} m_Name: ABL_ChaoFeng_TornadoLarge m_EditorClassIdentifier: - skillId: tornado_large - displayName: TornadoLarge - designNote: - category: 0 - skillType: 0 - availablePhaseIndices: 00000000 - attackPatterns: [] - vulnerabilityWindows: [] - interactionTags: 0 - sequenceOnHit: {fileID: 0} - sequenceOnMiss: {fileID: 0} - counterResponses: [] - arenaEvents: [] - resourceCost: - resourceId: - cost: 0 - minRequired: 0 - buildsRage: 0 - poiseWindow: - Level: 0 - NormalizedStart: 0 - NormalizedEnd: 0 - skillAnimation: + abilityId: tornado_large + designNote: "\u9636\u6BB5 0 \u62DB\u5F0F\uFF1B\u9636\u6BB5\u53EF\u7528\u6027\u7531 + BossPhaseAbilityGate \u914D\u7F6E" + attackSequence: [] + cooldown: 6 + telegraphVfxKey: + telegraphDuration: 0 + interruptOnHurt: 1 + interruptOnStagger: 1 + preferredMinRange: 0 + preferredMaxRange: 5 + requiresLineOfSight: 1 + requiresGrounded: 1 + exclusionGroup: + priority: 0 + category: 1 + weight: 0.8 + rangeRadius: 12 + rangeOffset: {x: 0, y: 0} + clip: _FadeDuration: 0.25 _Speed: 1 _Events: @@ -43,8 +40,6 @@ MonoBehaviour: _Names: [] _Clip: {fileID: 0} _NormalizedStartTime: NaN - cooldown: 0 - weight: 0.8 references: version: 2 RefIds: [] diff --git a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_TornadoSmall.asset b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_TornadoSmall.asset index e808eccb..f4ffb266 100644 --- a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_TornadoSmall.asset +++ b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_TornadoSmall.asset @@ -9,32 +9,29 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: de92221c7c3fb4a42a7cd122a8f97632, type: 3} + m_Script: {fileID: 11500000, guid: fc81345eb5294d643b4242eac215c5fc, type: 3} m_Name: ABL_ChaoFeng_TornadoSmall m_EditorClassIdentifier: - skillId: tornado_small - displayName: TornadoSmall - designNote: - category: 0 - skillType: 0 - availablePhaseIndices: 00000000 - attackPatterns: [] - vulnerabilityWindows: [] - interactionTags: 0 - sequenceOnHit: {fileID: 0} - sequenceOnMiss: {fileID: 0} - counterResponses: [] - arenaEvents: [] - resourceCost: - resourceId: - cost: 0 - minRequired: 0 - buildsRage: 0 - poiseWindow: - Level: 0 - NormalizedStart: 0 - NormalizedEnd: 0 - skillAnimation: + abilityId: tornado_small + designNote: "\u9636\u6BB5 0 \u62DB\u5F0F\uFF1B\u9636\u6BB5\u53EF\u7528\u6027\u7531 + BossPhaseAbilityGate \u914D\u7F6E" + attackSequence: [] + cooldown: 3.5 + telegraphVfxKey: + telegraphDuration: 0 + interruptOnHurt: 1 + interruptOnStagger: 1 + preferredMinRange: 0 + preferredMaxRange: 5 + requiresLineOfSight: 1 + requiresGrounded: 1 + exclusionGroup: + priority: 0 + category: 1 + weight: 1.2 + rangeRadius: 8 + rangeOffset: {x: 0, y: 0} + clip: _FadeDuration: 0.25 _Speed: 1 _Events: @@ -43,8 +40,6 @@ MonoBehaviour: _Names: [] _Clip: {fileID: 0} _NormalizedStartTime: NaN - cooldown: 0 - weight: 1.2 references: version: 2 RefIds: [] diff --git a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_WindStone.asset b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_WindStone.asset index ba43f777..d7e32232 100644 --- a/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_WindStone.asset +++ b/Assets/_Game/Data/Enemies/ChaoFeng/Abilities/ABL_ChaoFeng_WindStone.asset @@ -9,32 +9,29 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: de92221c7c3fb4a42a7cd122a8f97632, type: 3} + m_Script: {fileID: 11500000, guid: fc81345eb5294d643b4242eac215c5fc, type: 3} m_Name: ABL_ChaoFeng_WindStone m_EditorClassIdentifier: - skillId: wind_stone - displayName: WindStone - designNote: - category: 0 - skillType: 0 - availablePhaseIndices: 01000000 - attackPatterns: [] - vulnerabilityWindows: [] - interactionTags: 0 - sequenceOnHit: {fileID: 0} - sequenceOnMiss: {fileID: 0} - counterResponses: [] - arenaEvents: [] - resourceCost: - resourceId: - cost: 0 - minRequired: 0 - buildsRage: 0 - poiseWindow: - Level: 0 - NormalizedStart: 0 - NormalizedEnd: 0 - skillAnimation: + abilityId: wind_stone + designNote: "\u9636\u6BB5 1 \u62DB\u5F0F\uFF1B\u9636\u6BB5\u53EF\u7528\u6027\u7531 + BossPhaseAbilityGate \u914D\u7F6E" + attackSequence: [] + cooldown: 3 + telegraphVfxKey: + telegraphDuration: 0 + interruptOnHurt: 1 + interruptOnStagger: 1 + preferredMinRange: 0 + preferredMaxRange: 5 + requiresLineOfSight: 1 + requiresGrounded: 0 + exclusionGroup: + priority: 0 + category: 1 + weight: 1 + rangeRadius: 12 + rangeOffset: {x: 0, y: 0} + clip: _FadeDuration: 0.25 _Speed: 1 _Events: @@ -43,8 +40,6 @@ MonoBehaviour: _Names: [] _Clip: {fileID: 0} _NormalizedStartTime: NaN - cooldown: 0 - weight: 1 references: version: 2 RefIds: [] diff --git a/Assets/_Game/Prefabs/Enemies/ChaoFeng/ENM_ChaoFeng.prefab b/Assets/_Game/Prefabs/Enemies/ChaoFeng/ENM_ChaoFeng.prefab index a277c6ef..1eafcae2 100644 --- a/Assets/_Game/Prefabs/Enemies/ChaoFeng/ENM_ChaoFeng.prefab +++ b/Assets/_Game/Prefabs/Enemies/ChaoFeng/ENM_ChaoFeng.prefab @@ -1,5 +1,58 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &979165801027136474 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5181544129696273283} + - component: {fileID: 7940098084422673156} + m_Layer: 0 + m_Name: MeleeAttackAbility_FanCombo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5181544129696273283 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 979165801027136474} + 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: 5296480593323786894} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &7940098084422673156 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 979165801027136474} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 971ba82e05d87234e8b944760542e47c, type: 3} + m_Name: + m_EditorClassIdentifier: + _config: {fileID: 11400000, guid: b13d174edfd74654188f1cd08f072123, type: 2} + _hitBoxSlots: + - slotName: fan_1 + hitBox: {fileID: 230484937522067432} + - slotName: fan_2 + hitBox: {fileID: 9170136654108653383} + - slotName: fan_3 + hitBox: {fileID: 4630646362173111049} + _faceTargetOnStart: 1 --- !u!1 &1231266844344956596 GameObject: m_ObjectHideFlags: 0 @@ -62,6 +115,51 @@ Transform: m_Children: [] m_Father: {fileID: 2025611111464161772} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1825922247716397416 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8959989091743334252} + - component: {fileID: 8219329344573822582} + m_Layer: 0 + m_Name: PlayClipAbility_Intro + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8959989091743334252 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1825922247716397416} + 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: 5296480593323786894} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8219329344573822582 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1825922247716397416} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a26fca0fa72894a4da1a5a58ee023154, type: 3} + m_Name: + m_EditorClassIdentifier: + _config: {fileID: 11400000, guid: eddeb2d9e64934d4eab9acf5efd8902e, type: 2} --- !u!1 &2290525692157171072 GameObject: m_ObjectHideFlags: 0 @@ -191,7 +289,7 @@ Transform: m_GameObject: {fileID: 2904988631977355437} serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalPosition: {x: 0, y: 1, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -285,7 +383,7 @@ SpriteRenderer: m_WasSpriteAssigned: 1 m_MaskInteraction: 0 m_SpriteSortPoint: 0 ---- !u!1 &3015807690815610513 +--- !u!1 &2916559493138038639 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -293,99 +391,88 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 1409576167468823365} - - component: {fileID: 2458103135947848963} - - component: {fileID: 2450883169310398879} - m_Layer: 25 - m_Name: Phase1_Tornado_HitBox + - component: {fileID: 7149986575129040968} + - component: {fileID: 209352783170023499} + m_Layer: 0 + m_Name: PlayClipAbility_Boomerang m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!4 &1409576167468823365 + m_IsActive: 1 +--- !u!4 &7149986575129040968 Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3015807690815610513} + m_GameObject: {fileID: 2916559493138038639} 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: 2025611111464161772} + m_Father: {fileID: 5296480593323786894} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!61 &2458103135947848963 -BoxCollider2D: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3015807690815610513} - m_Enabled: 1 - m_Density: 1 - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_ForceSendLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_ForceReceiveLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_ContactCaptureLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_CallbackLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_IsTrigger: 1 - m_UsedByEffector: 0 - m_UsedByComposite: 0 - m_Offset: {x: 0, y: 0} - m_SpriteTilingProperty: - border: {x: 0, y: 0, z: 0, w: 0} - pivot: {x: 0, y: 0} - oldSize: {x: 0, y: 0} - newSize: {x: 0, y: 0} - adaptiveTilingThreshold: 0 - drawMode: 0 - adaptiveTiling: 0 - m_AutoTiling: 0 - serializedVersion: 2 - m_Size: {x: 0.6, y: 1.2} - m_EdgeRadius: 0 ---- !u!114 &2450883169310398879 +--- !u!114 &209352783170023499 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3015807690815610513} + m_GameObject: {fileID: 2916559493138038639} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: a655e2461396a8348a32a13144438e8e, type: 3} + m_Script: {fileID: 11500000, guid: a26fca0fa72894a4da1a5a58ee023154, type: 3} m_Name: m_EditorClassIdentifier: - _defaultSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2} - _hitCooldown: 0.1 - _hitMode: 0 - _hitInterval: 0.5 - _targetLayers: - serializedVersion: 2 - m_Bits: 4294967295 - _id: - _rivalHitBoxMask: - serializedVersion: 2 - m_Bits: 0 + _config: {fileID: 11400000, guid: 6076c1b736f69af4c9048d9d4e7ec768, type: 2} +--- !u!1 &3224375973558534567 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6052463430739264899} + - component: {fileID: 1436318798284677237} + m_Layer: 0 + m_Name: PlayClipAbility_TornadoLarge + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6052463430739264899 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3224375973558534567} + 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: 5296480593323786894} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1436318798284677237 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3224375973558534567} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a26fca0fa72894a4da1a5a58ee023154, type: 3} + m_Name: + m_EditorClassIdentifier: + _config: {fileID: 11400000, guid: 27037bf4ed7188741ba55bb82fdd8fa9, type: 2} --- !u!1 &3277627412355666927 GameObject: m_ObjectHideFlags: 0 @@ -487,6 +574,43 @@ MonoBehaviour: _rivalHitBoxMask: serializedVersion: 2 m_Bits: 0 +--- !u!1 &3801371647583863605 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5296480593323786894} + m_Layer: 0 + m_Name: Abilities + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5296480593323786894 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3801371647583863605} + 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: + - {fileID: 8959989091743334252} + - {fileID: 5181544129696273283} + - {fileID: 7149986575129040968} + - {fileID: 3558980470815650670} + - {fileID: 6052463430739264899} + - {fileID: 4717475142090746934} + m_Father: {fileID: 2025611111464161772} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &4177669747969163254 GameObject: m_ObjectHideFlags: 0 @@ -634,7 +758,10 @@ GameObject: - component: {fileID: 973594085864951384} - component: {fileID: 5341485012012430190} - component: {fileID: 8088437629491012474} - - component: {fileID: 3437191888218430966} + - component: {fileID: 3133205082234065514} + - component: {fileID: 3942835667027582048} + - component: {fileID: 4739322141714049461} + - component: {fileID: 5585087268776340831} - component: {fileID: 1810872916174435854} - component: {fileID: 1201243240150589714} - component: {fileID: 6858366591425580670} @@ -654,20 +781,20 @@ Transform: m_GameObject: {fileID: 7781161515165213226} serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 1968.4287, y: 77.1997, z: 0} + m_LocalPosition: {x: 98, y: 21, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - {fileID: 5517492589801030229} - {fileID: 6397871098464242200} + - {fileID: 80973138644072513} - {fileID: 376149298811787739} - {fileID: 8176707102135037433} - {fileID: 8814706017035826473} - - {fileID: 1409576167468823365} - {fileID: 7580995191264333933} - {fileID: 2397879757105861778} - {fileID: 4107279870065028942} - - {fileID: 80973138644072513} + - {fileID: 5296480593323786894} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!50 &6158877404411547497 @@ -729,7 +856,7 @@ BoxCollider2D: m_IsTrigger: 0 m_UsedByEffector: 0 m_UsedByComposite: 0 - m_Offset: {x: 0, y: 0} + m_Offset: {x: 0, y: 1} m_SpriteTilingProperty: border: {x: 0, y: 0, z: 0, w: 0} pivot: {x: 0, y: 0} @@ -763,7 +890,7 @@ MonoBehaviour: _animancer: {fileID: 8300109994792221770} _feedback: {fileID: 5341485012012430190} _hurtBox: {fileID: 6579043664862402528} - _bodyCollider: {fileID: 0} + _bodyCollider: {fileID: 4474032822853512122} _patrolZone: {fileID: 0} _onEnemyDied: {fileID: 11400000, guid: def849e2c5ec8204eae6b083b02307aa, type: 2} _onPlayerSpawned: {fileID: 11400000, guid: 7e2c7e614f6627b449a244ab44443adf, type: 2} @@ -775,6 +902,8 @@ MonoBehaviour: _onBossPhaseChanged: {fileID: 11400000, guid: 9f49e575a92a7fb43af755ba1840abd2, type: 2} _skillExecutor: {fileID: 0} _bossResource: {fileID: 0} + _phaseGate: {fileID: 5585087268776340831} + _arenaAnchors: {fileID: 0} _onParrySuccess: {fileID: 0} _floatController: {fileID: 1810872916174435854} _knockdownCounter: {fileID: 1201243240150589714} @@ -908,14 +1037,13 @@ MonoBehaviour: _dbg_IsWallAhead: 0 _dbg_IsLedgeAhead: 0 _dbg_IsTurning: 0 - _dbg_NavDriving: 0 _dbg_Input_MoveDir: 0 _dbg_Input_MoveSpeed: 0 _dbg_Input_WantStop: 0 _dbg_Input_WantFace: 0 _dbg_Input_FaceTargetPos: {x: 0, y: 0} _dbg_Input_FaceDir: 0 ---- !u!114 &3437191888218430966 +--- !u!114 &3133205082234065514 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -924,27 +1052,69 @@ MonoBehaviour: m_GameObject: {fileID: 7781161515165213226} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 4dfa1c525eaca5640b3cfe945626a466, type: 3} + m_Script: {fileID: 11500000, guid: 8caa8e247c70b7445820efe80d2da0ec, type: 3} m_Name: m_EditorClassIdentifier: - _hitBoxes: - - {fileID: 230484937522067432} - - {fileID: 9170136654108653383} - - {fileID: 4630646362173111049} - - {fileID: 2450883169310398879} - _weakPointSystem: {fileID: 0} - _animancer: {fileID: 8300109994792221770} - _bossId: ChaoFeng - _onBossSkillStarted: {fileID: 0} - _onBossSkillEnded: {fileID: 0} - _playerTransform: {fileID: 0} - _skills: - - {fileID: 11400000, guid: 6076c1b736f69af4c9048d9d4e7ec768, type: 2} - - {fileID: 11400000, guid: b13d174edfd74654188f1cd08f072123, type: 2} - - {fileID: 11400000, guid: 7cb2926dd5b97e64b9e37f07124ae307, type: 2} - - {fileID: 11400000, guid: 27037bf4ed7188741ba55bb82fdd8fa9, type: 2} - - {fileID: 11400000, guid: 02b79b9dc903c824786ed3cc3c3e225e, type: 2} - _repeatRangeCheck: 8 + _stoppingDistance: 0.2 + _wanderMinRange: 1.5 + _wanderMaxRange: 5 + _stallWindowSeconds: 0.4 + _stallMinProgress: 0.05 +--- !u!114 &3942835667027582048 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7781161515165213226} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9201463979893884288d3645a607eb90, type: 3} + m_Name: + m_EditorClassIdentifier: + _patrolStrategy: 0 + _wanderPauseMin: 0.5 + _wanderPauseMax: 1.5 + _waypoints: [] + _pingPong: 0 + _waypointArriveRadius: 0.4 +--- !u!114 &4739322141714049461 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7781161515165213226} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d92d657c6bbdfe246a7333e04f79f8f7, type: 3} + m_Name: + m_EditorClassIdentifier: + _recipe: {fileID: 0} + _definitionId: ChaoFeng +--- !u!114 &5585087268776340831 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7781161515165213226} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a9f265c84eb5db34b8fd06472949ee83, type: 3} + m_Name: + m_EditorClassIdentifier: + _entries: + - ability: {fileID: 7940098084422673156} + phases: 00000000 + - ability: {fileID: 209352783170023499} + phases: 00000000 + - ability: {fileID: 536854426800190861} + phases: 00000000 + - ability: {fileID: 1436318798284677237} + phases: 00000000 + - ability: {fileID: 9004908790283913037} + phases: 01000000 --- !u!114 &1810872916174435854 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1115,6 +1285,96 @@ MonoBehaviour: obstructLayer: serializedVersion: 2 m_Bits: 0 +--- !u!1 &7806369876961327953 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3558980470815650670} + - component: {fileID: 536854426800190861} + m_Layer: 0 + m_Name: PlayClipAbility_TornadoSmall + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3558980470815650670 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7806369876961327953} + 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: 5296480593323786894} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &536854426800190861 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7806369876961327953} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a26fca0fa72894a4da1a5a58ee023154, type: 3} + m_Name: + m_EditorClassIdentifier: + _config: {fileID: 11400000, guid: 7cb2926dd5b97e64b9e37f07124ae307, type: 2} +--- !u!1 &7888626137513785884 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4717475142090746934} + - component: {fileID: 9004908790283913037} + m_Layer: 0 + m_Name: PlayClipAbility_WindStone + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4717475142090746934 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7888626137513785884} + 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: 5296480593323786894} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &9004908790283913037 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7888626137513785884} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a26fca0fa72894a4da1a5a58ee023154, type: 3} + m_Name: + m_EditorClassIdentifier: + _config: {fileID: 11400000, guid: 02b79b9dc903c824786ed3cc3c3e225e, type: 2} --- !u!1 &8109938981782931710 GameObject: m_ObjectHideFlags: 0 @@ -1124,7 +1384,7 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 6397871098464242200} - - component: {fileID: 5510659119725211148} + - component: {fileID: 5509146531381767278} - component: {fileID: 6579043664862402528} m_Layer: 27 m_Name: HurtBox @@ -1148,8 +1408,8 @@ Transform: m_Children: [] m_Father: {fileID: 2025611111464161772} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!70 &5510659119725211148 -CapsuleCollider2D: +--- !u!61 &5509146531381767278 +BoxCollider2D: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -1180,9 +1440,19 @@ CapsuleCollider2D: m_IsTrigger: 1 m_UsedByEffector: 0 m_UsedByComposite: 0 - m_Offset: {x: 0, y: 0} - m_Size: {x: 1.1, y: 1.9} - m_Direction: 0 + m_Offset: {x: 0, y: 1} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0, y: 0} + oldSize: {x: 0, y: 0} + newSize: {x: 0, y: 0} + adaptiveTilingThreshold: 0 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1.2, y: 2} + m_EdgeRadius: 0 --- !u!114 &6579043664862402528 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1195,7 +1465,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d7b7a233d7f70aa4f86b473412b826de, type: 3} m_Name: m_EditorClassIdentifier: - _onDamageDealt: {fileID: 0} + _onDamageDealt: {fileID: 11400000, guid: eebd58cfef3527940949a8a7655a343b, type: 2} _onHitConfirmed: {fileID: 11400000, guid: a67d56f5124e0db4f98f326c74be8091, type: 2} --- !u!1 &8920059952006723162 GameObject: @@ -1206,7 +1476,7 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 80973138644072513} - - component: {fileID: 6125666153035542197} + - component: {fileID: 4535625604443592544} - component: {fileID: 4960688227238377219} - component: {fileID: 3072716489886911545} m_Layer: 25 @@ -1231,8 +1501,8 @@ Transform: m_Children: [] m_Father: {fileID: 2025611111464161772} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!70 &6125666153035542197 -CapsuleCollider2D: +--- !u!61 &4535625604443592544 +BoxCollider2D: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -1263,9 +1533,19 @@ CapsuleCollider2D: m_IsTrigger: 1 m_UsedByEffector: 0 m_UsedByComposite: 0 - m_Offset: {x: 0, y: 0} - m_Size: {x: 1.1, y: 1.9} - m_Direction: 0 + m_Offset: {x: 0, y: 1} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0, y: 0} + oldSize: {x: 0, y: 0} + newSize: {x: 0, y: 0} + adaptiveTilingThreshold: 0 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1.2, y: 2} + m_EdgeRadius: 0 --- !u!114 &4960688227238377219 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/_Game/Scenes/Testings/TestRoomA.unity b/Assets/_Game/Scenes/Testings/TestRoomA.unity index ec2ee748..a43d5c7c 100644 --- a/Assets/_Game/Scenes/Testings/TestRoomA.unity +++ b/Assets/_Game/Scenes/Testings/TestRoomA.unity @@ -7280,6 +7280,103 @@ MonoBehaviour: BarrelClipping: 0.25 Anamorphism: 0 BlendHint: 0 +--- !u!1 &378930082 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 378930085} + - component: {fileID: 378930084} + - component: {fileID: 378930083} + m_Layer: 24 + m_Name: BossFightTrigger_ChaoFeng + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &378930083 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 378930082} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bd8a9d00a149c124a9bd90ffba663a32, type: 3} + m_Name: + m_EditorClassIdentifier: + _bossBrain: {fileID: 2029340551999249091} + _onBossFightStarted: {fileID: 11400000, guid: 6ac21fc2929c8ce4b9f56df680ad122b, type: 2} + _onBossFightToggled: {fileID: 11400000, guid: f367dc6d9a2848241b54799ce37f7288, type: 2} + _bossId: ChaoFeng + _playerLayers: + serializedVersion: 2 + m_Bits: 512 +--- !u!61 &378930084 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 378930082} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 1 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0, y: 0} + oldSize: {x: 0, y: 0} + newSize: {x: 0, y: 0} + adaptiveTilingThreshold: 0 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 4, y: 6} + m_EdgeRadius: 0 +--- !u!4 &378930085 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 378930082} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 87, y: 21, 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!4 &379870868 stripped Transform: m_CorrespondingSourceObject: {fileID: 8020630769765462792, guid: dadbcefa02b3d0f4ba27af93ff088166, type: 3} @@ -217899,6 +217996,74 @@ Transform: - {fileID: 505494684} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &2029340551999249090 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalPosition.x + value: 98 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalPosition.y + value: 21 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2025611111464161772, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7781161515165213226, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + propertyPath: m_Name + value: ENM_ChaoFeng + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} +--- !u!114 &2029340551999249091 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 4739322141714049461, guid: e55e94346ed15ce40bc0ae5aa7771ea6, type: 3} + m_PrefabInstance: {fileID: 2029340551999249090} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d92d657c6bbdfe246a7333e04f79f8f7, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 @@ -217912,3 +218077,5 @@ SceneRoots: - {fileID: 960547555} - {fileID: 445140214} - {fileID: 310446327} + - {fileID: 2029340551999249090} + - {fileID: 378930085} diff --git a/Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs b/Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs index c31b63bb..c59d40fd 100644 --- a/Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs +++ b/Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs @@ -328,12 +328,12 @@ namespace BaseGames.Editor var factory = MakeActionGroup(); factory.Add(MakeFactoryButton("ENM_ChaoFeng_Stats.asset", () => { CreateChaoFengStatsSO(); RefreshSOStatus(); })); factory.Add(MakeFactoryButton("ENM_ChaoFeng_AnimConfig.asset",() => { CreateChaoFengAnimConfigSO(); RefreshSOStatus(); })); - foreach (var (abName, abId, soType, r, cd, w, ph) in ChaoFengAbilityDefs) + foreach (var (abName, abId, soType, r, cd, w, ph, g) in ChaoFengAbilityDefs) { string cName = abName; string cId = abId; System.Type cType = soType; - float cR = r, cCd = cd, cW = w; int cPh = ph; + float cR = r, cCd = cd, cW = w; int cPh = ph; bool cG = g; factory.Add(MakeFactoryButton($"ABL_ChaoFeng_{cName}.asset", - () => { CreateChaoFengAbilitySO(cName, cId, cType, cR, cCd, cW, cPh); RefreshSOStatus(); })); + () => { CreateChaoFengAbilitySO(cName, cId, cType, cR, cCd, cW, cPh, cG); RefreshSOStatus(); })); } root.Add(factory); @@ -691,7 +691,7 @@ namespace BaseGames.Editor private static void CreateChaoFengAbilitySO( string abilityName, string abilityId, System.Type soType, - float rangeRadius, float cooldown, float weight, int phase) + float rangeRadius, float cooldown, float weight, int phase, bool requiresGrounded) { const string dir = "Assets/_Game/Data/Enemies/ChaoFeng/Abilities"; string name = $"ABL_ChaoFeng_{abilityName}"; @@ -704,6 +704,9 @@ namespace BaseGames.Editor ? "入场演出,不进选招池" : $"阶段 {phase} 招式;阶段可用性由 BossPhaseAbilityGate 配置"; so.cooldown = cooldown; + // 空中阶段的招必须放开这一项:选招器把 requiresGrounded 当硬门, + // Boss 浮空时 IsGrounded 恒为 false,留着默认 true 会让该招永远选不中。 + so.requiresGrounded = requiresGrounded; if (phase < 0) { @@ -727,25 +730,27 @@ namespace BaseGames.Editor /// (见放置工具 PlaceChaoFeng),这里只记录供说明文本使用。 /// rangeRadius 必须 > 0:category==Attack 且射程为 0 的招永远够不着玩家, /// EnemyAbilitySO.Validate 与 EnemyBase.BuildAttackSelector 都会显式报错。 + /// grounded 是选招器的硬门:阶段 1 是空中阶段(Boss 浮空,IsGrounded 恒 false), + /// 该阶段的招必须为 false,否则永远选不中,空中阶段会站着不打。 /// private static readonly (string name, string id, System.Type soType, - float rangeRadius, float cooldown, float weight, int phase)[] + float rangeRadius, float cooldown, float weight, int phase, bool grounded)[] ChaoFengAbilityDefs = { - ("Intro", "chaofeng_intro", typeof(PlayClipAbilitySO), 0f, 0f, 0f, -1), - ("Boomerang", "boomerang", typeof(PlayClipAbilitySO), 9f, 4.0f, 1.0f, 0), - ("FanCombo", "fan_combo", typeof(EnemyAbilitySO), 2.5f, 2.5f, 1.5f, 0), - ("TornadoSmall", "tornado_small", typeof(PlayClipAbilitySO), 8f, 3.5f, 1.2f, 0), - ("TornadoLarge", "tornado_large", typeof(PlayClipAbilitySO), 12f, 6.0f, 0.8f, 0), - ("WindStone", "wind_stone", typeof(PlayClipAbilitySO), 12f, 3.0f, 1.0f, 1), + ("Intro", "chaofeng_intro", typeof(PlayClipAbilitySO), 0f, 0f, 0f, -1, true), + ("Boomerang", "boomerang", typeof(PlayClipAbilitySO), 9f, 4.0f, 1.0f, 0, true), + ("FanCombo", "fan_combo", typeof(EnemyAbilitySO), 2.5f, 2.5f, 1.5f, 0, true), + ("TornadoSmall", "tornado_small", typeof(PlayClipAbilitySO), 8f, 3.5f, 1.2f, 0, true), + ("TornadoLarge", "tornado_large", typeof(PlayClipAbilitySO), 12f, 6.0f, 0.8f, 0, true), + ("WindStone", "wind_stone", typeof(PlayClipAbilitySO), 12f, 3.0f, 1.0f, 1, false), }; private static void CreateAllChaoFengSOs() { CreateChaoFengStatsSO(); CreateChaoFengAnimConfigSO(); - foreach (var (n, id, t, r, cd, w, ph) in ChaoFengAbilityDefs) - CreateChaoFengAbilitySO(n, id, t, r, cd, w, ph); + foreach (var (n, id, t, r, cd, w, ph, g) in ChaoFengAbilityDefs) + CreateChaoFengAbilitySO(n, id, t, r, cd, w, ph, g); AssetDatabase.SaveAssets(); EditorUtility.DisplayDialog("创建完成", "全部嘲风 SO 已创建(已存在的跳过)。\n" + @@ -825,7 +830,7 @@ namespace BaseGames.Editor ("ENM_ChaoFeng_Stats", FindAtPath($"{dir}/ENM_ChaoFeng_Stats.asset")), ("ENM_ChaoFeng_AnimConfig",FindAtPath($"{dir}/ENM_ChaoFeng_AnimConfig.asset")), }; - foreach (var (abName, _, _, _, _, _, _) in ChaoFengAbilityDefs) + foreach (var (abName, _, _, _, _, _, _, _) in ChaoFengAbilityDefs) checks.Add(($"ABL_ChaoFeng_{abName}", FindAtPath($"{ablDir}/ABL_ChaoFeng_{abName}.asset"))); diff --git a/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs b/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs index a2a77b66..ef961fc5 100644 --- a/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs +++ b/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs @@ -302,6 +302,7 @@ namespace BaseGames.Editor EnemyStats enemyStats = GetOrAddComponent(go); EnemyMovement movement = GetOrAddComponent(go); GetOrAddComponent(go); // 地面导航(直接移动,无寻路图) + GetOrAddComponent(go); // 移动执行器:EnemyBase.Awake 必须找得到,否则 AI 图的移动意图无处落地 PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); var (hurtBox, bodyContact, contactHitBox) = @@ -445,6 +446,7 @@ namespace BaseGames.Editor EnemyStats enemyStats = GetOrAddComponent(go); EnemyMovement movement = GetOrAddComponent(go); GetOrAddComponent(go); // 地面导航(直接移动,无寻路图) + GetOrAddComponent(go); // 移动执行器:EnemyBase.Awake 必须找得到,否则 AI 图的移动意图无处落地 PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); var (hurtBox, bodyContact, contactHitBox) = @@ -493,9 +495,7 @@ namespace BaseGames.Editor SetupPerceptionSystemSlots(sensorHub, new[] { "aggro", "los" }, report); - GetOrAddComponent(go); - - // BrainGraph AI:挂载决策组件并绑定 AI 配方资产(取代旧的 Opsive BehaviorTree) + // BrainGraph AI:挂载决策组件并绑定 AI 配方资产 var brain = GetOrAddComponent(go); var recipe = AssetDatabase.LoadAssetAtPath( "Assets/_Game/Data/Enemies/E001/ENM_E001_Ai.asset"); @@ -550,6 +550,7 @@ namespace BaseGames.Editor EnemyStats enemyStats = GetOrAddComponent(go); EnemyMovement movement = GetOrAddComponent(go); GetOrAddComponent(go); // 地面导航(直接移动,无寻路图) + GetOrAddComponent(go); // 移动执行器:EnemyBase.Awake 必须找得到,否则 AI 图的移动意图无处落地 PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); // HurtBox + ContactDamageZone(身体接触伤害常驻开启;HurtBox 悬挂期外关闭见下) @@ -651,6 +652,7 @@ namespace BaseGames.Editor EnemyStats enemyStats = GetOrAddComponent(go); EnemyMovement movement = GetOrAddComponent(go); GetOrAddComponent(go); // 地面导航(直接移动,无寻路图) + GetOrAddComponent(go); // 移动执行器:EnemyBase.Awake 必须找得到,否则 AI 图的移动意图无处落地 PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); var (hurtBox, bodyContact, contactHitBox) = @@ -741,6 +743,7 @@ namespace BaseGames.Editor EnemyFeedback feedback = GetOrAddComponent(go); EnemyMovement movement = GetOrAddComponent(go); GetOrAddComponent(go); // 地面导航(直接移动,无寻路图) + GetOrAddComponent(go); // 移动执行器:EnemyBase.Awake 必须找得到,否则 AI 图的移动意图无处落地 PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); var (hurtBox, bodyContact, contactHitBox) = @@ -871,6 +874,7 @@ namespace BaseGames.Editor EnemyStats enemyStats = GetOrAddComponent(go); EnemyMovement movement = GetOrAddComponent(go); GetOrAddComponent(go); // 地面导航(直接移动,无寻路图) + GetOrAddComponent(go); // 移动执行器:EnemyBase.Awake 必须找得到,否则 AI 图的移动意图无处落地 PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); var (hurtBox, bodyContact, contactHitBox) = @@ -982,6 +986,7 @@ namespace BaseGames.Editor EnemyStats enemyStats = GetOrAddComponent(go); EnemyMovement movement = GetOrAddComponent(go); GetOrAddComponent(go); // 地面导航(直接移动,无寻路图) + GetOrAddComponent(go); // 移动执行器:EnemyBase.Awake 必须找得到,否则 AI 图的移动意图无处落地 PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); var (hurtBox, bodyContact, contactHitBox) = @@ -1084,6 +1089,10 @@ namespace BaseGames.Editor EnemyFeedback feedback = GetOrAddComponent(go); EnemyMovement movement = GetOrAddComponent(go); GetOrAddComponent(go); // 地面导航(直接移动,无寻路图) + // 移动执行器:AI 图的移动意图(Idle/Face/Approach)全靠它落地。 + // 少了它 EnemyBase.Awake 就报「未找到 EnemyLocomotion」,且 Locomotion 为 null, + // 建图时 AiStateFragments.ApplyLocomotion 会 NRE,AiRuntime 构造失败 → Boss 完全不动。 + GetOrAddComponent(go); EnemyAiBrain brain = GetOrAddComponent(go); BossPhaseAbilityGate phaseGate = GetOrAddComponent(go); ChaoFengFloatController floatCtrl = GetOrAddComponent(go); @@ -1094,16 +1103,16 @@ namespace BaseGames.Editor var (hurtBox, bodyContact, contactHitBox) = SetupHurtAndContactBoxes(go, size, report); - // Phase1 攻击 HitBox(默认禁用;由能力按 EnemyAttackSO.hitBoxSlot 归一化时机开关)。 - // 计划:挥扇三连 FanCombo ×3 + 龙卷接触 Tornado。 + // 近战攻击 HitBox(默认禁用;由 MeleeAttackAbility 按 EnemyAttackSO.hitBoxSlot 归一化时机开关)。 + // 只有挥扇三连需要 Boss 自身的判定;回旋扇 / 龙卷 / 风石都是弹体招, + // 判定随 SpawnProjectile 动画事件生成的弹体走,Boss 身上不留对应 HitBox + // (留一个无人引用的 HitBox 会让作者误以为该招判定挂在 Boss 身上)。 HitBox fan1 = CreateDisabledHitBox(go.transform, "Phase1_FanCombo_HitBox_1", "EnemyHitBox", true, report, size: new Vector2(1.0f, 0.5f)); HitBox fan2 = CreateDisabledHitBox(go.transform, "Phase1_FanCombo_HitBox_2", "EnemyHitBox", true, report, size: new Vector2(1.0f, 0.5f)); HitBox fan3 = CreateDisabledHitBox(go.transform, "Phase1_FanCombo_HitBox_3", "EnemyHitBox", true, report, size: new Vector2(1.2f, 0.6f)); - HitBox tornadoHB = CreateDisabledHitBox(go.transform, "Phase1_Tornado_HitBox", "EnemyHitBox", - true, report, size: new Vector2(0.6f, 1.2f)); // 弹体发射点(Phase1 回旋扇 / 龙卷;Phase2 风石) Transform boomerangMuzzleT = GetOrCreateChild(go.transform, "BoomerangMuzzle"); @@ -1212,7 +1221,7 @@ namespace BaseGames.Editor Object dmgSrc = FindFirstAsset("CMB_DS_BossBody", "CMB_DS_EnemyBody"); if (dmgSrc != null) { - foreach (var hb in new[] { fan1, fan2, fan3, tornadoHB, contactHitBox }) + foreach (var hb in new[] { fan1, fan2, fan3, contactHitBox }) if (hb != null) AssignReference(hb, "_defaultSource", dmgSrc, report); } @@ -1235,6 +1244,75 @@ namespace BaseGames.Editor MarkDirtyAndLog("Boss 嘲风 (ChaoFeng)", go, report); } + [MenuItem("BaseGames/Scene/Place/Boss 开战触发区 (嘲风)", priority = 118)] + public static void PlaceChaoFengFightTrigger() => PlaceBossFightTrigger("ChaoFeng"); + + /// + /// 放置 Boss 开战触发区:玩家进入即广播开战事件并让 Boss 决策层进战。 + /// 没有它,Boss 会一直停在静置态——开战事件频道此前全项目零发送方。 + /// + /// + /// Boss id。既写进触发器的 _bossId(BGM / 血条按它定位 Boss), + /// 也用来在活动场景里定位目标 Boss——按 EnemyAiBrain._definitionId 匹配。 + /// + public static void PlaceBossFightTrigger(string bossId) + { + var report = new List(); + int undoGroup = Undo.GetCurrentGroup(); + Undo.SetCurrentGroupName("Place Boss Fight Trigger"); + + GameObject go = new GameObject($"BossFightTrigger_{bossId}"); + Undo.RegisterCreatedObjectUndo(go, "Place Boss Fight Trigger"); + go.transform.position = GetDropPosition(); + SetLayer(go, "TriggerZone", report); + + // 碰撞体必须先于 BossFightTrigger 挂上:该组件标了 [RequireComponent(typeof(Collider2D))], + // 而 Collider2D 是抽象类,Unity 补不出来,AddComponent 会返回真正的 null。 + BoxCollider2D col = GetOrAddComponent(go); + col.isTrigger = true; + col.size = new Vector2(4f, 6f); // 门口尺寸占位,按竞技场入口在 Inspector 调整 + + BossFightTrigger trigger = GetOrAddComponent(go); + + AssignString(trigger, "_bossId", bossId, report); + AssignLayerMask(trigger, "_playerLayers", "Player", report); + AssignAsset(trigger, "_onBossFightStarted", report, true, "EVT_BossFightStarted"); + // 开关频道:资产名叫 EVT_BossFightEnded,但实际是「战斗中 true/false」的开关, + // BGMController 与 BossHPBar 绑的也是它。名字与用途不符是既存问题,此处沿用同一资产。 + AssignAsset(trigger, "_onBossFightToggled", report, true, "EVT_BossFightEnded"); + + // 目标 Boss:按 EnemyAiBrain._definitionId 在活动场景里精确匹配,不做名字模糊猜测。 + // 匹配不到(或匹配到多个)一律如实报告,不塞一个凑数的引用—— + // 漏绑时 BossFightTrigger.Awake 也会再报一次并停用自己。 + var matches = new List(); + foreach (var root in UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene().GetRootGameObjects()) + foreach (var b in root.GetComponentsInChildren(true)) + if (new SerializedObject(b).FindProperty("_definitionId")?.stringValue == bossId) + matches.Add(b); + + if (matches.Count == 1) + { + AssignReference(trigger, "_bossBrain", matches[0], report); + report.Add($"[OK] _bossBrain → {matches[0].name}(_definitionId={bossId})"); + } + else if (matches.Count == 0) + { + report.Add($"✗ 活动场景里找不到 _definitionId={bossId} 的 EnemyAiBrain," + + "_bossBrain 未绑定。请先放置该 Boss,再重跑本操作。"); + } + else + { + report.Add($"✗ 活动场景里有 {matches.Count} 个 _definitionId={bossId} 的 EnemyAiBrain," + + "无法确定目标,_bossBrain 未绑定。请先清理重复的 Boss。"); + } + + report.Add("★ 把触发区拖到竞技场入口并按门口尺寸调整 BoxCollider2D。只触发一次。"); + + Undo.CollapseUndoOperations(undoGroup); + Selection.activeGameObject = go; + MarkDirtyAndLog($"Boss 开战触发区 ({bossId})", go, report); + } + // ══ 敌人放置辅助方法 ═══════════════════════════════════════════════════ /// diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/EnemyBrainContext.cs b/Assets/_Game/Scripts/Enemies/AIBrain/EnemyBrainContext.cs index 8b46a078..6fb2bf63 100644 --- a/Assets/_Game/Scripts/Enemies/AIBrain/EnemyBrainContext.cs +++ b/Assets/_Game/Scripts/Enemies/AIBrain/EnemyBrainContext.cs @@ -67,10 +67,26 @@ namespace BaseGames.Enemies public Vector2 LastKnown => _lastKnown; // ---- ICombatant ---- + /// + /// 执行指定 id 的能力。解析不到该 id 一律显式报错—— + /// 建图期 AiStateFragments.Ability/AbilityOnce 已挡掉空 id, + /// 所以运行期解析不到只可能是漏挂能力组件或 SO 上的 abilityId 写错,没有合法情形。 + /// 静默返回 false 会让「能力态进入后什么都不做、IsAbilityRunning 恒假、 + /// 完成条件立刻成立」表现为"演出被跳过"却零报错(CLAUDE.md 第 6 条)。 + /// 用 LogError 而非抛异常:这是每帧路径,抛异常会打断整个 AiRuntime.Tick, + /// 让一个漏配的敌人拖垮整场战斗。 + /// public bool UseAbility(string abilityId) { var a = _enemy.Abilities?.Get(abilityId); - return a != null && a.Execute(); + if (a == null) + { + Debug.LogError($"[EnemyBrainContext] '{_enemy.name}' 的 AI 图请求能力 " + + $"'{abilityId}',但该敌人身上没有这个能力组件。" + + "请检查能力组件是否挂载、其 EnemyAbilitySO 的 abilityId 是否一致。", _enemy); + return false; + } + return a.Execute(); } public bool IsAbilityRunning(string abilityId = null) { diff --git a/Assets/_Game/Scripts/Enemies/Boss/BossBase.cs b/Assets/_Game/Scripts/Enemies/Boss/BossBase.cs index 7157e7e7..5905b3ad 100644 --- a/Assets/_Game/Scripts/Enemies/Boss/BossBase.cs +++ b/Assets/_Game/Scripts/Enemies/Boss/BossBase.cs @@ -86,6 +86,16 @@ namespace BaseGames.Enemies if (_arenaAnchors == null) _arenaAnchors = GetComponentInChildren(true); } + // 初始阶段的招池必须在第一次选招前就位。 + // ApplyPhase 此前只在 EnterPhase(阶段切换)与 OnSpawn(对象池复用)里调用, + // 而直接摆在场景里的 Boss 两条路径都不走——开局时后续阶段的招式仍是 enabled, + // 会混进阶段 0 的候选池。放在 Start:此时各能力组件的 Awake 均已执行完毕。 + protected override void Start() + { + base.Start(); + _phaseGate?.ApplyPhase(_currentPhase); + } + protected override void OnEnable() { base.OnEnable();