diff --git a/Assets/GameMain/Configs/ResourceBuilder.xml b/Assets/GameMain/Configs/ResourceBuilder.xml
index 8c08148..ad28384 100644
--- a/Assets/GameMain/Configs/ResourceBuilder.xml
+++ b/Assets/GameMain/Configs/ResourceBuilder.xml
@@ -7,8 +7,8 @@
1
UnityGameFramework.Runtime.DefaultCompressionHelper
False
- True
- VampireLike.Editor.VampireLikeBuildEventHandler
+ False
+ SepCore.Editor.DefaultBuildEventHandler
D:/Learn/GameLearn/UnityProjects/VampireLike/bin/AssetBundles
True
True
diff --git a/Assets/GameMain/Configs/ResourceCollection.xml b/Assets/GameMain/Configs/ResourceCollection.xml
index f948d45..f3c895d 100644
--- a/Assets/GameMain/Configs/ResourceCollection.xml
+++ b/Assets/GameMain/Configs/ResourceCollection.xml
@@ -31,20 +31,27 @@
-
+
+
+
+
+
+
+
+
@@ -57,24 +64,30 @@
+
+
+
+
+
+
@@ -82,26 +95,35 @@
+
+
+
+
+
+
+
+
+
@@ -111,10 +133,12 @@
+
+
@@ -122,17 +146,24 @@
+
-
+
+
+
+
+
+
+
@@ -140,55 +171,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs b/Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs
index 4cbcf0e..27e2070 100644
--- a/Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs
+++ b/Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs
@@ -8,6 +8,7 @@ using GameFramework.Fsm;
using GameFramework.Procedure;
using SepCore.EnemyManager;
using SepCore.Simulation;
+using SepCore.Timer;
using UnityEngine;
namespace SepCore.Procedure
@@ -20,7 +21,7 @@ namespace SepCore.Procedure
private int _currentLevel;
- private float _levelTimeLeft;
+ private TimerHandle _levelTimerHandle;
private Player Player => _procedureGame.Player;
@@ -29,7 +30,11 @@ namespace SepCore.Procedure
public void AddBattleDuration(float seconds)
{
if (seconds <= 0f) return;
- _levelTimeLeft += seconds;
+
+ float remaining = GameEntry.Timer.GetRemainingTime(_levelTimerHandle);
+ if (remaining < 0f) return;
+
+ GameEntry.Timer.ResetRemainingTime(_levelTimerHandle, remaining + seconds);
}
#region FSM
@@ -51,7 +56,7 @@ namespace SepCore.Procedure
throw new Exception($"GameStateBattle.OnEnter: {_currentLevel} is not found.");
}
- _levelTimeLeft = drLevel.Duration;
+ _levelTimerHandle = GameEntry.Timer.ScheduleOnce(drLevel.Duration, OnLevelTimeUp, this);
_enemyManager.OnInit(drLevel, Player);
if (Player != null) Player.Enable = true;
@@ -64,12 +69,6 @@ namespace SepCore.Procedure
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
- if (_levelTimeLeft < 0)
- {
- _procedureGame.BattleToShopOrLevelUp();
- return;
- }
-
_enemyManager.OnUpdate(elapseSeconds, realElapseSeconds);
SimulationWorld simulationWorld = GameEntry.SimulationWorld;
@@ -79,14 +78,22 @@ namespace SepCore.Procedure
simulationWorld.Tick(new SimulationTickContext(elapseSeconds, realElapseSeconds, playerPosition));
}
- _levelTimeLeft -= elapseSeconds;
- GameEntry.Event.Fire(this, LevelProcessEventArgs.Create((int)_levelTimeLeft));
+ int timeLeft = Mathf.Max(0, (int)GameEntry.Timer.GetRemainingTime(_levelTimerHandle));
+ GameEntry.Event.Fire(this, LevelProcessEventArgs.Create(timeLeft));
+ }
+
+ private void OnLevelTimeUp()
+ {
+ _procedureGame.BattleToShopOrLevelUp();
}
public override void OnLeave()
{
GameEntry.UIRouter.CloseUIAsync(UIFormType.JoystickForm).Forget();
+ GameEntry.Timer.Cancel(_levelTimerHandle);
+ _levelTimerHandle = TimerHandle.Invalid;
+
// 隐藏所有敌人实体
_enemyManager.OnReset();
diff --git a/Assets/Launcher.unity b/Assets/Launcher.unity
index 725f25a..e793a7a 100644
--- a/Assets/Launcher.unity
+++ b/Assets/Launcher.unity
@@ -738,7 +738,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 11499388, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3}
propertyPath: m_EditorResourceMode
- value: 1
+ value: 0
objectReference: {fileID: 0}
- target: {fileID: 11499388, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3}
propertyPath: m_JsonHelperTypeName
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor.meta b/Assets/Plugins/InputModule/Editor/Editor.meta
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor.meta
rename to Assets/Plugins/InputModule/Editor/Editor.meta
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/DynamicJoystickEditor.cs b/Assets/Plugins/InputModule/Editor/Editor/DynamicJoystickEditor.cs
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/DynamicJoystickEditor.cs
rename to Assets/Plugins/InputModule/Editor/Editor/DynamicJoystickEditor.cs
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/DynamicJoystickEditor.cs.meta b/Assets/Plugins/InputModule/Editor/Editor/DynamicJoystickEditor.cs.meta
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/DynamicJoystickEditor.cs.meta
rename to Assets/Plugins/InputModule/Editor/Editor/DynamicJoystickEditor.cs.meta
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/FloatingJoystickEditor.cs b/Assets/Plugins/InputModule/Editor/Editor/FloatingJoystickEditor.cs
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/FloatingJoystickEditor.cs
rename to Assets/Plugins/InputModule/Editor/Editor/FloatingJoystickEditor.cs
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/FloatingJoystickEditor.cs.meta b/Assets/Plugins/InputModule/Editor/Editor/FloatingJoystickEditor.cs.meta
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/FloatingJoystickEditor.cs.meta
rename to Assets/Plugins/InputModule/Editor/Editor/FloatingJoystickEditor.cs.meta
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/JoystickEditor.cs b/Assets/Plugins/InputModule/Editor/Editor/JoystickEditor.cs
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/JoystickEditor.cs
rename to Assets/Plugins/InputModule/Editor/Editor/JoystickEditor.cs
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/JoystickEditor.cs.meta b/Assets/Plugins/InputModule/Editor/Editor/JoystickEditor.cs.meta
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/JoystickEditor.cs.meta
rename to Assets/Plugins/InputModule/Editor/Editor/JoystickEditor.cs.meta
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/VariableJoystickEditor.cs b/Assets/Plugins/InputModule/Editor/Editor/VariableJoystickEditor.cs
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/VariableJoystickEditor.cs
rename to Assets/Plugins/InputModule/Editor/Editor/VariableJoystickEditor.cs
diff --git a/Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/VariableJoystickEditor.cs.meta b/Assets/Plugins/InputModule/Editor/Editor/VariableJoystickEditor.cs.meta
similarity index 100%
rename from Assets/Plugins/InputModule/Presentation/JoystickPack/Editor/VariableJoystickEditor.cs.meta
rename to Assets/Plugins/InputModule/Editor/Editor/VariableJoystickEditor.cs.meta
diff --git a/Assets/Plugins/InputModule/Editor/SepCore.InputModule.Editor.asmdef b/Assets/Plugins/InputModule/Editor/SepCore.InputModule.Editor.asmdef
index c19fd6c..3de2279 100644
--- a/Assets/Plugins/InputModule/Editor/SepCore.InputModule.Editor.asmdef
+++ b/Assets/Plugins/InputModule/Editor/SepCore.InputModule.Editor.asmdef
@@ -5,7 +5,8 @@
"GUID:d54b9488b03814a44ab937f0aeb738b1",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:363c5eb08ff8e6a439b85e37b8c20d96",
- "GUID:436e23dbdc31e7d4fb5c3f804548b2df"
+ "GUID:436e23dbdc31e7d4fb5c3f804548b2df",
+ "GUID:0e1d182005e0ae647ab3fa40f5492dbb"
],
"includePlatforms": [
"Editor"
diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset
index 5eac22c..f7b31b2 100644
--- a/ProjectSettings/UnityConnectSettings.asset
+++ b/ProjectSettings/UnityConnectSettings.asset
@@ -4,7 +4,7 @@
UnityConnectSettings:
m_ObjectHideFlags: 0
serializedVersion: 1
- m_Enabled: 0
+ m_Enabled: 1
m_TestMode: 0
m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events
m_EventUrl: https://cdp.cloud.unity3d.com/v1/events
@@ -25,7 +25,7 @@ UnityConnectSettings:
m_Enabled: 0
m_TestMode: 0
m_InitializeOnStartup: 1
- m_PackageRequiringCoreStatsPresent: 0
+ m_PackageRequiringCoreStatsPresent: 1
UnityAdsSettings:
m_Enabled: 0
m_InitializeOnStartup: 1
diff --git a/skills/simulation-development/SKILL.md b/skills/simulation-development/SKILL.md
deleted file mode 100644
index bcce81f..0000000
--- a/skills/simulation-development/SKILL.md
+++ /dev/null
@@ -1,103 +0,0 @@
----
-name: simulation-development
-description: Maintain, review, refactor, and extend VampireLike SimulationWorld architecture. Use when working on SimulationWorld data ownership, entity lifecycle sync, tick pipeline orchestration, Job/Burst data channels, projectile or area collision settlement, target-selection indexing, presentation write-back, or Simulation regression tests and architecture documentation that must preserve core invariants.
----
-
-# Simulation Development
-
-1. Read `./references/SimulationDevelopmentSkill.md` first.
-2. Treat current code as the source of truth when the reference and implementation diverge.
-3. Load only the source files needed for the task from the map below.
-4. Keep architecture changes and behavior changes explicit; do not hide them inside unrelated edits.
-
-## Source Map
-
-- Core entry: `../../Assets/GameMain/Scripts/Simulation/SimulationWorld.cs`
-- Sim state lifecycle: `../../Assets/GameMain/Scripts/Simulation/SimulationWorld.SimEntityState.cs`
-- Entity lifecycle bridge: `../../Assets/GameMain/Scripts/Simulation/SimulationWorld.EntitySync.cs`
-- Job data channel: `../../Assets/GameMain/Scripts/Simulation/DataChannel/SimulationWorld.JobDataChannel.cs`
-- Enemy pipeline: `../../Assets/GameMain/Scripts/Simulation/Jobs/SimulationWorld.EnemyJobs.cs`
-- Projectile pipeline: `../../Assets/GameMain/Scripts/Simulation/Jobs/SimulationWorld.ProjectileJobs.cs`
-- Collision pipeline: `../../Assets/GameMain/Scripts/Simulation/Jobs/SimulationWorld.CollisionPipeline.cs`
-- Target selection index: `../../Assets/GameMain/Scripts/Simulation/SimulationWorld.TargetSelectionSpatialIndex.cs`
-- Transform write-back: `../../Assets/GameMain/Scripts/Simulation/Presentation/SimulationWorld.TransformSync.cs`
-- Hit presentation bridge: `../../Assets/GameMain/Scripts/Simulation/Presentation/SimulationWorld.HitPresentation.cs`
-- Tick context: `../../Assets/GameMain/Scripts/Simulation/SimulationTickContext.cs`
-- Entity index binding: `../../Assets/GameMain/Scripts/Simulation/EntityBinding.cs`
-- Battle update entry: `../../Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs`
-- Procedure-level cleanup: `../../Assets/GameMain/Scripts/Procedure/Game/ProcedureGame.cs`
-- Damage and collision utility: `../../Assets/GameMain/Scripts/Utility/AIUtility.cs`
-- Regression tests:
- - `../../Assets/Tests/Simulation/EditMode/SimulationWorldTickTests.cs`
- - `../../Assets/Tests/Simulation/PlayMode/SimulationWorldPlayModeTests.cs`
-
-## Workflow
-
-1. Classify the change before editing:
- - simulation state contract
- - entity lifecycle mapping
- - tick pipeline stage
- - collision or area query semantics
- - presentation write-back
- - test or architecture doc maintenance
-2. Preserve the main boundaries:
- - `Tick` remains the only simulation logic entry
- - lifecycle registration and removal remain centralized
- - logic does not write `Transform`
- - damage, event dispatch, entity hiding, and recycle stay on the main thread
-3. Extend data first when behavior depends on new state:
- - update `SimData`
- - update job input/output structs
- - update conversion and initialization paths
-4. Reuse an existing pipeline stage before adding a new one.
-5. Update `./references/SimulationDevelopmentSkill.md` when module boundaries, invariants, or execution flow change.
-6. Add or adjust Simulation tests for every behavior change.
-
-## Non-Negotiable Invariants
-
-- Keep `_enemies`, `_projectiles`, and `_pickups` as the persistent source of truth.
-- Keep `EntityBinding` consistent with container indices.
-- Use swap-back removal with remap before unbind.
-- Drive container add/remove only through lifecycle sync and sim state helpers.
-- Keep target-selection buckets and collision buckets as rebuildable caches, not persistent business state.
-- Keep area query snapshot semantics intact.
-- Avoid managed allocations and LINQ in hot paths.
-
-## Change Guidance
-
-### Extend Simulation State
-
-1. Add fields to the relevant sim data and job structs.
-2. Populate defaults in the lifecycle registration path.
-3. Flow the data through the execution stage that owns it.
-4. Consume presentation-only values in Presentation code, not in simulation jobs.
-
-### Extend Lifecycle Mapping
-
-1. Add the entity group mapping in `SimulationWorld.EntitySync.cs`.
-2. Register and unregister through dedicated sim state helpers.
-3. Preserve clear ownership over which container the entity enters.
-
-### Extend Tick Pipeline
-
-1. Place logic inside the smallest existing stage that fits.
-2. Keep job work data-oriented and side-effect free.
-3. Apply outputs back to sim state before any presentation write-back.
-
-### Extend Collision Behavior
-
-1. Separate broad-phase candidate generation from final settlement.
-2. Preserve dedup and snapshot behavior on the main thread.
-3. Route gameplay effects through the existing main-thread settlement path.
-
-### Extend Presentation
-
-1. Read simulation output only after logic settlement is complete.
-2. Do not mutate simulation state from presentation code.
-
-## Validation
-
-- Verify index stability after removal paths.
-- Verify clear/reset paths leave no stale bindings or transient buffers.
-- Verify behavior under the relevant Simulation tests.
-- Verify the reference doc still matches the code after architectural edits.
diff --git a/skills/simulation-development/agents/openai.yaml b/skills/simulation-development/agents/openai.yaml
deleted file mode 100644
index 286be52..0000000
--- a/skills/simulation-development/agents/openai.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-interface:
- display_name: "Simulation Development"
- short_description: "Extend VampireLike SimulationWorld safely"
- default_prompt: "Use $simulation-development to implement, review, or extend a SimulationWorld change while preserving architecture invariants."
diff --git a/skills/simulation-development/references/SimulationDevelopmentSkill.md b/skills/simulation-development/references/SimulationDevelopmentSkill.md
deleted file mode 100644
index 623ce68..0000000
--- a/skills/simulation-development/references/SimulationDevelopmentSkill.md
+++ /dev/null
@@ -1,311 +0,0 @@
-# SimulationWorld Architecture Specification
-
-## 文档定位
-本文件是 `SimulationWorld` 的架构规范与扩展开发约束。
-
-用途分为两部分:
-- 作为当前 `SimulationWorld` 实现的架构总览,说明模块职责、依赖边界、运行链路和数据所有权。
-- 作为后续扩展、重构、性能优化和回归修复时的约束文档,防止破坏核心不变量。
-
-文档与实现冲突时,当前分支源码优先;提交前必须同步修正文档。
-
-## 适用范围
-- `Assets/GameMain/Scripts/Simulation/*`
-- `Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs`
-- `Assets/GameMain/Scripts/Procedure/Game/ProcedureGame.cs`
-- `Assets/GameMain/Scripts/Utility/AIUtility.cs`
-- `Assets/Tests/Simulation/EditMode/*`
-- `Assets/Tests/Simulation/PlayMode/*`
-
-## 架构目标
-- 将战斗中的敌人、投射物、掉落物运行时状态收口到统一仿真容器。
-- 将热路径逻辑与 Unity 表现层解耦,避免在仿真阶段直接读写 `Transform`。
-- 为 Job/Burst 提供稳定的数据通道、生命周期管理和主线程结算收口点。
-- 保持 `SimulationWorld` 对外是单一战斗调度入口,而不是分散的业务入口集合。
-- 保证扩展新仿真对象或新碰撞规则时,能够沿着既有管线接入,而不是旁路修改。
-
-## 非目标
-- 不负责完整战斗规则定义。伤害公式、碰撞业务语义仍由 `AIUtility` 和实体逻辑承担。
-- 不负责实体创建策略。实体创建与隐藏仍由外部流程和 Entity 系统负责。
-- 不追求全局 ECS 化。本模块仍以 `SimulationWorld + partial + Native 容器` 为中心组织。
-- 不在 Job 中直接驱动表现层、事件系统或 Unity 对象生命周期。
-
-## 外部依赖与系统边界
-`SimulationWorld` 处于战斗流程中层,位于 `GameStateBattle` 和具体实体逻辑之间。
-
-上游依赖:
-- `GameStateBattle.OnUpdate` 驱动每帧 `Tick`。
-- `GameEntry.Event` 提供实体显示/隐藏事件,用于同步仿真容器生命周期。
-- `GameEntry.Entity` 提供实体查询、隐藏和表现事件消费。
-
-下游协作:
-- `AIUtility` 负责伤害与碰撞业务结算。
-- Enemy/Projectile/Drop 实体提供初始化所需运行时数据。
-- Presentation 子模块负责把仿真结果写回表现层。
-
-边界要求:
-- 外部业务代码不得直接增删 `_enemies`、`_projectiles`、`_pickups`。
-- 外部业务代码不得绕过 `SimulationWorld` 直接维护仿真索引。
-- `SimulationWorld` 不直接拥有实体生成权,只消费实体生命周期事件。
-
-## 模块结构
-`SimulationWorld` 使用 `partial` 拆分,职责按以下边界划分:
-
-- `SimulationWorld.cs`
- - 核心组件入口、主状态容器、基础依赖、Unity 生命周期入口。
-- `SimulationWorld.SimEntityState.cs`
- - 敌人、投射物、掉落物的仿真态创建、更新、删除和清空。
-- `SimulationWorld.EntitySync.cs`
- - 监听实体 show/hide 事件,将实体生命周期映射到仿真容器。
-- `DataChannel/SimulationWorld.JobDataChannel.cs`
- - Native 容器持有、初始化、清理、容量准备、仿真数据到 Job 数据的转换。
-- `Jobs/SimulationWorld.EnemyJobs.cs`
- - 每帧仿真主编排、敌人移动与互斥分离 Job 调度。
-- `Jobs/SimulationWorld.ProjectileJobs.cs`
- - 投射物移动、寿命处理、越界回收。
-- `Jobs/SimulationWorld.CollisionPipeline.cs`
- - 投射物与区域碰撞查询构建、候选筛选、主线程命中结算。
-- `SimulationWorld.TargetSelectionSpatialIndex.cs`
- - 敌人目标选择空间索引。
-- `Presentation/SimulationWorld.TransformSync.cs`
- - `LateUpdate` 表现写回。
-- `Presentation/SimulationWorld.HitPresentation.cs`
- - 命中事件的表现消费桥。
-
-## 核心数据所有权
-### 主容器
-- `_enemies`
-- `_projectiles`
-- `_pickups`
-
-这些容器是真实仿真态所有者。Job 输入输出缓冲只是当前帧的镜像通道,不是持久源数据。
-
-### 绑定关系
-- `EntityBinding` 维护 `EntityId <-> SimulationIndex` 双向映射。
-- 容器删除使用 `swap-back`。
-- 发生尾元素覆盖时,必须同步 `RemapIndex`。
-- 删除完成后再 `Unbind`,避免索引悬挂。
-
-### Native 容器
-- Job 通道一律使用 `Allocator.Persistent`。
-- 生命周期由 `InitializeJobDataChannels` / `DisposeJobDataChannels` 集中管理。
-- 帧间复用时使用 `Clear`,不允许用临时重建替代正常复用。
-- Job 数据与主容器数据之间的转换必须集中在 `JobDataChannel` 侧完成。
-
-## 生命周期模型
-### 实体进入仿真
-统一由 `EntitySync` 监听实体显示事件后触发:
-- Enemy group -> `RegisterEnemyLifecycle`
-- Drop group -> `RegisterPickupLifecycle`
-- Bullet / Projectile / EnemyProjectile group -> `RegisterProjectileLifecycle`
-
-### 实体退出仿真
-统一由 `EntitySync` 监听实体隐藏事件后触发:
-- Enemy -> `UnregisterEnemyLifecycle`
-- Drop -> `UnregisterPickupLifecycle`
-- Projectile 相关 group -> `UnregisterProjectileLifecycle`
-
-### 清场
-`ClearSimulationState` 负责:
-- 清空主容器
-- 清空投射物回收与结算缓存
-- 清空区域碰撞请求与命中缓存
-- 清空 Job 通道
-- 清空全部 `EntityBinding`
-
-## 运行时执行链路
-### 帧级入口
-1. `GameStateBattle.OnUpdate`
-2. `_enemyManager.OnUpdate(...)`
-3. `SimulationWorld.Tick(...)`
-4. `SimulationWorld.LateUpdate()`
-
-### Tick 总流程
-`SimulationWorld.Tick` 是战斗仿真的唯一主入口。
-
-约束:
-- 当 `UseSimulationMovement == false` 时,直接返回。
-- `Tick` 只负责逻辑仿真与结算,不直接写 `Transform`。
-
-### 每帧仿真管线
-当前实现的标准顺序为:
-1. Early Return
- - `DeltaTime <= 0` 时只清理碰撞临时通道和统计。
-2. BuildInput
- - 将 `_enemies` / `_projectiles` 同步为 Job 输入。
- - 准备敌人输出、投射物输出、碰撞查询缓冲。
-3. StateUpdate
- - 调度敌人移动 Job。
- - 调度投射物移动 Job。
-4. Schedule
- - 按需调度敌人互斥分离 Job。
- - 合并敌人与投射物 Job 依赖。
-5. Complete
- - 等待本帧仿真 Job 完成。
-6. Collision
- - 构建碰撞查询。
- - 构建敌人碰撞桶。
- - 生成候选并统计。
-7. WriteBack
- - 把输出写回主容器。
- - 在主线程结算碰撞与伤害。
- - 回收失效投射物。
-
-### LateUpdate
-`LateUpdate` 只做表现写回,不做逻辑判定:
-- 敌人位置/朝向写回
-- 投射物位置/朝向写回
-
-## 线程模型与边界
-### Job/Burst 允许做的事
-- 读取 Job 输入缓冲
-- 写入 Job 输出缓冲
-- 写入 NativeHashMap / NativeList 等碰撞与分桶数据
-- 执行纯数据计算
-
-### Job/Burst 禁止做的事
-- 读写 `Transform`
-- 操作 GameObject / Entity 生命周期
-- 调用事件系统
-- 直接调用 `AIUtility.PerformCollision`
-- 进行托管分配、LINQ、装箱
-
-### 主线程必须做的事
-- 应用输出到仿真主容器
-- 命中结算与伤害计算
-- 投射物失效回收
-- 命中表现事件派发
-- `LateUpdate` 表现写回
-
-## 子系统约束
-### 敌人仿真
-固定接入点:
-- BuildInput
-- Movement
-- Separation
-- WriteBack
-
-约束:
-- 敌人状态必须以 `EnemySimData` 为中心流动。
-- 互斥与移动结果必须先写入输出缓冲,再统一提交。
-- 与目标选择相关的空间索引脏标记必须在主容器变更时维护。
-
-### 投射物仿真
-固定接入点:
-- BuildInput
-- Movement
-- Collision Query
-- Resolve
-- Recycle
-
-约束:
-- 投射物生命周期状态必须由 `ProjectileSimData.Active` 和 `State` 共同表达。
-- 投射物实际隐藏与移除只能在主线程回收阶段完成。
-
-### 碰撞管线
-职责:
-- 构建投射物查询和区域查询
-- 生成 broad-phase 候选
-- 在主线程做最终业务结算
-
-约束:
-- Broad-phase 只能筛候选,不能替代最终命中判定。
-- Area Query 必须保留 `SourceWasActiveAtQueryTime` 快照语义。
-- 候选去重与区域命中去重只能在主线程收口。
-
-### 目标选择空间索引
-职责:
-- 提供按位置查询最近敌人的能力。
-
-约束:
-- 仅在仿真启用时对外提供结果。
-- 敌人主容器变更后必须标记脏。
-- 索引是缓存,不是源数据;源数据仍是 `_enemies`。
-
-### Presentation
-职责:
-- 将仿真层结果写回表现层。
-- 消费命中表现事件。
-
-约束:
-- Presentation 只消费仿真结果,不反向修改仿真逻辑状态。
-- 任何新增表现都应接在 `Presentation` 子模块,而不是接回 Job 或业务结算热路径。
-
-## 不可破坏的不变量
-### 生命周期单入口
-仿真容器的增删必须只经过 `EntitySync` 和 `SimEntityState`。
-
-### 数据单一事实来源
-主容器是持续态事实来源,Job 缓冲只是帧级副本。
-
-### 逻辑与表现分离
-逻辑阶段不写 `Transform`,表现阶段不做业务结算。
-
-### 索引一致性
-任何 `swap-back` 删除都必须同步 remap,否则视为架构级错误。
-
-### 主线程结算收口
-伤害、事件派发、实体隐藏和回收必须回到主线程。
-
-### 空间索引与碰撞桶是缓存
-它们可以重建,不可被外部业务当作持久数据依赖。
-
-## 扩展开发流程
-### Step 0:判定接入位置
-先判断新需求属于:
-- 新仿真态字段
-- 新执行阶段逻辑
-- 新碰撞查询类型
-- 新表现桥接
-
-不要一开始就直接改 `Tick` 主流程。
-
-### Step 1:扩状态
-先补 `SimData`、必要的 Job 输入输出结构和转换逻辑。
-
-### Step 2:接生命周期
-如果是新实体类型,先定义 show/hide 到仿真态的映射,再进入执行阶段。
-
-### Step 3:接执行管线
-优先复用已有阶段;只有确实无法收纳时才新增阶段,并补可观测的 profiler 标记。
-
-### Step 4:接主线程结算
-需要业务判定、伤害、事件派发、实体隐藏时,一律回主线程收口。
-
-### Step 5:接表现
-视觉写回、命中反馈、临时特效都放在 `Presentation` 侧。
-
-### Step 6:补测试
-至少覆盖:
-- 正常行为
-- 空容器和边界条件
-- 删除后的索引稳定性
-- 碰撞去重或快照语义
-- 与旧路径一致的关键行为
-
-### Step 7:更新文档
-修改模块边界、数据契约、不变量或执行阶段时,必须同步更新本文件。
-
-## 回归关注点
-- `ClearSimulationState` 是否把主容器、缓存和 binding 一并清干净。
-- 删除路径是否保持 `swap-back + remap` 一致。
-- Job Native 容器是否有泄漏或容量管理回退。
-- 是否在热路径引入托管分配。
-- 是否让表现逻辑重新侵入仿真逻辑。
-- 是否破坏 Area Query 快照语义。
-- 是否破坏碰撞候选与命中去重。
-
-## 测试建议
-至少保留并持续扩展以下类型的测试:
-- Tick 行为正确性
-- 主线程与 Job 管线一致性
-- 最近敌查询正确性
-- 投射物候选上限与玩家候选覆盖
-- Area Query 快照语义
-- 清场和 Battle 循环稳定性
-
-## 维护原则
-如果未来需要继续扩展为多模式仿真开关、更多 Job 管线层级或新的仿真对象类型,应优先维护以下三点:
-- `Tick` 仍然只有一个主入口
-- 仿真态生命周期仍然只有一个注册/反注册入口
-- 主线程结算与表现写回边界不被打穿
diff --git a/skills/ui-five-layer-architecture/SKILL.md b/skills/ui-five-layer-architecture/SKILL.md
deleted file mode 100644
index 4b898d0..0000000
--- a/skills/ui-five-layer-architecture/SKILL.md
+++ /dev/null
@@ -1,81 +0,0 @@
----
-name: ui-five-layer-architecture
-description: Define, review, and refactor UI modules using a strict five-layer architecture (UseCase, RawData, Controller, Context, View). Use when creating cross-project UI architecture standards, designing new UI modules, reviewing layer boundaries and event flow, converting ad-hoc UI code into layered structure, or validating UI test strategy for business-driven interfaces.
----
-
-# UI Five-Layer Architecture
-
-## Quick Start
-
-1. Read `./references/ui-five-layer-standard.md`.
-2. Classify the UI as `standard-five-layer` or `lightweight`.
-3. Apply boundary rules before editing code or writing design output.
-4. Use the checklists in this file to drive design, review, or refactor tasks.
-
-## Workflow
-
-### 1. Scope the task
-
-Decide which mode the user needs:
-
-- architecture-spec mode: create or revise a UI architecture standard
-- design mode: design one or more UI modules before coding
-- implementation mode: implement or refactor code to match the standard
-- review mode: audit existing code for boundary or dependency violations
-
-### 2. Choose module level
-
-Use `standard-five-layer` when UI owns business state transitions, validations, or branching behavior.
-
-Use `lightweight` when UI only handles display/navigation and has no independent business rules.
-
-### 3. Enforce non-negotiable boundaries
-
-Apply these constraints in every mode:
-
-- keep `UseCase` business-only and return only `RawData/Result`
-- build `Context` only inside `Controller`
-- keep `View` presentation-only and event-emitting only
-- keep `View` out of global business event subscriptions
-- route external UI open/close/refresh through `Controller`
-
-### 4. Apply communication and dependency checks
-
-Validate:
-
-- dependency direction is valid for all touched files
-- UI-specific events stay UI-local in meaning
-- `Controller` filters sender and instance scope when needed
-- no `RawData` field uses `*Context` types
-
-### 5. Produce mode-specific output
-
-- architecture-spec mode:
- - output the final standard text
- - include strict rules, permitted exceptions, and checklists
-- design mode:
- - output layer map and flow diagram for each UI module
- - include type list and event list
-- implementation mode:
- - implement code changes matching the standard
- - update tests if `UseCase` behavior changes
-- review mode:
- - report findings first, ordered by severity
- - include concrete file and line references
-
-## Architecture Checklist
-
-Use this list before closing any task:
-
-1. Classify each UI module correctly: `standard-five-layer` or `lightweight`.
-2. Ensure `UseCase` does not construct `Context` or touch view concerns.
-3. Ensure `RawData` does not include `*Context` or presentation types.
-4. Ensure `Controller` owns all `RawData/Result -> Context` transformation.
-5. Ensure `View` only consumes `Context` and emits UI-local events.
-6. Ensure external open/close/update operations enter through `Controller`.
-7. Ensure event ownership and sender filtering are explicit.
-8. Ensure test approach matches policy in the reference file.
-
-## References
-
-Read `./references/ui-five-layer-standard.md` for the full specification.
diff --git a/skills/ui-five-layer-architecture/agents/openai.yaml b/skills/ui-five-layer-architecture/agents/openai.yaml
deleted file mode 100644
index d92a807..0000000
--- a/skills/ui-five-layer-architecture/agents/openai.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-interface:
- display_name: "UI Five-Layer Architecture"
- short_description: "Cross-project UI five-layer architecture standards"
- default_prompt: "Use $ui-five-layer-architecture to define, review, or refactor a UI module with clear five-layer boundaries."
diff --git a/skills/ui-five-layer-architecture/references/ui-five-layer-standard.md b/skills/ui-five-layer-architecture/references/ui-five-layer-standard.md
deleted file mode 100644
index 6a60f41..0000000
--- a/skills/ui-five-layer-architecture/references/ui-five-layer-standard.md
+++ /dev/null
@@ -1,274 +0,0 @@
-# UI Five-Layer Architecture Standard
-
-## Table of Contents
-
-1. [Scope and Intent](#scope-and-intent)
-2. [Core Model](#core-model)
-3. [Layer Definitions](#layer-definitions)
-4. [UI Module Levels](#ui-module-levels)
-5. [Dependency Rules](#dependency-rules)
-6. [Event Communication Rules](#event-communication-rules)
-7. [Interaction Flow](#interaction-flow)
-8. [Naming and Folder Conventions](#naming-and-folder-conventions)
-9. [Testing Policy](#testing-policy)
-10. [Anti-Patterns](#anti-patterns)
-11. [Delivery Checklist](#delivery-checklist)
-
-## Scope and Intent
-
-Use this standard to define and enforce a stable UI architecture that can be reused across projects.
-
-Primary goals:
-
-- keep business logic independent from UI rendering
-- keep UI rendering deterministic and testable
-- make reviews and refactors consistent
-- reduce coupling and regression risk
-
-## Core Model
-
-Base chain:
-
-```text
-External Flow
- -> Controller
- -> UseCase
- -> RawData / Result
- -> BuildContext
- -> View
-
-View
- --(UI-local event)--> Controller
-```
-
-Rules:
-
-- `UseCase` produces business outputs only.
-- `Controller` is the only layer that creates `Context`.
-- `View` only renders and emits interaction events.
-
-## Layer Definitions
-
-### UseCase
-
-Responsibilities:
-
-- own business rules and state transitions
-- validate business actions
-- return `RawData` or result objects
-
-Constraints:
-
-- do not depend on `Context`, `View`, or rendering types
-- do not format display strings or map visual assets
-- do not publish UI-local events
-
-### RawData
-
-Responsibilities:
-
-- carry business data from `UseCase` to `Controller`
-
-Constraints:
-
-- keep data business-oriented
-- do not reference any `*Context` type
-- do not contain rendering objects (for example UI components)
-
-### Controller
-
-Responsibilities:
-
-- be the external entry point for open/close/refresh
-- bind and call `UseCase`
-- transform `RawData/Result` into `Context`
-- subscribe/unsubscribe UI-local events
-- coordinate full or partial refresh
-
-Constraints:
-
-- do not let `View` bypass controller orchestration
-- do not hide heavy business logic that belongs in `UseCase`
-
-### Context
-
-Responsibilities:
-
-- carry display-ready data for rendering
-
-Constraints:
-
-- construct/update only in `Controller`
-- do not enter `UseCase`
-- allow composition (`FormContext`, `ItemContext`, `AreaContext`)
-
-### View
-
-Responsibilities:
-
-- bind controls and render `Context`
-- emit UI-local interaction events
-
-Constraints:
-
-- do not call `UseCase`
-- do not mutate domain state
-- do not subscribe to global business events
-- do not become external entry points
-
-## UI Module Levels
-
-### Standard Five-Layer Module
-
-Structure:
-
-- `UseCase + RawData + Controller + Context + View`
-
-Use when:
-
-- module owns business rules, validations, or branching state transitions
-- user actions mutate domain state
-- behavior requires automated verification
-
-### Lightweight Module
-
-Structure:
-
-- `Controller + Context + View`
-
-Use when:
-
-- module is display/navigation/confirmation only
-- no independent business rules are present
-
-Rule:
-
-- upgrade to standard five-layer as soon as business rules appear
-
-## Dependency Rules
-
-Allowed:
-
-- `UseCase -> domain/services/RawData/Result`
-- `Controller -> UseCase/RawData/Result/Context/View/UI-local events`
-- `Context -> child context/value objects`
-- `View -> Context/UI-local events`
-
-Forbidden:
-
-- `UseCase -> Context/View/rendering types`
-- `RawData/Result -> Context/View`
-- `Context -> UseCase/View`
-- `View -> UseCase`
-- `View -> global business events`
-- `View -> domain state mutation`
-
-## Event Communication Rules
-
-### Event Ownership
-
-- `View -> Controller` uses UI-local events only
-- UI-local events are not global business contracts
-- business/domain modules must not consume UI-local event semantics
-
-### Safety Requirements
-
-- validate sender ownership in `Controller`
-- scope handling to the active UI instance
-- keep subscribe/unsubscribe symmetric
-
-## Interaction Flow
-
-### Standard Module
-
-```text
-External Flow
- -> create/bind UseCase
- -> open UI via Controller
-
-Controller
- -> UseCase action
- -> RawData/Result
- -> BuildContext
- -> View refresh
-
-View
- --(UI-local event)--> Controller
-```
-
-### Lightweight Module
-
-```text
-External Flow
- -> open UI via Controller(userData)
-
-Controller
- -> BuildContext(userData)
- -> View refresh
-
-View
- --(UI-local event)--> Controller
-```
-
-## Naming and Folder Conventions
-
-Recommended folders:
-
-- `UI//UseCase`
-- `UI//RawData`
-- `UI//Controller`
-- `UI//Context`
-- `UI//View`
-
-Recommended naming:
-
-- `XXXFormUseCase`
-- `XXXFormRawData`
-- `XXXFormController`
-- `XXXFormContext`, `XXXItemContext`, `XXXAreaContext`
-- `XXXResult`, `XXXActionResult`
-
-## Testing Policy
-
-Policy:
-
-- if a UI has a `UseCase` and automated tests are added, use EditMode tests for the `UseCase`
-
-Priority coverage:
-
-- initial model generation
-- business branch and validation behavior
-- action result correctness
-- boundary and invalid input handling
-
-Manual verification focus:
-
-- first open
-- interaction refresh
-- partial refresh
-- close and reopen
-- null/invalid userData behavior
-
-## Anti-Patterns
-
-Do not allow:
-
-- `UseCase` returning `Context`
-- `RawData` carrying `*Context`
-- `View` subscribing global business events
-- direct domain mutation inside `View`
-- skipping `Controller` as module entry
-- module marked lightweight while carrying business state transitions
-
-## Delivery Checklist
-
-Use this checklist before marking work complete:
-
-1. classify each module as standard or lightweight
-2. verify business rules sit in `UseCase` only
-3. verify `Context` is built only in `Controller`
-4. verify `RawData` has no presentation model leakage
-5. verify `View` is render-and-emit only
-6. verify UI-local events are scoped and sender-checked
-7. verify dependency direction constraints pass
-8. verify tests/manual checks match the testing policy
diff --git a/skills/weapon-development/SKILL.md b/skills/weapon-development/SKILL.md
deleted file mode 100644
index d0bdc7b..0000000
--- a/skills/weapon-development/SKILL.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-name: weapon-development
-description: Develop and extend the VampireLike weapon system. Use when creating new weapons, updating weapon state machines, changing target selection/effects/data parsing, or integrating weapon behavior with shop, inventory, and entity flow.
----
-
-# Weapon Development
-
-## Quick Start
-
-1. Read full baseline spec: `./references/WeaponDevelopmentSkill.md`.
-2. Confirm change scope:
- - weapon runtime (`WeaponBase`, concrete weapons)
- - state flow (`Idle`, `Check_OutRange`, `Check_InRange`, `Attack`)
- - target selector (`ITargetSelector`, `TargetSelectorType`)
- - effect layer (`IWeaponAttackEffect`)
- - data contract (`DRWeapon`, `WeaponData`, `ParamsData`)
-3. Keep behavior compatibility with current gameplay loop, shop flow, inventory flow, and UI/event chain.
-
-## Source Map
-
-- Weapon base:
- - `../../Assets/GameMain/Scripts/Entity/EntityLogic/Weapon/WeaponBase.cs`
-- Existing weapons:
- - `../../Assets/GameMain/Scripts/Entity/EntityLogic/Weapon/WeaponKnife/`
- - `../../Assets/GameMain/Scripts/Entity/EntityLogic/Weapon/WeaponHandgun/`
- - `../../Assets/GameMain/Scripts/Entity/EntityLogic/Weapon/WeaponSlash/`
- - `../../Assets/GameMain/Scripts/Entity/EntityLogic/Weapon/WeaponLightning/`
-- Selectors:
- - `../../Assets/GameMain/Scripts/Entity/EntityLogic/Weapon/TargetSelector/`
-- Attack effects:
- - `../../Assets/GameMain/Scripts/Entity/EntityLogic/Weapon/AttackEffects/`
-- Weapon data:
- - `../../Assets/GameMain/Scripts/Entity/EntityData/Weapon/`
-- Weapon table:
- - `../../Assets/GameMain/DataTables/Weapon.txt`
-- Data row:
- - `../../Assets/GameMain/Scripts/DataTable/DRWeapon.cs`
-- Shop integration:
- - `../../Assets/GameMain/Scripts/UI/GameScene/UseCase/ShopFormUseCase.cs`
-- Entity show flow:
- - `../../Assets/GameMain/Scripts/Entity/EntityExtension.cs`
-
-## Non-Negotiable Invariants
-
-- Do not duplicate logic already owned by `WeaponBase`.
-- Keep state transitions explicit and non-blocking.
-- Keep cooldown accumulation valid even when no target is found.
-- Keep attack logic and visual effect logic decoupled.
-- Parse weapon-specific parameters into strong-typed `ParamsData` at data initialization time.
-- Treat `Weapon.txt` `Params` as a JSON object column; empty params must use `{}`.
-- Preserve compatibility with shop/inventory/UI refresh flow.
-
-## Change Recipes
-
-### Add a New Weapon
-
-1. Extend `WeaponType` without reordering existing enum values.
-2. Add `WeaponXxxData : WeaponData` and `WeaponXxxParamsData` for weapon-specific parameters.
-3. Parse `ParamsJson` through `ParseParams()` inside the weapon data constructor.
-4. Add `WeaponXxx : WeaponBase` and implement only weapon-specific behavior.
-5. Build state files under `Weapon/WeaponXxx/` with partial class layout.
-6. Register display/data mapping path so `ShowWeapon` and shop purchase can instantiate correctly.
-
-### Add or Update a Target Selector
-
-1. Implement `ITargetSelector`.
-2. Update `TargetSelectorType`.
-3. Register creation in `WeaponBase.CreateSelector`.
-4. Validate target semantics with current-health/runtime-health rules where applicable.
-
-### Add or Update Attack Effect
-
-1. Implement `IWeaponAttackEffect`.
-2. Trigger effect from weapon attack state only.
-3. Keep damage resolution outside effect code.
-
-### Add or Update Weapon Parameters
-
-1. Update `Weapon.txt` `Params` JSON object.
-2. Add or update the corresponding `WeaponXxxParamsData` fields.
-3. Keep key names aligned with `ParamsData` property names.
-4. Read values from `ParamsData` in weapon initialization, not by manual string parsing in runtime logic.
-
-## Validation Checklist
-
-- Weapon can be shown, attached, and updated without exceptions.
-- State machine does not stall across target loss/reacquire.
-- Cooldown and range checks match design expectation.
-- Damage path and effect path remain decoupled.
-- `ParamsData` matches table content and default fallback behavior.
-- UI/shop/inventory interactions stay stable after the change.
-- Update `./references/WeaponDevelopmentSkill.md` if contracts or recommended patterns changed.
diff --git a/skills/weapon-development/agents/openai.yaml b/skills/weapon-development/agents/openai.yaml
deleted file mode 100644
index d8a820e..0000000
--- a/skills/weapon-development/agents/openai.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-interface:
- display_name: "Weapon Development"
- short_description: "Build and extend VampireLike weapon architecture"
- default_prompt: "Use $weapon-development to implement a weapon system change with stable state flow and data contracts."
diff --git a/skills/weapon-development/references/WeaponDevelopmentSkill.md b/skills/weapon-development/references/WeaponDevelopmentSkill.md
deleted file mode 100644
index b8f75c1..0000000
--- a/skills/weapon-development/references/WeaponDevelopmentSkill.md
+++ /dev/null
@@ -1,262 +0,0 @@
-# Weapon Development Skill(VampireLike)
-
-## 目标
-本文件是 `Entity.Weapon` 体系的开发规范与速查手册。
-后续新增武器、扩展参数、调整状态机或联动商店/背包时,优先按本文档执行,避免重复通读历史上下文。
-
-## 当前架构总览
-- 武器运行时入口:`WeaponBase`(`Assets/GameMain/Scripts/Entity/EntityLogic/Weapon/WeaponBase.cs`)
-- 武器具体实现:`WeaponKnife`、`WeaponHandgun`、`WeaponSlash`、`WeaponLightning`
-- 目标选择策略:`ITargetSelector` + `TargetSelectorType`
-- 攻击可视化:`IWeaponAttackEffect`
-- 数据入口:`DRWeapon` -> `WeaponData`(及其子类)
-- 实体生成:`EntityExtension.ShowWeapon`
-- 商店接入:`ShopFormUseCase.CreateWeaponData`
-
-## WeaponBase 统一职责(已上收)
-`WeaponBase` 负责以下通用逻辑,子类不要重复实现:
-- 生命周期模板:`OnShow/OnHide/OnAttachTo/OnDetachFrom`
-- 状态机管理:`RegisterState`、`EnsureStatesBuilt`、`TransitionTo`
-- 通用运行字段:`_target`、`_currAttackTimer`、`_sqrRange`
-- 启用门控:`OnUpdate` 中统一 `if (!_isEnabled) return`
-- 目标选择入口:`SelectTarget`、`SetTargetSelector`、`CreateSelector`
-- 距离判定:`IsInRange`(基于 XZ 平面距离)
-- Simulation 命中请求:`TryQueueAreaCollisionQuery`、`TryQueueSectorCollisionQuery`
-- 玩家攻击属性订阅:`BindAttackStatFromOwner` / `ReleaseAttackStatSubscription`
-
-约束:
-- 不要在子类里重复实现 `WeaponBase` 已有能力。
-- 行为差异优先收敛在:`BuildStates`、`Check`、`Attack`、少量专属辅助方法。
-
-## 当前武器模板分类
-### 1. `WeaponKnife`
-- 模式:近身前刺 + 圆形范围命中
-- 典型参数:`HitRadius`
-- 适合派生:长枪、刺剑、短矛、震地锤近身版
-
-### 2. `WeaponHandgun`
-- 模式:单次 `Raycast` 瞬发命中
-- 当前参数化程度较低,仍适合作为远程枪械母版继续扩展
-- 适合派生:手枪、霰弹枪、狙击枪、三连发枪
-
-### 3. `WeaponSlash`
-- 模式:扇形范围命中
-- 典型参数:`SectorAngle`
-- 适合派生:大剑、斧头、半月斩、横扫类武器
-
-### 4. `WeaponLightning`
-- 模式:锁定目标点 + 落点范围打击
-- 典型参数:`HitRadius`、`HoverHeight`
-- 适合派生:闪电、陨石杖、圣光柱、空袭类武器
-
-## 状态机约定
-统一状态枚举:
-- `Idle`
-- `Check_OutRange`
-- `Check_InRange`
-- `Attack`
-- `Disabled`(可选)
-
-推荐流程:
-1. `Idle`:查找目标,计时器持续累积。
-2. `Check_OutRange`:有目标但不在攻击范围,继续转向并累积计时。
-3. `Check_InRange`:在攻击范围内,若 `currAttackTimer >= Cooldown` 切 `Attack`。
-4. `Attack`:执行攻击,重置计时器,结束后回 `Check_InRange`。
-
-关键规则:
-- 即使没有目标,也允许蓄力(计时器持续走)。
-- 一旦进入 `Check_InRange` 且冷却已满,应立即触发攻击。
-- 攻击过程中若需要多帧动画,使用 `_isAttacking` 控制状态退出时机。
-
-## 3D 场景下的距离/朝向原则
-- 射程与目标筛选:优先使用 XZ 平面距离(忽略 Y),调用 `AIUtility.GetSqrMagnitudeXZ`。
-- 视觉朝向与弹道:可按武器设计决定是否使用完整 3D 向量。
- - `WeaponHandgun`:允许俯仰瞄准,逻辑上用射线命中对象判定伤害。
- - 近战地面范围类(Knife/Slash):伤害检测建议投影到地面(XZ)再判定。
- - 落点类(Lightning):锁点可取目标当前位置,但范围判定仍建议按地面距离收口。
-
-## 目标选择策略规范
-接口:`ITargetSelector.SelectTarget(WeaponBase weapon, IEnumerable candidates, float maxSqrRange)`
-
-现有策略:
-- `NearestTargetSelector`
-- `HighestHealthTargetSelector`
-- `LowestHealthTargetSelector`
-
-语义约定:
-- `NearestTargetSelector` 在 Simulation 启用时优先走空间索引。
-- `HighestHealth` / `LowestHealth` 当前基于运行时生命值选择目标。
-- 若新增新策略,必须明确“按当前值”还是“按最大值”筛选,避免语义漂移。
-
-扩展策略步骤:
-1. 新建 selector 类并实现 `ITargetSelector`。
-2. 更新 `TargetSelectorType` 枚举。
-3. 在 `WeaponBase.CreateSelector` 中注册。
-4. 武器在 `OnWeaponShow` 或初始化阶段选择策略。
-
-## 攻击可视化效果规范
-接口:`IWeaponAttackEffect.Play(WeaponBase weapon, Vector3 position, EntityBase target, float radius)`
-
-约定:
-- 可视化逻辑与伤害逻辑解耦。
-- 武器类只负责触发 `Play`,不把可视化细节塞回武器核心逻辑。
-- 当前阶段允许临时对象创建;后续若有性能压力再统一对象池化。
-- 命中特效、范围预警、扇形描边都属于 effect 层,不属于伤害层。
-
-## 数据层规范(DRWeapon / WeaponData)
-### `DRWeapon`
-提供通用字段:
-- `Attack`
-- `Cooldown`
-- `AttackRange`
-- `AttackSoundId`
-- `ParamsJson`
-- `Pramas`
-- `Modifiers`
-
-约定:
-- `Params` 列现在使用标准 JSON 对象。
-- 空参数统一写 `{}`。
-- 不再兼容 `[]`。
-- `Pramas` 保留为描述/UI 的兼容字典视图,不再作为武器逻辑主读取入口。
-
-### `WeaponData`
-提供公共武器字段与通用解析入口:
-- 公共战斗字段:`Attack`、`Cooldown`、`AttackRange`
-- 公共展示字段:`Title`、`IconAssetName`、`Rarity`、`Price`
-- 参数入口:`ParamsJson`、`Params`
-- 通用强类型解析:`ParseParams()`
-
-约定:
-- 参数解析优先在数据层完成。
-- 武器逻辑层读取强类型 `ParamsData`,不要散落字符串 `Parse`。
-- 只有描述/UI 等弱类型场景才继续读取 `Params` 字典。
-
-### 具体武器数据子类
-每种武器数据子类都应持有自己的 `ParamsData`:
-- `WeaponKnifeData -> WeaponKnifeParamsData`
-- `WeaponHandgunData -> WeaponHandgunParamsData`
-- `WeaponSlashData -> WeaponSlashParamsData`
-- `WeaponLightningData -> WeaponLightningParamsData`
-
-当前已接通字段:
-- `WeaponKnifeParamsData`
- - `HitRadius`
-- `WeaponHandgunParamsData`
- - 暂无字段
-- `WeaponSlashParamsData`
- - `SectorAngle`
-- `WeaponLightningParamsData`
- - `HitRadius`
- - `HoverHeight`
-
-JSON 约束:
-- key 名应与 `ParamsData` 属性名一致。
-- 统一使用 JSON 对象,不要再使用自定义 KV 串。
-- 不建议在 `ParamsJson` 中使用制表符和跨行内容,避免 txt 表分列出错。
-
-## 新增武器标准流程
-1. 定义枚举
- - 更新 `WeaponType`,保持递增值,避免重排已有值。
-
-2. 建立数据类
- - 新建 `WeaponXxxData : WeaponData`。
- - 新建 `WeaponXxxParamsData`。
- - 在构造阶段调用 `ParseParams()`,把参数初始化为强类型字段。
-
-3. 建立行为类
- - 新建 `WeaponXxx : WeaponBase`。
- - 只实现差异化逻辑:`BuildStates`、`Check`、`Attack`、特有检测/动画。
-
-4. 建立状态类
- - 推荐放在 `Weapon/WeaponXxx/` 目录,采用 partial 组织:
- - `WeaponXxx.cs`
- - `WeaponXxx.IdleState.cs`
- - `WeaponXxx.CheckOutRangeState.cs`
- - `WeaponXxx.CheckInRangeState.cs`
- - `WeaponXxx.AttackState.cs`
-
-5. 建立可视化(可选)
- - 新建 `WeaponXxxAttackEffect : IWeaponAttackEffect`,在武器中组合调用。
-
-6. 接入实体展示与数据表
- - 确保 `DRWeapon` / `DREntity` 配置齐全。
- - `EntityExtension.ShowWeapon` 可正确映射到 `Entity.Weapon.WeaponXxx`。
- - 商店/背包创建入口能正确构造 `WeaponXxxData`。
-
-7. 联动系统
- - 背包、商店购买/出售、UI 展示、事件流刷新。
-
-8. 验证点
- - 武器能正确生成、附着、更新。
- - `ParamsData` 与数据表一致。
- - 描述文本仍正确展示。
- - Simulation 模式和非 Simulation 模式都能命中。
-
-## 扩展优先级建议
-### 第一批:低成本高收益
-- 长枪 / 刺剑
- - 基于 `WeaponKnife`
-- 大剑 / 半月斩
- - 基于 `WeaponSlash`
-- 战锤 / 震地锤
- - 基于 `WeaponLightning` 或 `WeaponKnife`
-- 霰弹枪
- - 基于参数化后的 `WeaponHandgun`
-- 狙击枪
- - 基于参数化后的 `WeaponHandgun`
-- 陨石杖 / 圣光柱
- - 基于 `WeaponLightning`
-
-### 第二批:中成本扩展
-- 链式闪电
-- 穿透弹 / 火球
-- 地雷 / 陷阱
-- 回旋镖
-
-### 暂缓项
-- 持续激光
-- 喷火器
-- 环绕飞剑
-- 常驻法球
-- 状态异常驱动的复杂武器流派
-
-原因:
-- 当前武器主流程仍是单次攻击结算。
-- 持续伤害、异常状态和常驻 orbit 行为尚未形成统一挂点。
-
-## `WeaponHandgun` 后续建议
-当前 `WeaponHandgun` 参数化仍偏弱,建议作为下一阶段母版优先扩展。
-
-建议新增字段:
-- `PelletCount`
-- `SpreadAngle`
-- `PenetrationCount`
-- `FireOriginOffsetX`
-- `FireOriginOffsetY`
-- `FireOriginOffsetZ`
-- `HitMarkerSize`
-- `HitMarkerYOffset`
-- `HitMarkerDuration`
-
-完成后可快速派生:
-- 手枪
-- 霰弹枪
-- 狙击枪
-- 三连发枪
-
-## 代码检查清单(提交前)
-- 是否重复实现了 `WeaponBase` 已有通用逻辑。
-- 状态流转是否会卡死或漏转场。
-- 冷却计时是否在无目标时仍正常累积。
-- 目标失效(null/Unavailable/死亡)是否安全处理。
-- 命中检测是否符合武器设计(地面范围/射线/扇形/落点)。
-- 数据参数是否全部收敛到 `ParamsData`。
-- 可视化是否与伤害逻辑解耦。
-- 是否正确订阅/解绑攻击属性(或复用基类方法)。
-- 商店、背包、武器描述是否仍保持兼容。
-
-## 已知注意点
-- 目录中存在 `Pramas` 命名拼写历史包袱,当前保持兼容即可。
-- 文档中的“规范”优先级高于历史实现;历史实现若偏离,按本规范逐步收敛。
-- 当前更推荐“公共 `WeaponData` + 专属 `ParamsData`”结构,不建议把每种武器做成一套完全独立的数据总线。