船只
船只是本作唯一的“可移动基地”:一块由格子拼成的甲板平台,地板决定浮力与重量,锅炉与引擎决定速度,船长决定操控性;玩家船与敌船共用同一套船体物理,敌船另外挂一套战术状态机。
船只(Ship.cs)是玩家与 AI 共用的核心实体。一艘船 = 一个网格化建造平台(甲板)+ 一组船级服务(库存、任务、船员、武器分配等,见 ShipContext.cs)+ 一套移动物理(MovementController.cs + ShipHull.cs)。
- 玩家船:场景
mvp_002.unity中预置,唯一,沉没后在最后停靠的港口复活。 - AI 船(敌船/巡逻船/海上炮台):由
AIShipFactory.cs在运行时整船组装——铺地板、放建筑、招船员、装 AI 状态机,全部按舰队配置 JSON 生成。
玩家接触船只的方式:键盘直接操船(WASD)、右键点海面自动导航、按 F 全速前进;建造模式下在甲板格子上摆建筑改变船的重量、动力与火力;战斗中船体被打穿会进水沉没。
所有船统一注册到 ShipRegistry.cs,船上金币存在 ShipData.cs(上限 9,999,999,999,代码常量)。
一、船的组成结构
Section titled “一、船的组成结构”- 船是一张以船体原点为中心的建造网格(
GridManager.cs):每格 1×1 米(gridSize = 1,Inspector 字段)。玩家船网格 100×100 格(代码默认),AI 船 50×50 格(AIShipFactory.cs代码常量)。 - 建筑按三维格坐标摆放,Y 坐标 = 甲板层。
ShipBuildingOrganizer.cs自动把每个建筑挂到对应的Deck_{y}节点下(Deck_0 = 底层甲板)。 - “底层地板” 定义 = 格坐标 Y 为 0 且建筑层为 Floor 的建筑(
ShipBuoyancy.cs)。它同时决定三件事:浮力分子、船体外接半径、碰撞船舷的生成位置。
船体物理外壳(ShipHull.cs)
Section titled “船体物理外壳(ShipHull.cs)”- 整船只有一个刚体:无重力、锁定垂直位移与横滚/俯仰(只能在海平面上平移+水平旋转),连续动态碰撞检测。
- 外接半径 = 最远底层地板到船中心的距离 + 0.7 米(半格对角线余量,代码常量)。AI 的距离判定、避让检测都用这个半径。
- 沿甲板暴露边缘自动生成“碰撞船舷”——一圈薄壁碰撞体(高 1.2 米、厚 0.08 米,Inspector 字段,运行时添加故取代码默认值),防止侧向碰撞从薄甲板之间穿透。地板增减时自动重建。
总质量 = Σ墙体材质重量 + Σ(地板格数 × 0.1) + Σ(其他建筑占地格数 × 1.0),下限 1
| 部件 | 质量贡献 | 来源 |
|---|---|---|
| 墙 | 按墙体材质重量(IWallComponent.Weight) | 见 建筑 / 修建 |
| 地板 | 每格 0.1 | ShipHull.cs Inspector 字段 _massPerFloor(运行时添加 → 代码默认值) |
| 其他建筑(引擎、火炮、家具等) | 每占地格 1.0 | ShipHull.cs 代码常量 |
质量变化即时推送给移动系统与引擎系统重新计算。参考校准:玩家初始船约 mass = 33(ShipEngineBinding.cs 注释)。
船级服务容器(ShipContext.cs)
Section titled “船级服务容器(ShipContext.cs)”每艘船自带一整套独立服务:建筑注册表、寻路、任务管理、船员管理、武器分配、容器/库存、薪酬、关系网。AI 船与玩家船服务栈一致(AIShipFactory.cs 按相同顺序组装),所以敌船船员也会吃饭、搬弹药、操炮,见 任务与工作、船员。
二、动力链:锅炉 → 引擎 → 航速
Section titled “二、动力链:锅炉 → 引擎 → 航速”船的速度不是固定属性,而是由船上引擎建筑的实时产出驱动:
- 锅炉烧煤产蒸汽,引擎(Engine 建筑)作为生产建筑消耗蒸汽运转(见 生产与制作)。
EnginePowerComponent.cs监视每台引擎:有效输出 = 正在生产 ? 综合生产效率(0~1) : 0,以 1 秒平滑时间渐变(_smoothingSeconds = 1,Inspector 字段)——蒸汽断供约 1 秒内动力归零,恢复供汽约 1 秒爬满。ShipEngineBinding.cs汇总全船动力并换算航速(海军上将系数:功率 ∝ 速度³):
总功率 = Σ(各引擎有效输出) × 400 质量惩罚 = 1 / (1 + (总质量 / 80)^1.5) 速度倍率 SpeedRatio = 总功率^(1/3) × 质量惩罚 (总功率为 0 时 = 0,船完全不动) 最高航速(米/秒) = 1.715 × SpeedRatio 最大转向速率(度/秒) = 10.0 × SpeedRatio
| 参数 | 值 | 单位 | 来源 |
|---|---|---|---|
单引擎满功率贡献 _powerPerEngine |
400 | — | Inspector 字段(场景中玩家船 = 400;AI 船运行时添加 = 默认 400) |
无动力最低速度比例 _minSpeedRatio |
0 | — | Inspector 字段 |
质量惩罚中点 _massPenaltyMidpoint |
80 | 质量 | Inspector 字段(mass=80 时惩罚恰为 0.5) |
质量惩罚陡峭度 _massPenaltyStiffness |
1.5 | — | Inspector 字段 |
| 基准速度刻度 BASE_MOVE_SPEED | 1.715 | 米/秒 | ShipEngineBinding.cs 代码常量(刻意不进 Inspector) |
| 基准转向刻度 BASE_ROTATE_SPEED | 10.0 | 度/秒 | 代码常量 |
校准基准(ShipEngineBinding.cs 注释):玩家船 mass=33、1 台引擎满转 → SpeedRatio = 400^(1/3) × 0.79 ≈ 5.83 → 顶速 ≈ 10 米/秒(约 19 节),最大转向 ≈ 58 度/秒(约 6 秒一圈)。没有速度上限:堆引擎可以无限提速,但收益按立方根递减,加重又吃质量惩罚。
注意:MovementController 在场景里序列化的 moveSpeed=14 / rotateSpeed=30 每物理帧都会被 ShipEngineBinding 覆盖,改它们无效。
船长在岗(CaptaincyManager.cs,仅玩家船)
Section titled “船长在岗(CaptaincyManager.cs,仅玩家船)”- 在岗判定 = 船上存在一名军衔为 Captain 的船员,且存活、未失能、未瘫痪。事件驱动 + 每秒 1 次轮询兜底。
- 缺岗时机动乘数 = 0.5:航速、转向速率、线性加速度、角加速度全部减半(
CaptaincyConsts.cs代码常量MissingMultiplier)。 - 缺岗持续 60 秒(实时秒,代码常量
MissingThoughtDelaySeconds)后全船船员获得“群龙无首”负面心情(见 船员)。船长回岗即解除。 - AI 船完全不受此机制影响(初始化即跳过)。
三、移动与转向物理(MovementController.cs)
Section titled “三、移动与转向物理(MovementController.cs)”所有船共用一套参数(代码常量,刻意不走 prefab Inspector)。控制模型是 P 控制器 + 各向异性水阻力:
质量因子 = sqrt(80 / 总质量) (重船加速慢、滑行远、转向沉;80 为参考质量) 有推进输入时:前向速度 += (目标速度 − 当前前向速度) × 0.30 × 质量因子 × 船长乘数 × dt 松开油门后:前向速度 ×= e^(−0.12 × 质量因子 × dt) 横向速度恒衰减:×= e^(−0.2 × 质量因子 × dt) 有转舵输入时:角速度 += (目标角速度 − 当前角速度) × 0.3 × 质量因子 × 船长乘数 × dt 目标角速度 = 转舵输入 × 最大转向速率 × 舵效 舵效 = 0.25 + 0.75 × (当前速度 / 顶速)(原地只有 25% 转向能力,全速 100%) 松舵后:角速度 ×= e^(−0.5 × 质量因子 × dt)
| 参数 | 值 | 含义 | 来源 |
|---|---|---|---|
| ACCEL_COEFFICIENT | 0.30 | 线加速系数;中型船约 10 秒达到 95% 顶速 | MovementController.cs 代码常量 |
| ANGULAR_ACCEL_COEFFICIENT | 0.3 | 角加速系数;约 10 秒达到 95% 最大角速度 | 代码常量 |
| DRAG_COEFFICIENT | 0.12 | 松手滑行衰减;中型船约 25 秒滑停 | 代码常量 |
| LATERAL_DRAG_COEFFICIENT | 0.2 | 横向阻力 ≈ 纵向 1.7 倍,转弯保留大部分动能 | 代码常量 |
| ANGULAR_DRAG_COEFFICIENT | 0.5 | 松舵后旋转衰减 | 代码常量 |
| REFERENCE_MASS | 80 | 质量因子锚点(与引擎质量惩罚中点同值) | 代码常量 |
| 角速度归零阈值 | 操舵中 0.01;松舵 0.5 | 度/秒;防止重船“舵回中后还转 30 秒” | 代码常量 |
| 倒车转向 | 后退时转向输入反相 | — | 代码逻辑 |
四、浮力与沉没(ShipBuoyancy.cs)
Section titled “四、浮力与沉没(ShipBuoyancy.cs)”浮力 = max(0, 当前底层地板数 − 未修复破洞数) / 历史最大底层地板数 (无地板史时 = 1)
战斗中 Deck 0 外缘墙被打爆会登记“破洞”,等效少一块地板;只有在原坐标重建墙才撤销(与地板修复完全独立)。
| 状态 | 条件 | 效果 |
|---|---|---|
| 安全 Safe | 浮力 ≥ 50% | 水位每秒 −5 |
| 进水 Sinking | 浮力 < 50% | 水位每秒 +(0.5 − 浮力) × 100(浮力 0 时每秒 +50,2 秒灌满) |
| 沉没 Sunk | 水位 ≥ 100 | 触发沉没流程 |
| 参数 | 值 | 来源 |
|---|---|---|
安全阈值 _safeThreshold |
0.5 | Inspector 字段(场景玩家船 = 0.5,可调 0.3~0.7) |
最大水位 _maxWaterLevel |
100 | Inspector 字段 |
排水速度 _drainRate |
5/秒 | Inspector 字段 |
进水系数 _leakMultiplier |
100 | Inspector 字段 |
玩家船沉没流程
Section titled “玩家船沉没流程”- 禁用碰撞与操控,立即结算死亡惩罚:
- 金币损失 = 当前金币 × 50%(
_goldLossPercent,Inspector 字段),以金币掉落物形式留在沉没点; - 每组物品损失比例 ~ 正态分布(均值 0.375,标准差 0.125),截断到 0~75%(Inspector 字段
_itemLossMean/_itemLossStdDev),掉落物散布在沉没点 ±5 米内,复活前不可拾取(见 战利品与掉落)。
- 金币损失 = 当前金币 × 50%(
- 复活倒计时:场景玩家船配置 3 秒(
_respawnDelay,Inspector 字段;代码默认 6 秒)。 - 复活:免费自动重建所有被毁地板、清空全部破洞、水位归零,传送到最后停靠的港口(
ShipRegistry.cs记录;无港口记录时GetRespawnPosition返回世界原点 (0,0,0)。场景RespawnPoint.cs注册的复活点只在 ShipRegistry 单例缺失时才会启用,正常运行中不生效)。
AI 船沉没流程
Section titled “AI 船沉没流程”沉没后 2 秒(代码常量)将船上所有容器物品生成为掉落物供玩家拾取,然后整船销毁,无复活。
在港可付费修复被毁地板:修复费 = 被毁地板数 × 10 金币/块(_repairCostPerFloor,Inspector 字段),并可一键排空积水(免费,DrainAllWater)。见 城市与国家。
五、船间碰撞(ShipCollisionHandler.cs + CollisionDamageCalculator.cs)
Section titled “五、船间碰撞(ShipCollisionHandler.cs + CollisionDamageCalculator.cs)”碰撞只在敌对阵营之间结算伤害(按阵营关系判定而非阵营字符串相等,避免误伤本国船,见 阵营与外交)。撞击速度取碰撞求解前的真实接近速度(接触点相对速度在法线上的分量)。
撞击力 = 接近速度 × 对方船质量 基础伤害 = round(撞击力 × 0.4) (< 1 则不结算) 单建筑实伤 = round(基础伤害 × 衰减),直接命中格 100%,周围 8 邻格 50%,下限 1
| 参数 | 值 | 单位 | 来源 |
|---|---|---|---|
伤害系数 _damageCoefficient |
0.4 | — | Inspector 字段(运行时添加 → 代码默认值) |
伤害阈值 _minImpactForce |
0.375 | 米/秒(接近速度) | Inspector 字段 |
同一对船伤害冷却 _damageCooldown |
1 | 秒 | Inspector 字段 |
AI 撞击通知阈值 _minRamNotifyApproachSpeed |
0.15 | 米/秒 | Inspector 字段 |
接触会话宽限 _contactGraceSteps |
2 | 物理步 | Inspector 字段 |
伤害落到命中格及邻格上的建筑(每个建筑每次碰撞只伤一次),走通用伤害管线,见 伤害与护甲。
撞击导致船员摔倒(仅玩家船,Ship.cs 代码常量)
Section titled “撞击导致船员摔倒(仅玩家船,Ship.cs 代码常量)”碰撞接触点 5 米半径内的船员按碰撞强度掷骰:
| 接近速度 | 摔倒基础概率 | 摔倒后重伤概率 |
|---|---|---|
| < 0.3 米/秒 | 不触发 | — |
| ≥ 0.3(轻) | 10% | 0 |
| ≥ 0.5(中) | 25% | 5% |
| ≥ 1.0(重) | 50% | 15% |
实际摔倒概率 = 基础概率 × (1 − 距接触点距离 / 5米) 摔倒 = 瘫痪 2~4 秒(均匀随机)+ 中断当前任务 重伤 = 额外受到 ceil(最大生命 × 60%) 伤害
已失能/已瘫痪的船员不重复结算。
六、玩家操船方式
Section titled “六、玩家操船方式”| 操作 | 效果 | 出处 |
|---|---|---|
| W / S | 前进 / 后退(后退时 A/D 转向自动反相) | MovementController.cs(新版 InputSystem) |
| A / D | 左 / 右转舵 | 同上 |
| F | 全速前进开关:等价持续按住 W,不影响转舵;屏幕顶部显示“全速前进” | FullSpeedAheadController.cs |
| 右键点海面 / 小地图右键 | 设定自动导航目标(替换式) | WorldClickToTarget.cs / MiniMap |
| Shift + 右键 | RTS 式追加航点到队尾 | 同上 |
| N | 手动 → 提示开地图;自动航行中 → 暂停;暂停 → 恢复 | ShipNavigationController.cs |
| 任意 WASD 输入 | 自动航行 → 立即暂停(玩家接管) | 同上 |
| 进入建造模式 | 船舶键盘输入整体禁用(WASD 让给建造焦点) | MovementController.cs |
| 地图视角(MapView) | N / F / 右键操船入口全部屏蔽 | 各入口统一守卫 |
自动导航(ShipNavigationController.cs + ShipNavigationStateMachine.cs)
Section titled “自动导航(ShipNavigationController.cs + ShipNavigationStateMachine.cs)”三态状态机:Manual(手动)/ AutoNavigating(自动航行)/ Suspended(暂停)。
- 航线规划(
RoutePlanner.cs):先试起点到目标直线;被岛屿阻挡则在所有岛屿多边形顶点中找一个中转点(顶点沿外向方向推出 16 米安全距离,代码常量),使两段都通且总路程最短——最多 1 个拐点 / 2 段。两段都不通 = 目标不可达,弹提示不起航。 - 到达判定:距当前航点 < 5 米(
ArrivalRadius,代码常量)即切下一个航点;最后一个到达即完成。 - 卡死检测:每 5 秒采样一次(
StuckTimeWindow),位移 < 1 米(StuckPositionEpsilon)→ 判定受阻(Blocked),自动退回手动并通知 UI。 - 船沉没时自动取消导航。导航中按 F 视为玩家接管 → 暂停(船停下,而不是“接管 + 全速”)。
- 当前航线以静态响应式属性广播给航线渲染层/小地图(见 界面总览)。
七、敌船 AI 行为(ShipAIStateMachine.cs)
Section titled “七、敌船 AI 行为(ShipAIStateMachine.cs)”AI 决策以 5Hz(每秒 5 次,TickFrequency.FiveTimesPerSecond)驱动。每艘 AI 船初始化时自动分析自身武器布局:
- 主舷侧方向 = 全船武器朝向求和后取最近基数方向(前/后/左/右)。
- 武器射程 WeaponRange = 船上武器目标探测器的最大探测距离(无武器或 ≤ 1 时回退 20 米,代码常量),见 武器与弹药。
- 攻击距离 AttackRange = 行为为 “Ram” 时取检测半径(看见就冲),否则取 WeaponRange。
所有距离判定用边缘距离 = 两船中心距 − 双方外接半径之和。
状态与切换条件
Section titled “状态与切换条件”| 状态 | 行为 | 进入/退出条件 |
|---|---|---|
| Patrol 巡逻 | 围绕锚点漫游(半径 = 检测半径 × 0.8,航点到达判定 5 米);战备等级 Routine | 每 1 秒扫描一次敌人,发现 → Chase |
| Chase 追逐 | 直线追踪目标;战备 Alert | 边距 ≤ AttackRange → Attack 或 Ram;边距 > 检测半径 × 1.5 → 放弃回 Patrol |
| Attack 攻击 | 按武器布局选战术(下表);战备 BattleStations | 边距 > AttackRange × 1.5 → 退回 Chase |
| Ram 撞击 | 全速冲撞 + 撞后三段脱离(下文);战备 BattleStations;对目标关闭避让 | 边距 > 检测半径 × 1.5 → 退回 Chase |
| Flee 逃跑 | 背向威胁逃离 | 距威胁 ≥ 检测半径 × 2 → 回 Patrol。当前没有任何逻辑会切入此状态(见已知限制) |
| Garrison 驻守 | 永不移动,火炮自动开火;战备恒为 BattleStations;每 1 秒扫描刷新目标 | 永不主动退出;用于城市海防炮台 |
战斗状态(Chase/Attack/Ram)中目标失效(沉没/销毁)时:立即重新扫描,找到新目标继续战斗,否则回 Patrol。战备等级会改变船员炮术任务优先级并抑制需求任务(Alert → 优先级 8;BattleStations → 11 + 抑制吃喝需求,ShipCombatState.cs 代码常量),见 任务与工作。
目标选择(TargetScorer.cs)
Section titled “目标选择(TargetScorer.cs)”检测半径内取最近的敌对目标:所有已注册敌对船只 + 物理球扫描到的敌对怪物(见 怪物)。无评分权重,纯距离最近。
Attack 三种战术(AttackState.cs)
Section titled “Attack 三种战术(AttackState.cs)”理想交战半径 = WeaponRange × 0.525
| 战术 | 触发(主舷侧方向) | 机动逻辑 |
|---|---|---|
| Broadside 舷侧齐射 | 武器朝左/右舷 | 绕目标公转(右舷武器顺时针、左舷逆时针)。边距 < 理想 × 0.7:80% 径向拉开 + 20% 切向;> 理想 × 1.3:60% 径向靠近 + 40% 切向;之间:纯切向绕行 |
| BowChase 船艏追击 | 武器朝前 | 直冲目标;边距 < 理想 × 0.6 时径向后撤 10 米 |
| Kiting 风筝 | 武器朝后 | 背对目标边退边打;边距 > 理想 × 1.5 时斜向回靠(前向 30% + 侧向 70%) |
Ram 撞后三段响应(RamState.cs 代码常量)
Section titled “Ram 撞后三段响应(RamState.cs 代码常量)”- Coast 滑行 0.2 秒:完全停推,保留物理弹开冲量;
- Retreat 脱离 3.75 秒:沿(碰撞分离方向 × 0.7 + 远离目标方向 × 0.3)倒车/驶离,允许倒车;
- Charge 再冲:重新全速冲锋。撞击事件(接近速度 ≥ 0.15 米/秒)随时重置回第 1 段。
巡逻链与狗链(Leash)
Section titled “巡逻链与狗链(Leash)”- 城市巡逻船由
PatrolSimulationManager.cs虚拟模拟 + 近距激活,激活时锚点固定在所属城市,注入巡逻区采样器(航点只在巡逻区海面内取样)。 - LeashRadius:战斗状态下距锚点超过此值 → 强制放弃目标回 Patrol(防止玩家把巡逻船拖出城)。巡逻船 = 远巡半径 × 1.2;普通 AI 船 = 0(无限制)。见 遭遇与刷怪。
- 海防炮台(harbor_picket/battery/bastion/citadel 舰队)由城市系统 spawn 后直接切 Garrison。
八、AI 转向与避障
Section titled “八、AI 转向与避障”AI 不直接控制物理,而是把“想去哪”翻译成与玩家相同的虚拟摇杆输入(SteeringController.cs,每物理帧刷新):
转舵输入 = clamp(目标方向夹角 / 30°, −1, 1) (夹角 ≥ 30° 即满舵) 油门 = 油门系数 × lerp(1, 0.2, |转舵输入|) (满舵时只给 20% 油门,原地转向) 允许倒车时:目标落在船尾 ±115° 之外 → 切倒车,按船尾对准目标,倒车油门 × 0.9
| 参数 | 值 | 来源 |
|---|---|---|
转向比例带 _turnAngleRange |
30 度 | Inspector 字段(运行时添加 → 代码默认值,下同) |
转向时最小前进分量 _minForwardWhileTurning |
0.2 | 同上 |
倒车切换阈值 _reverseTurnThreshold |
115 度 | 同上 |
倒车油门倍率 _reverseThrottleScale |
0.9 | 同上 |
第一层防线:航点生成避让(WanderBehavior.cs,意图层)
Section titled “第一层防线:航点生成避让(WanderBehavior.cs,意图层)”巡逻漫游航点在生成时即排除:
- 非敌对船周边禁区:玩家船 30 米、其他 AI 船 15 米(
PatrolState.cs代码常量)——端点在禁区内或直达线段穿过禁区都重选; - 陆地过滤(
LandWanderFilter.cs):端点入岛或线段穿岛多边形都重选,见 岛屿与陆地; - 最多重试 10 次,全失败时选“侵入最浅”的候选(maximin 兜底)。
第二层防线:反应式船间软避让(SteeringController.cs)
Section titled “第二层防线:反应式船间软避让(SteeringController.cs)”对所有邻近船累加侧向避让力(不是只躲最近一艘):
避让触发距离 = (双方外接半径之和) × 2.5 (敌对船减半 = × 1.25,近距才避;Ram 目标完全豁免) 紧迫度 = 1 − 距离 / 避让触发距离 前向权重 = 正前方 1.0 ~ 纯侧方 0.15,后方障碍忽略 转向偏移 = 累计侧向 × 1.0(障碍在右 → 往左躲),1.5 秒侧向记忆防左右抖动 减速 = 油门 × max(0.2, 1 − 最大紧迫度 × 0.5)
反应式陆地避让(LandSteeringAvoidance.cs)
Section titled “反应式陆地避让(LandSteeringAvoidance.cs)”沿船头探查 30 米(代码常量,SteeringController.cs 调用处写死),探查点落入岛屿多边形 → 取最近岛边的外向法向 × 权重 1.5 折算成转舵偏移,同时油门 × 0.3 强制减速,防全速冲滩。
玩家自动导航同样经过 SteeringController,因此也享受这两层反应式避让;规划层则由 RoutePlanner.cs 负责绕岛。
公式与数值(集中速查)
Section titled “公式与数值(集中速查)”| 公式 | 出处 |
|---|---|
| 总质量 = Σ墙重 + 地板格 × 0.1 + 其他建筑格 × 1.0(下限 1) | ShipHull.cs |
| 质量因子 = sqrt(80 / 总质量) | MovementController.cs |
| 总功率 = Σ引擎有效输出(0~1) × 400 | ShipEngineBinding.cs |
| SpeedRatio = 总功率^(1/3) × 1/(1+(总质量/80)^1.5) | ShipEngineBinding.cs |
| 顶速 = 1.715 × SpeedRatio 米/秒;最大转向 = 10 × SpeedRatio 度/秒 | ShipEngineBinding.cs |
| 船长缺岗:速度/转向/加速度 × 0.5;60 秒后全船负面心情 | CaptaincyConsts.cs |
| 舵效 = 0.25 + 0.75 × 当前速度/顶速 | MovementController.cs |
| 浮力 = (底层地板数 − 破洞数) / 历史最大地板数;< 0.5 进水 | ShipBuoyancy.cs |
| 进水速度 = (0.5 − 浮力) × 100 /秒;排水 5/秒;水位 100 沉没 | ShipBuoyancy.cs |
| 死亡:金币 −50%;每组物品损失 |
ShipBuoyancy.cs |
| 碰撞伤害 = round(接近速度 × 对方质量 × 0.4);阈值 0.375 米/秒;冷却 1 秒;邻格 50% | ShipCollisionHandler.cs / CollisionDamageCalculator.cs |
| 摔倒概率 = (10%/25%/50%) × (1 − 距离/5米);瘫痪 2~4 秒;重伤 60% 最大生命 | Ship.cs |
| 自动导航:到达 5 米;卡死 5 秒内位移 < 1 米;绕岛拐点外推 16 米 | ShipNavigationController.cs / RoutePlanner.cs |
| AI:决策 5Hz;扫敌 1Hz;追逐放弃 = 检测半径 × 1.5;交战半径 = 武器射程 × 0.525 | ShipAIStateMachine.cs 等 |
| Ram 撞后:滑行 0.2 秒 → 脱离 3.75 秒 → 再冲 | RamState.cs |
| 避让距离 = 半径和 × 2.5(敌对 × 1.25);陆地探查 30 米;命中油门 × 0.3 | SteeringController.cs |
| 金币磁吸:半径 8 米,吸引速度 8 米/秒,0.8 米入账,每 0.3 秒扫描 | ShipPickup.cs(场景 Inspector 字段) |
AI 舰队配置表(策划可直接改)
Section titled “AI 舰队配置表(策划可直接改)”AI 船的船体构成全部来自 Assets/StreamingAssets/DataSets/fleet/*.json(共 14 个文件),字段:startingGold(初始金币)、floorSize(方形甲板边长,格)、crew(军衔+专长列表)、buildings(建筑名 + 网格偏移 + 朝向)、items(初始物资)。
| 舰队 | 甲板 | 船员 | 关键配置 |
|---|---|---|---|
| pirate_sloop | 6×6 | 4 | 锅炉+引擎、1 机枪、弹药 500 |
| speedboat | 5×5 | 3 | 锅炉+引擎、1 机枪 |
| gunship | 8×8 | 5 | 锅炉+引擎、2 机枪 |
| ram_ship | 8×8 | 4 | 锅炉+引擎、无武器(纯撞击,配合 behavior=Ram) |
| harbor_picket / battery / bastion / citadel | 6/8/10/14 | 1/3/5/8 | 1/2/4/6 门机枪、无引擎(海防炮台,Garrison 驻守) |
| combat | 22×22 | 7 | 4 机枪 + 全套生产链 |
| combat_player / production_test / full / outer_loop_starter / minimal | 18/18/16/14/10 | 9/5/5/6/2 | 玩家初始舰队预设(含床、厕所、屠宰台等生活设施) |
AI 船的出场参数在场景预设 JSON(Assets/StreamingAssets/Presets/*.json 的 aiShips 数组,ScenarioPreset.cs):fleet(引用上表)、factionId(默认 “Pirate”)、nationality、spawnOffset(相对玩家船)、behavior(“Patrol” 默认 / “Ram”)、detectionRange(默认 50 米)。
与其他系统的交互
Section titled “与其他系统的交互”- 建筑 / 修建:甲板格子上的一切都是建筑;地板=浮力与质量,墙=破洞登记与质量,引擎/锅炉=动力。建筑被毁直接改变船性能。
- 船员:船长在岗加成、碰撞摔倒、战备等级抑制需求;AI 船船员同样由任务系统驱动。
- 武器与弹药:AI 的攻击距离与战术由船上武器朝向和探测距离决定;Garrison 炮台依赖武器自动开火。
- 伤害与护甲:碰撞伤害走通用伤害管线。
- 阵营与外交:碰撞结算、AI 索敌、避让强度都按阵营敌对关系区分。
- 城市与国家 / 遭遇与刷怪:港口复活与修船;巡逻船虚拟模拟、海防炮台 spawn。
- 岛屿与陆地:所有导航/漫游/避让的陆地判定都基于岛屿多边形。
- 战利品与掉落:沉没掉落、金币磁吸拾取。
- 基础/时间与调度:AI 决策 5Hz、引擎监视 10Hz 都挂在统一 Tick 调度上。
- 工具/开发者工具:
AIShipSpawner.cs按预设生成 AI 船用于测试。
配置与调参指南
Section titled “配置与调参指南”| 想调的体验 | 改哪里 | 类型 |
|---|---|---|
| 全局船速手感(顶速/转速基准) | ShipEngineBinding.cs 的 BASE_MOVE_SPEED / BASE_ROTATE_SPEED |
代码常量(需程序改,刻意不进 prefab) |
| 加速/滑行/转向惯性 | MovementController.cs 五个系数常量 |
代码常量 |
| 单引擎功率、质量惩罚曲线 | 场景玩家船 ShipEngineBinding 组件的 _powerPerEngine / _massPenaltyMidpoint / _massPenaltyStiffness(AI 船用代码默认值) |
Inspector 字段 |
| 引擎动力响应速度 | Engine prefab 上 EnginePowerComponent 的 _smoothingSeconds |
Inspector 字段 |
| 船长缺岗惩罚强度/心情延迟 | CaptaincyConsts.cs |
代码常量 |
| 进水/沉没节奏 | 场景玩家船 ShipBuoyancy 的 _safeThreshold / _leakMultiplier / _drainRate |
Inspector 字段 |
| 死亡惩罚轻重 | 同上 _goldLossPercent / _itemLossMean / _itemLossStdDev、复活时间 _respawnDelay |
Inspector 字段 |
| 修船价格 | 同上 _repairCostPerFloor |
Inspector 字段 |
| 碰撞伤害强度/阈值 | ShipCollisionHandler.cs 字段默认值(运行时添加,等效代码常量) |
代码常量 |
| 撞击摔倒概率 | Ship.cs 顶部碰撞常量区 |
代码常量 |
| 敌船船体/武器/船员配置 | StreamingAssets/DataSets/fleet/*.json |
JSON 配置(策划可直接改) |
| 敌船行为/检测半径/出场位置 | StreamingAssets/Presets/*.json 的 aiShips |
JSON 配置 |
| AI 战术距离感 | AttackState.cs(0.525 交战系数与三档距离带)、ShipAIStateMachine.cs(1.5 倍放弃系数) |
代码常量 |
| 避让强度/抖动 | SteeringController.cs 避让字段默认值 |
代码常量(运行时添加) |
| 自动导航到达/卡死判定 | ShipNavigationController.cs 三个 internal 常量 |
代码常量 |
| 绕岛安全距离 | RoutePlanner.cs 的 DetourPushOut |
代码常量 |
提醒:玩家船 MovementController 在场景里的 moveSpeed/rotateSpeed 序列化值(14/30)运行时无效,会被引擎绑定每帧覆盖——不要在那里调速度。
已知限制与注意事项
Section titled “已知限制与注意事项”- Flee 状态是死代码:
FleeState.cs与逃跑血量阈值FleeHPThreshold = 0.25(ShipAIStateMachine.cs)已实现,但没有任何代码路径会切入 Flee——当前敌船永远不会因血量低而逃跑。 - 航线规划最多 1 个拐点:
RoutePlanner.cs是 Anno 风简化实现,需要连续绕过两个以上岛屿的目标会直接判“不可达”,玩家需点更近的中间点。 - AI 船扫怪用全场物理球扫描:
TargetScorer.cs对怪物目标用 Physics.OverlapSphere(船只走注册表),AI 船多时有性能开销。 - 巡逻船去激活不保留战损:
PatrolSimulationManager.cs注明 MVP 简化——巡逻船退出激活范围再回来时满血重生。 AIShipFactory.cs第 244 行注释过期:写着“moveSpeed=5”,实际MovementController代码默认 10,且运行时立即被引擎绑定覆盖,对行为无影响。- 复活延迟代码默认与场景不一致:代码默认 6 秒,场景玩家船配的是 3 秒,以场景为准。
- Garrison 永不退出:海防炮台被打也不还击移动、不逃跑;其覆灭判定由城市占领系统扫描子物体完成,不在船 AI 内。
- 速度无上限:引擎堆叠没有 cap(设计如此,立方根+质量惩罚自然递减),极端堆引擎的小船可以非常快。
- 碰撞船舷是运行时隐藏碰撞体:调试穿透问题时注意甲板边缘有一圈 1.2 米高、0.08 米厚的不可见 BoxCollider。
- 设计文档覆盖度低:
Docs/Notion/设计/实体/船只 Ship/目前只有“警戒状态配置”一张 CSV(且内容属于船员紧张度系统),移动/浮力/AI 均无设计文档,本页全部以代码为准。