Commit Graph
281 Commits
Author SHA1 Message Date
joywayer 4455062ee9 refactor(editor): 脚手架改用 GroundNavigator,移除寻路库引用与导航面放置工具 2026-07-28 11:45:24 +08:00
joywayer 219fe46719 fix(enemy): GroundNavigator 停止改为直写移动输入,消除与 EnemyBase.StopMovement 的无限递归(栈溢出) 2026-07-28 11:39:25 +08:00
joywayer de3c9deff4 refactor(enemy): 消费者切换到 IEnemyNavigator(Wander/Waypoints 去导航图化,调试面板简化) 2026-07-28 11:25:21 +08:00
joywayer 49627d357d refactor(enemy): FlyingDirectNavigator 改名 FlyingNavigator 并切换到 IEnemyNavigator 2026-07-28 11:17:34 +08:00
joywayer 668bc3500e feat(enemy): 新增 GroundNavigator 地面直接移动导航(+7 纯函数单测)
补充 EditMode 测试程序集对 BaseGames.Enemies.Navigation 的引用(此前缺失,新测试无法编译)
2026-07-28 11:12:11 +08:00
joywayer 2174e42ce0 feat(enemy): 新增 IEnemyNavigator 瘦身导航接口(7 成员)与 NullEnemyNavigator 2026-07-28 11:07:53 +08:00
joywayer 8ea919a7f1 chore(enemy): 补交 StallDetector 与其测试的 .meta 2026-07-28 11:07:06 +08:00
joywayer c929b5efb7 refactor(enemy): 三处卡死检测收敛为 StallDetector;修复 Pace 持续受阻时无法掉头的死锁 2026-07-28 11:04:18 +08:00
joywayer 5cfacf199a feat(enemy): 新增 StallDetector 推进停滞检测(+8 单测),为收敛三处重复实现做准备 2026-07-28 11:01:01 +08:00
joywayer 28cd335f40 chore(enemy): [临时调试] E001 出生即巡逻,用于真机验证中心悬空导致导航失效的问题
代码处已留 [临时调试] 标记,验证结束后改回 Entry=Idle_Disguise。
2026-07-27 16:01:03 +08:00
joywayer 47c2ce7e99 fix(enemy): 冲锋禁止以中心悬空姿态收尾(会导致导航映射失败/巡逻失效)
新增 EnemyMovement.IsCenterOverGround() 与 RushAbility.SettleRoutine:
冲锋结束时若着地却中心悬在崖外,继续朝原方向推进直到离地(自由落体)或中心重回地面上方;
有时限,超时仍未脱离则告警暴露地形问题(崖沿有墙),不静默留下坏站位。
2026-07-27 15:50:01 +08:00
joywayer 80c0e5c277 revert(enemy): E001 初始态改回 Idle_Disguise(伪装静止),移除临时调试改动 2026-07-27 15:27:15 +08:00
joywayer e2645b6212 fix(editor): 脚手架提示改为 BrainGraph 指引,清除已废弃的 BehaviorTree/BossSkillSequencer 说法 2026-07-27 15:09:47 +08:00
joywayer 4808077fc6 feat(enemy): ContactChaseAbility 改造为 RushAbility(冲锋)
- 起手前锁定玩家 X 与方向(committed),终点改为身体整体越过锁定点(Body.HasPassed)
- 终止条件:越过锁定点/撞墙(只判墙)/最大冲刺时长(SO 新增 maxDashDuration)/净位移卡死
- 冲锋期间经 EnemyMoveInput.AllowLedgeCross 放开悬崖夹紧,可冲下崖不悬停边缘
- 类与文件重命名(GUID 保留),脚手架与向导同步更新
2026-07-27 13:38:05 +08:00
joywayer 7cba58919f feat(editor): 敌人/Boss 放置脚手架绑定 EnemyBase._bodyCollider(身体几何唯一权威) 2026-07-27 13:17:38 +08:00
joywayer 9f8d4f21ca fix(enemy): EnemyMovement 加 RequireComponent(EnemyBase),固化身体权威同物体不变量 2026-07-27 12:13:10 +08:00
joywayer b1d3c169ec chore(enemy): 补交 EnemyBody 与其测试的 .meta 2026-07-27 12:07:46 +08:00
joywayer 9a61d3e256 refactor(enemy): 移动层探测与 EdgeSafeMargin 改走 Body 权威,删除重复的碰撞体解析 2026-07-27 11:55:55 +08:00
joywayer 6026911532 feat(enemy): EnemyBase 持有身体几何权威(_bodyCollider + Body),Awake/OnValidate 双重校验 2026-07-27 11:51:45 +08:00
joywayer b0e1ebfecc feat(enemy): 新增 IEnemyBody 身体几何权威接口与 EnemyBody 实现(+14 纯函数单测) 2026-07-27 11:48:26 +08:00
joywayer 86e3637d8e chore(core): 补交 WeightedPick 与其测试的 .meta 2026-07-27 10:00:59 +08:00
joywayer 1d5214beea refactor(enemy): Boss 选招与战利品掉落改用 WeightedPick;删除零调用的 SelectWeightedSkill 死代码 2026-07-27 09:58:40 +08:00
joywayer 67220b4bbd refactor(enemy): 小怪选招改用 WeightedPick 共享原语(权重缓冲复用,零 GC) 2026-07-27 09:55:59 +08:00
joywayer 3d85f65965 feat(core): 新增 WeightedPick 加权随机共享原语(+10 单测),为消除四处平行实现做准备 2026-07-27 09:54:34 +08:00
joywayer 23de5adf75 fix(enemy): MeleeAttackAbility 空 clip 走 fallbackDuration(判 clip.Clip 而非 clip),兑现 EnemyAttackSO 契约 2026-07-24 15:12:41 +08:00
joywayer 568b6e46c0 chore(enemy): 补交新脚本的 .meta(AbilityCategory/AttackSelectionMode/IAttackCandidate/EnemyAttackSelector+测试) 2026-07-24 14:55:17 +08:00
joywayer 022e4f18d2 fix(enemy): Approach 逼近改用 aggro/视野双刷新的 LastKnown(修 aggro 先命中扑向错误点)+补 Attack 退出测试 2026-07-24 12:47:48 +08:00
joywayer f77ab71555 feat(enemy): 攻击能力射程 Gizmo(选中可见)+ category==Attack 的 rangeRadius 自检 2026-07-24 12:33:16 +08:00
joywayer 980fe35ae4 docs(enemy): PerceptionStateMachine 类注释补充 ApproachAttack 交战风格 2026-07-24 12:31:31 +08:00
joywayer 6cdd4ef513 feat(enemy): PerceptionStateMachine 增加 ApproachAttack 风格(寻路逼近↔选招攻击)+测试 2026-07-24 12:27:59 +08:00
joywayer 297f9d2968 feat(enemy): IEnemyLocomotion 增加 Pursue 寻路逼近原语(RunSpeed) 2026-07-24 12:23:43 +08:00
joywayer 6fd80cfec9 fix(enemy): BuildAttackSelector 表达式上下文全限定 AbilityCategory(消歧义于 Abilities 属性) 2026-07-24 12:22:35 +08:00
joywayer 702df35efd feat(enemy): ICombatant 增加 HasEligibleAttack/UseBestAttack + EnemyBase 构建选择器 2026-07-24 12:20:54 +08:00
joywayer 04a267b69f feat(enemy): EnemyAttackSelector 选招器(射程+冷却+LOS+着地过滤,两模式选招)+单测 2026-07-24 12:15:41 +08:00
joywayer 2cf0d6b1a9 feat(enemy): EnemyAbilityBase 实现 IAttackCandidate 契约(自管圆形射程) 2026-07-24 11:58:22 +08:00
joywayer 25fae97065 feat(enemy): 攻击选招元数据(category/weight/圆形射程)与选招模式入 SO 2026-07-24 11:56:07 +08:00
joywayer 4a80a11ab5 fix(enemy): 改道到最近可达点时同步防抖记账,避免下次 RequestMoveTo 被误吞 2026-07-23 17:22:11 +08:00
joywayer 8e71b1a922 feat(enemy): Waypoints 受阻/到达即结算推进,删除对不可达点的无限重发 2026-07-23 17:09:06 +08:00
joywayer 49b7adbdae feat(enemy): IPathAgent 增加 LastMoveObstructed/TryGetClosestReachable 契约 2026-07-23 17:07:31 +08:00
joywayer 72ed14428c feat(enemy): FlyingDirectNavigator 实现受阻/最近可达点成员(飞行单位恒 false) 2026-07-23 17:06:21 +08:00
joywayer 675e1950af feat(enemy): EnemyNavAgent 卡死检测+统一受阻处理+best-effort 改道到最近可达点 2026-07-23 16:56:56 +08:00
joywayer 02150836b0 场景修改和editor优化 2026-07-23 15:54:38 +08:00
joywayerandClaude Opus 4.8 859d4e9bd6 feat(enemy): 感知系统新增 BoxLOS 槽位(横向矩形视野+遮挡)
BoxCast 是纯几何矩形无遮挡,BatchLOS/Sight 有遮挡但为圆形。
新增 BoxLOS 槽位:OverlapBox 矩形区域 + 从感知原点多点 LOS 遮挡校验,
用于走廊/平台等横向矩形视野带遮挡的场景。

- enum 末尾追加 BoxLOS(避免打乱既有序列化索引)
- 复用 boxSize/boxOffset 定义矩形、losBlockMask/losRayCount/losMinVisibility 定义遮挡
- 方向由 boxOffset.x 控制:0=前后双向对称,boxSize.x*0.5=仅前向
- Editor 补 Gizmo(矩形+眼点+实时检测连线)与条件字段

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 15:54:17 +08:00
joywayerandClaude Opus 4.8 fccd87df6b fix(enemy): 修复退出 Play 时巡逻调试 Inspector 的 NRE 与 IMGUI 报错
退出 Play 有一个窗口:Application.isPlaying 仍为 true 但 PBWorld 已销毁,此时 Inspector
调 nav.CanReach → PBWorld.PathTo(instance=null) 抛 NRE;该异常在 IMGUI 布局组中途中断,
使 BeginHorizontal 组失衡 → 级联 ArgumentException("control N in a group with only N controls")。

修:
- 订阅 playModeStateChanged,ExitingPlayMode 置 _exitingPlay,CanReach 调用点加
  !_exitingPlay && isPlaying 守卫,退出期不再查询已销毁的 PBWorld。
- 运行时区块的绘制判定只在 Layout 事件锁定、Repaint 复用,避免 isPlaying 在两趟 GUI
  间翻转导致控件数不一致。

实测:选中敌人连续两次进/退 Play,Console 无 NRE/ArgumentException。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 15:33:41 +08:00
joywayerandClaude Opus 4.8 854bcb3d6f perf(enemy): 感知系统 Inspector 限频重绘,修复选中敌人掉帧
PhysicsPerceptionSystemEditor.OnInspectorGUI 尾部每帧 Repaint(),选中敌人时强制整个多组件
Inspector(本编辑器逐槽位 IMGUI + 同物体其它自定义编辑器)以游戏帧率(100+fps)重绘,单帧多耗
~18ms → 帧率从 140 掉到 40。

改为与 EnemyLocomotionEditor 同款:走 EditorApplication.update 定频(~5Hz)请求重绘,与游戏
帧率解耦,移除每帧 Repaint。感知 Gizmo 本就 NonSelected|Selected 都画(在基线内,非选中新增成本)。

实测(平均帧):选中开销从 ~18ms/帧 降到 ~4.3ms/帧(未选中~106fps / 选中~73fps,原为 140→40)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 15:24:22 +08:00
joywayerandClaude Opus 4.8 842a20fbb3 chore(enemy): [临时调试] E001 初始态改为 Move_Patrol,出生即巡逻便于 MCP 调试
仅为调试方便:Entry 从 Idle_Disguise 改为 Move_Patrol,一进场就走 Waypoints。
正式版应改回 Idle_Disguise(伪装静止),代码处已留 [临时调试] 注释标记待回退。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 15:13:30 +08:00
joywayerandClaude Opus 4.8 16edf7cb90 fix(enemy): Waypoint 巡逻寻路失败/丢失时自动重发,修复出生即巡逻卡死
TickPatrol 原来只在"首次或到达路点"时发一次 MoveTo。若这一次 UpdatePath 失败(如敌人
刚出生、当帧尚未映射到 NavGraph),路径永不建立且再不重试 → 永久原地不动(mode=Patrol
但 IsFollowingAPath=False)。旧 Entry=Idle_Disguise 因巡逻只在出生很久后才开始而掩盖了此问题。

新增:有目标但 nav 空闲(!IsMoving)且未到达 → 重发同一目标(只重发不推进索引;RequestMoveTo
自带 0.25s 防抖,寻路跨帧计算期间的重发被吞掉,不会每帧重启寻路)。

Play 实测:出生即在两路点间以 WalkSpeed 正常往返巡逻。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 15:13:19 +08:00
joywayerandClaude Opus 4.8 be7d511e45 feat(enemy): 巡逻调试 Inspector 加"一键打印报告"按钮(供 AI 诊断)
点击将完整状态以纯文本 Debug.Log 到 Console,可直接复制给 AI:AI决策层(EnemyState/
BrainGraph 当前状态名/LocomotionMode)、移动导航(Nav类型/IsMoving/IsOnLink/HasValidPosition/
PB2d Position/EdgeSafeMargin/_maxSnapDistance)、Waypoints(当前索引/吸附目标/CanReach/逐路点
实时吸附检测 raw→snap 及垂直差)、文末一句根因诊断。编辑期打印静态配置,Play 期打印运行时全量。

实测输出直指根因:Brain='Idle_Disguise' → LocomotionMode=Idle → TickPatrol 不执行。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 15:04:53 +08:00
joywayerandClaude Opus 4.8 424d9bbbe0 perf(enemy): 巡逻调试 Inspector 限频,消除每帧阻塞式 CanReach 掉帧
上版 OnInspectorGUI 每帧 Repaint 且每帧调用 NavAgent.CanReach——该 API 会同步阻塞主线程
跑一次完整寻路(其文档自述"not optimal for performance"),选中敌人时每帧一次直接把帧率拖垮。

改为:刷新走 EditorApplication.update 定频(~5Hz)与游戏帧率解耦;CanReach 限频 ~2Hz 并缓存;
_maxSnapDistance 运行期不变只读一次缓存(不再每帧 new SerializedObject)。实测选中敌人 ~53fps 稳定无卡顿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 13:15:53 +08:00
joywayerandClaude Opus 4.8 00ee48f750 feat(enemy): EnemyLocomotion 运行时巡逻调试(Inspector 面板 + Scene Gizmos)
排查"敌人原地不动"用:PlayMode 下自定义 Inspector 实时显示 模式/策略/是否移动/是否在导航图上/
当前路点与吸附目标/到目标距离vs到达半径/目标是否可达,并按优先级给出定位诊断(模式非Patrol|不在
NavGraph|吸附失败|不可达|已寻路未动)。Scene 视图 Gizmos 画出全部路点连线 + 当前吸附目标(绿/红)+到达半径。

EnemyLocomotion 加 #if UNITY_EDITOR 只读调试访问器 + OnDrawGizmosSelected;记录 _wpResolveOk。
Editor 程序集补 BaseGames.AI 引用(PatrolStrategy/LocomotionMode 所在)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 11:57:02 +08:00