Commit Graph
357 Commits
Author SHA1 Message Date
joywayer d84e66fcb9 fix(nav): 发出新寻路请求时作废上一次最近可达点,避免跨目标读到过期数据 2026-07-23 17:05:27 +08:00
joywayer 675e1950af feat(enemy): EnemyNavAgent 卡死检测+统一受阻处理+best-effort 改道到最近可达点 2026-07-23 16:56:56 +08:00
joywayer 4079392a79 feat(nav): NavAgent 暴露寻路失败时的最近可达点 TryGetClosestReachablePosition 2026-07-23 16:52:28 +08:00
joywayerandClaude Opus 4.8 a60073d92c docs(enemy): 敌人寻路受阻处理实现计划(6任务,编译门+Play验证)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 16:44:12 +08:00
joywayerandClaude Opus 4.8 04b294734a docs(enemy): 敌人寻路受阻处理设计(Waypoints+MoveTo,含卡死检测与最近可达点)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 16:37:39 +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
joywayerandClaude Opus 4.8 66d100f353 fix(enemy): 目标点吸附改用固定大搜索距离,与 PB2d 映射任意点机制一致
上版把搜索距离绑到 agent→目标距离(仿 UpdatePath),仍脆弱:吸附距离取决于 agent 离得多远
而非目标离导航段多远——agent 贴在高处路点正下方时距离小、reach 小仍会漏。

查明 PB2d 映射机制(NavGraph.TryMapPointSurface):queryAABB 边长=传入值、可靠搜索半径仅其一半;
PB2d 映射"鼠标点击等任意点"用固定的 closestToSegmentMaxDistance(默认 20,"想多大就多大")。
据此改为:EnemyNavAgent._maxSnapDistance(默认 10m,真实"点离最近段"上限),底层传 2× 补偿 AABB 半宽。
只要目标在 _maxSnapDistance 内一定吸附到最近烘焙段,返回 false 仅表示目标真正脱离导航面。

Play 实测:两路点 + 压力用例(agent 正上方 3m/5m)ResolveStandablePoint 均 ok=True 且映射到地面段。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 10:35:24 +08:00
joywayerandClaude Opus 4.8 4ecf949d83 fix(enemy): 目标点吸附改用距离自适应搜索,修复稍离地路点吸附失败
之前 TryGetStandablePointNear 用固定 2m 搜索半径(实为 ±1m AABB)+ agent 过滤映射,
导致摆放在离地面 >1m 的路点(如 wp y=3.16 而地面段 y=2.00)映射失败、误报"超出搜索半径"。

改为与 PB2d 自身 UpdatePath 映射目标完全一致:搜索距离=agent 到目标距离(+0.1),
用不带 agent 过滤的 TryMapPoint(就近段几何映射,可达性交给 allowCloseEnoughPath 寻路阶段)。
只要图上有段就一定吸附得到最近点。移除 EnemyNavAgent._goalMapSearchRadius 固定半径字段。

Play 实测:两个路点 ResolveStandablePoint 均 ok=True((-20.90,3.16)->(-20.90,2.00)),
CanReach=True,敌人实际走到 x=-20.75(目标 -20.90)后停,无 EnemyLocomotion 报警。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 10:10:35 +08:00
joywayerandClaude Opus 4.8 132cd24908 feat(enemy): 目标点吸附统一处理导航宽度,Waypoint 不再卡崖边
将"角色导航宽度"收口到导航执行层单一入口,意图层(Locomotion/AI)只递原始目标、不再感知身体尺寸:

- NavAgent 新增 TryGetStandablePointNear:把世界点映射到最近可行走段并按 endMargin 内缩两端(与 SetRandomDestinationOnCurrentSegment 同源)
- EnemyNavAgent 新增 ResolveStandablePoint,以 EnemyMovement.EdgeSafeMargin(半宽+落崖余量)为唯一宽度真源;加 _goalMapSearchRadius
- IPathAgent 暴露 ResolveStandablePoint;FlyingDirectNavigator 原样返回(飞行无崖沿约束),NullPathAgent 空实现
- EnemyLocomotion Waypoint 分支改用吸附后的可达点做移动与到达判定,修复路点摆在空中/崖外时永不到达而卡死;吸附失败显式报错暴露误配,不静默兜底

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 15:52:18 +08:00
joywayerandClaude Opus 4.8 7f7d237915 feat(enemy): Wander 到达随机点后可配置停顿时长
到达一个段内随机游走点后原地停顿 [_wanderPauseMin, _wanderPauseMax] 秒再挑下一个点:
- 两个可配置字段(相等=固定时长;都为 0=不停顿立即挑点),每次停顿时长在区间内随机
- 停顿期间切 Idle 步态(否则站着播 Walk=原地踏步),速度归零
- 切换 locomotion 模式时清停顿态,避免残留
实测:移动→到点→停顿(Idle,velX=0)→再出发 循环正常。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 13:45:21 +08:00
joywayerandClaude Opus 4.8 31b77fa473 feat(enemy): Wander 巡逻改为当前段内随机 + 按身体宽度内缩两端
修复地面单位 Wander 巡逻"走一小段就停":
- 随机点从全图(GetRandomPointOnGraph)改为限定在 agent 当前所站的 NavSegment 上,
  不再跨越跳/落/拐角 NavLink,避免路径跨沟被崖边夹停或卡在过不去的 link。
- 段内随机 t 按"身体前缘安全余量(碰撞体半宽 + 悬崖检测前向偏移)"从两端各内缩,
  避免随机点落在角色宽度站不住的崖沿(WouldFallAhead 夹停、IsFollowingAPath 不复位→卡死)。
- NavAgent.SetRandomDestinationOnCurrentSegment(endMargin):段内采样+内缩(段过短退化到中点)
- EnemyMovement.EdgeSafeMargin:身体前缘安全余量
- IPathAgent.WalkToRandomOnSegment():EnemyNavAgent 传入 margin;飞行单位复用局部偏移;Null 返回 false

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 12:45:01 +08:00
joywayerandClaude Opus 4.8 46c9718793 docs: 删除 Behavior Designer 选型评估文档
BD 已被自研 BrainGraph HFSM 替换、不再使用,其选型评估文档一并移除。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 16:40:42 +08:00
joywayerandClaude Opus 4.8 9226eb0330 docs: 删除过时指南 02(敌人搭建) 与 08(BD 行为树编写)
- 02_Enemy_Boss_Setup_Guide:敌人框架仍在改动、预制体延后,指南暂删待功能定稿后重写
- 08_BehaviorTree_Authoring_Guide:Behavior Designer 已被自研 BrainGraph HFSM 替换,BD 不再使用

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 16:39:16 +08:00
joywayerandClaude Opus 4.8 3bca15b69e fix(wizard): 移除 E001 残留的 Alert 能力定义
Alert/警觉张口在 locomotion 重构后已改为纯移动模式(LocomotionMode.Face),
不再是能力(ABL_E001_Alert SO 已删);起手张口并入 ContactChaseAbility 的 Skill_Start。
向导 GetEnemyAbilityDefs 里 E001 仍列 ("Alert","e001_alert") 是残留,
会导致重跑向导时又造一个无用 SO。E001 现只保留 Chase 能力。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 16:35:15 +08:00
joywayerandClaude Opus 4.8 a94348d64c chore(enemy): 移除 E001-E006 小怪预制体(延后至功能定稿再用脚手架产出)
敌人框架改动期间不再维护预制体,待所有敌人功能定稿后用 SceneObjectPlacerTool 统一重建。
ChaoFeng Boss 预制体保留。
- 删除 6 个 ENM_*.prefab 及 .meta
- Enemies.asset(Addressables 组)同步移除条目
- TestRoomA.unity 移除失效敌人实例引用

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 16:31:44 +08:00
joywayerandClaude Opus 4.8 6f519ec9a9 refactor(enemy): 身体接触伤害改为常驻开启并与能力解耦
所有敌人默认常驻身体接触伤害:存活即开、死亡时经 PerformDeath 统一关碰撞体停止。
- ContactChaseAbility/AnimatedCeilingDropAbility 移除对 BodyContactDamage 的开关引用
- BodyContactDamage 语义改为常驻(更新注释)
- 脚手架 SetupHurtAndContactBoxes 去掉 contactEnabled 参数恒为 true,并把
  ContactDamageZone 的 HitBox._targetLayers 限定为 PlayerHurtBox(避免常驻后敌人互相误伤)
- 7 个敌人预制体:E001 启用 BodyContactDamage;E002/E004/E005/ChaoFeng 补齐
  ContactDamageZone(镜像 HurtBox 身体碰撞体);全部 _targetLayers 收敛为 PlayerHurtBox
- 更新 Docs/Guides/02 敌人搭建指南

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 16:18:07 +08:00
joywayerandClaude Opus 4.8 b4379db5de docs(game): 建立游戏设计文档规范并迁移重写 Docs/Game 设计文档
- 新增 Docs/Standards/GameDesignDocSpec.md:目录结构/通用文档头/六类分节/命名编号/交叉引用/禁参考游戏字样
- Docs/Game 按类别重组:总览/主角/敌人(小怪+Boss)/NPC/系统/剧情 + _Templates 模板
- 小怪 E001-E006、嘲风:程序文档+动作需求表合并为单份综合文档
- 其余 7 Boss 迁移设计层内容,程序/动画/数值节标注待补充
- 主角能力设定清除全部外部游戏参考字样并修正 OCR 乱码
- 删除 参考/ 原始文档(已忠实重写,原件保留于 git 历史)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 15:42:33 +08:00
joywayer 94bbf3acf2 chore(data): 7 个 ABL_ 能力资产重型为对应子类 SO 并迁入参数(m_Script+字段) 2026-07-21 12:17:21 +08:00
joywayer 79829cc629 场景改动 2026-07-21 12:05:04 +08:00
joywayer 447575d66e docs(enemy): 更新迁移后能力脚本残留旧字段名注释为 _cfg.* 2026-07-21 11:45:30 +08:00
joywayer 8bd24df11e feat(wizard): 敌人能力 SO 按能力类型创建正确子类(向导批量创建产出子类 SO) 2026-07-21 11:40:44 +08:00
joywayer 6d071e83ae refactor(enemy): Appear/FacePlayer/PlayClip 参数迁入各自子类 SO 2026-07-21 11:35:39 +08:00
joywayer 78c8c6dcd6 refactor(enemy): MeleeVulnerability 参数迁入 MeleeVulnerabilityAbilitySO(子类) 2026-07-21 11:32:20 +08:00
joywayer 34772c3d20 refactor(enemy): AnimatedCeilingDrop 参数迁入 AnimatedCeilingDropAbilitySO(子类) 2026-07-21 11:29:20 +08:00
joywayer 16b0d7b819 refactor(enemy): CeilingHangStrike 参数迁入 CeilingHangStrikeAbilitySO(子类) 2026-07-21 11:26:03 +08:00
joywayer 1e3b01705f refactor(enemy): RepeatSlam 参数迁入 RepeatSlamAbilitySO(子类) 2026-07-21 11:23:11 +08:00
joywayer 6873a2cd8e refactor(enemy): ContactChase 参数迁入 ContactChaseAbilitySO(子类) 2026-07-21 11:19:08 +08:00
joywayer ca36974ec3 feat(enemy): EnemyAbilityBase 加 ResolveConfig<T> 类型化配置解析(不匹配显式报错) + EditMode 测试 2026-07-21 11:14:28 +08:00
joywayer 0ad4acc484 docs(plan): 敌人能力配置迁移到 AbilitySO 子类实现计划 2026-07-21 11:04:36 +08:00
joywayer 68e2cc506d docs(spec): 敌人能力配置迁移到 AbilitySO 子类设计文档 2026-07-21 10:42:25 +08:00
joywayer a7307a5a07 调整文档 2026-07-21 10:22:43 +08:00
joywayer 2d4b3cfd96 feat(wizard): 敌人/Boss 加默认外观 Sprite 字段并透传给脚手架(碰撞体尺寸依据) 2026-07-20 16:42:13 +08:00
joywayer 3af4e4140b refactor(scaffold): ChaoFeng + 通用 Place 统一 Box HurtBox/接触伤害区 + sprite 尺寸 2026-07-20 16:35:25 +08:00
joywayer 4fcbc73d44 refactor(scaffold): E002-E006 统一 Box HurtBox/接触伤害区 + sprite 尺寸(补全缺失的接触伤害区) 2026-07-20 16:24:03 +08:00
joywayer 8efd5e2207 refactor(scaffold): E001 用统一助手建 Box HurtBox/接触伤害区 + sprite 尺寸参数 2026-07-20 16:11:18 +08:00
joywayer 3124b2bba2 feat(scaffold): 新增 SpriteSizeOr / SetupHurtAndContactBoxes 助手(Box 统一 HurtBox/接触伤害区) 2026-07-20 16:01:15 +08:00
joywayer ee0bc6948d @
docs(scaffold): 敌人碰撞体 Sprite 驱动+统一 Box+全员接触伤害区 实施计划

Task1 助手(SpriteSizeOr/SetupHurtAndContactBoxes)/Task2 E001 样板/Task3 E002-E006/
Task4 ChaoFeng+通用/Task5 向导 sprite 字段/Task6 端到端验证。只改脚手架+向导。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
2026-07-20 15:51:35 +08:00
joywayer 82d5212dfd @
docs(scaffold): 敌人碰撞体 Sprite 驱动 + 统一 Box + 全员接触伤害区 设计文档

脚手架生成的敌人(含 Boss):主体/HurtBox/ContactDamageZone 三者统一 BoxCollider2D、
同尺寸、底部对齐 y=0;尺寸由向导默认 Sprite 的包围盒推导(留空回退硬编码);每个
敌人都有 ContactDamageZone。只改脚手架+向导,不动现有 prefab。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
2026-07-20 15:46:52 +08:00
joywayer b8360ec426 @
fix(scaffold): 兜底把 HurtBox/接触伤害节点所有碰撞体设为 trigger

脚手架原本只对自己创建的具体类型(Capsule/Circle)设 isTrigger=true;若碰撞体被
手动换成别的类型(如 BoxCollider2D,默认 isTrigger=false),那条就漏掉——E001 的
HurtBox/ContactDamageZone 被换成 Box 后 isTrigger 掉回 false,导致受击/接触伤害
的 trigger 判定失效。

新增 EnsureCollidersAreTriggers 助手,对节点全部 Collider2D 兜底设 trigger;
PlaceE001 的 HurtBox 与 ContactDamageZone 建好后调用。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
2026-07-20 14:50:00 +08:00
joywayer d7be0cc119 @
feat(ai): 追击冲刺带冷却——CD 期巡逻,冷却结束仍在追逐区则再冲(PatrolBetweenChases)

按需求:冲刺打完 → CD 期切到巡逻(Move_Patrol) → 冷却结束且玩家仍在追逐区 → 再冲刺。

PerceptionStateMachine 加 opt-in 开关 PatrolBetweenChases:
- Chase → Patrol When !IsAbilityRunning(chase):冲刺是 committed 冲锋,感知丢失
  也不中途打断,打完(能力结束)即降巡逻。
- Idle/Patrol/Alert → Chase 加冷却门 CanUseAbility(chase):CD 中不回追击,
  避免"CD 期在追逐区每帧 Chase↔Patrol 来回抖"(用户担心的错切/抖动)。
- 默认关:不影响其他敌人(leftAllZones 旧行为保留)。
E001CaoZhiAi 打开开关。追击能力保持单次冲刺不变,冷却=ABL_E001_Chase.cooldown(1s)。

测试:PerceptionStateMachineTests +5(CD 转换矩阵含"CD 期多帧不抖动"负例),
FakeCombat 加可控 CanUse。全量 75/75 绿。PlayMode 实测循环
Move_Patrol(CD)→Chase(冲)→Move_Patrol,inChase 全程 true 亦不抖,0 报错。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
2026-07-20 13:11:28 +08:00
joywayer 1a15473966 @
fix(enemy): 转身中不再静默丢弃新朝向请求,修"冲刺方向与朝向相反"

UpdateFacing 原 `if (_isTurning) return` 会把转身进行中的新朝向请求静默丢弃。
当敌人在平台边缘触发 Pace 翻转(开始 Flip 转身)同时进入追击时,追击的
FaceDirection(朝玩家)被丢弃,旧的巡逻转身完成后朝向定格在与玩家相反方向
→ 冲刺朝玩家方向移动、脸却朝相反(并连带"冲刺中途转身""提前停"两个衍生现象)。

改为:转身中收到不同方向请求时重定向(停旧转身按新方向重起),同向则忽略。
根因修复,惠及 Pace/追击/FaceTarget 所有调用方。

systematic-debugging 确定性复现证实:修复前 AFTER-TURN dir=+1 facing=-1;
修复后开阔地冲刺全程 dir=1 facing=1、冲满 6 米到真实平台边缘才停。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
2026-07-20 13:03:29 +08:00
joywayer 55b6255ce6 @
test(ai): BrainGraph 全面测试——框架边界 + 全感知矩阵(70 tests 全绿)

保证自研 AI 状态机(BrainGraph)稳定与功能正确性。EditMode AI 测试从 31 增至 70。

新增 AiFrameworkTests(17)——框架健壮性/边界(与 AiRuntimeTests 主干互补):
- 构图校验:Entry 未设/未声明、全局转换目标未声明、GlobalBuilder 顺序错用抛异常
- 转换优先级:同态多条件首声明胜、全局条件转换、全局优先于局部
- 事件 vs 条件:事件优先(Tick 首步)、未匹配信号被消费不阻塞、多信号首个匹配胜
- 时序:条件自转换 no-op、转换当帧跳过 OnTick、Tick 双参传 dt
- trace 环形上限 16、事件推进后清挂起、State 重声明累加转换

重写 PerceptionStateMachineTests(22)——完整感知↔状态矩阵:
- 待机/巡逻/警觉/追击/死亡 全转换 + HasAlert 分支(无警觉态不进警觉)
- 追击优先于警觉;追击永不回警觉、脱离全部感知才降级 R(=Patrol)
- 视野单独/追逐区单独仍维持追击;locomotion 意图(Idle/Patrol/Face)
- 追击触发能力、离开中断能力;死亡为终态不复活

验证:反射调用全部 [Test] 方法(负对照确认能捕获失败),70/70 通过。
去重:Blackboard/局部转换目标校验已由 BlackboardTests/BrainBuilderTests 覆盖,不重复。

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