战利品与掉落
怪物、敌船与玩家自己的沉船都会在海面上留下可拾取的掉落物:金币由玩家船自动磁吸入账,物品由收集建筑磁吸入库;玩家死亡掉落遵循“死魂灵”规则(下次死亡前可捡回,再死即消失),远海虚拟战斗的残骸则走休眠机制(数据常驻、靠近才生成实体、10 分钟后过期)。
战利品系统是战斗与经济之间的桥梁:玩家击杀怪物获得可屠宰的怪物尸体、击沉敌船获得对方船舱里的全部物资,这些资源进入船上容器后流向生产与制作和交易。同时它也是死亡惩罚的载体——玩家船沉没时损失的金币和物品并非凭空蒸发,而是以掉落物形式留在沉没点,给玩家一次“跑尸”捡回的机会。
玩家接触本系统的四条路径:
- 打怪:怪物死亡后在原地弹出掉落物(当前全部为“怪物尸体”),由船上的收集建筑自动吸取入库。
- 击沉敌船:实体 AI 船沉没后掉出船上所有容器里的物品。
- 自己沉船:损失一半金币和约三分之一物品,全部掉在沉没点,复活后驶回原地可捡回;但如果在捡回之前再次沉船,上一次的掉落会全部消失。
- 远海残骸:不在玩家视野内的虚拟巡逻船相互战损后,会在战损点留下木材/弹药残骸记录,玩家航行靠近时残骸实体才会出现,10 分钟无人拾取则永久消失。
掉落物分两种实体:物品掉落(DropItem.cs,记录物品 ID 与数量)和金币掉落(GoldDrop.cs,金色圆币,记录金额)。两者都有约 0.8 秒的落地弹跳动画,动画播完前不可被拾取。拾取没有手动操作——全部依靠自动磁吸(金币吸向玩家船体,物品吸向收集建筑),掉落物本身没有点击交互。
本页涉及的两个管理器(死魂灵管理器 DeathDropManager.cs、休眠管理器 LootHibernationManager.cs)都是运行时懒加载的全局单例,场景里没有摆放实例——它们身上的字段默认值实际等同于代码配置。
掉落物实体与落地动画
Section titled “掉落物实体与落地动画”掉落物生成后立即播放“弹出—落地”动画,动画结束前处于不可拾取状态(防止物品在空中就被吸走)。
| 参数 | 值 | 说明 | 来源 |
|---|---|---|---|
| 弹跳高度 | 2 米 | 向上弹出的最高点 | Inspector(ItemDrop.prefab、GoldDrop.prefab、DropTest.prefab 的 _bounceHeight) |
| 弹跳总时长 | 0.8 秒 | 上抛 0.32 秒 + 回落 0.48 秒(总时长的 40% / 60%) | Inspector(_bounceDuration);40%/60% 拆分为代码常量(DropItem.cs、GoldDrop.cs) |
| 弹出顶点水平随机偏移 | X、Z 各 ±1 米 | 掉落物在空中的散布 | 代码常量(DropItem.cs、GoldDrop.cs) |
| 缩放动画 | 0.3 秒,从 30% 放大到 100% | 出现时的弹性缩放 | Inspector(_scaleAnimationDuration);30% 起始比例为代码常量 |
| 金币落地后自转 | 90 度/秒,绕 Y 轴无限循环 | 金币闪烁提示 | Inspector(GoldDrop.prefab 的 _spinSpeed) |
可拾取条件(DropItem.cs / GoldDrop.cs):
可拾取 = 落地动画已完成 且 物品数据有效 且 (不是死亡掉落物 或 玩家已复活)来源一:怪物死亡掉落
Section titled “来源一:怪物死亡掉落”触发:任何怪物血量归零。注意三种死亡路径都会走掉落判定(BaseMonster.cs 的死亡处理对所有死因统一):
- 被玩家击杀;
- 离玩家超过 100 米被系统回收(
EncounterSpawnConstants.cs的DespawnRange = 100,代码常量,详见遭遇与刷怪); - 遭遇区会话结束时的清场。
判定规则(DropManager.cs):
roll = 随机数(0 ~ 100)若 roll ≤ DropChance(百分比,CSV 配置) → 掉落掉落物 = DropItemId 在映射表(DropItemMapping.asset)中对应的预制体 × 预制体上配置的数量掉落位置 = 怪物死亡点(无散布)每只怪物每次死亡最多掉一种、一份掉落物(单次判定,无多物品掉落表)。怪物不掉金币——全游戏的金币掉落物只来自玩家自己的死亡惩罚。
当前配置(CSV:StaticMonsterConfig.csv,策划可直接改;完整怪物数值见怪物):
| 怪物 ID | 掉落物品 ID(DropItemId) | 掉落概率(DropChance,%) |
|---|---|---|
| Normal | MonsterCorpse | 100 |
| Elite | MonsterCorpse | 100 |
| Boss1 | MonsterCorpse | 100 |
| SteelHorseshoe | MonsterCorpse | 100 |
| BlazeSerpent | MonsterCorpse | 100 |
| GlideRay | MonsterCorpse | 100 |
| BarnacleSwarm | MonsterCorpse | 100 |
| AbyssBeast | MonsterCorpse | 100 |
全部 8 种怪物(none / easy / hard 难度数据集同样)都是 100% 掉 1 个怪物尸体,没有差异化。
掉落物 → 预制体映射表(Inspector:DropItemMapping.asset,全量收录,当前仅 1 条):
| DropItemId | 预制体 | 预制体上的物品配置 |
|---|---|---|
| MonsterCorpse | DropTest.prefab |
物品 ID = MonsterCorpse,数量 = 1(Inspector 字段 _itemId / _itemCount) |
怪物尸体物品(CSV:StaticItemConfig.csv,详见物品数据表):最大堆叠 5,带新鲜度属性(初始 100/100)。经屠宰台配方(CSV:RecipeConfig.csv)1 个尸体 → 3 怪物肉 + 2 兽油,制作耗时 5.0 秒、工作类型为烹饪,详见生产与制作。
来源二:玩家船沉没——死亡惩罚与“死魂灵”
Section titled “来源二:玩家船沉没——死亡惩罚与“死魂灵””玩家船浮力耗尽沉没时(沉没条件见船只),在沉没点执行死亡惩罚(ShipBuoyancy.cs):
金币惩罚:
损失金币 = 向下取整(当前金币 × 50%)损失的金币生成为一个金币掉落物(金额合并,不拆堆),落在沉没点。50% 比例是 Inspector 序列化字段(mvp_002 场景玩家船 ShipBuoyancy 组件的 _goldLossPercent,可在 0~100% 间调)。
物品惩罚:遍历船上所有容器(每个建筑的存储/输入/输出三类容器都算),对每一个物品堆独立判定:
损失比例 = 正态分布随机数(均值 0.375, 标准差 0.125),裁剪到 [0, 0.75]损失数量 = 向下取整(该堆数量 × 损失比例)即平均损失约 37.5%,最多不超过 75%,运气好可能一件不丢(损失数量取整后为 0 的堆不掉)。均值与标准差是 Inspector 字段(_itemLossMean / _itemLossStdDev),0.75 上限是代码常量(ShipBuoyancy.cs)。每个损失的物品堆生成一个物品掉落物,位置为:
掉落位置 = 沉没点 + X 随机(-5 ~ +5 米) + Z 随机(-5 ~ +5 米)(±5 米散布为代码常量,ShipBuoyancy.cs。)
死魂灵规则(DeathDropManager.cs):
- 沉没瞬间,上一次死亡的掉落物(若还没捡回)全部销毁,然后才生成本次掉落——掉落物只保留一代。
- 沉没到复活之间为“死亡状态”,本次掉落物(金币和物品都包括)不可被任何方式拾取——防止复活前被船上收集建筑原地吸回,惩罚失效。
- 复活(倒计时 3 秒,
mvp_002场景 Inspector 值_respawnDelay;脚本默认值为 6 秒)后死亡状态解除,掉落物恢复可拾取。玩家从复活港口驶回沉没点即可捡回。 - 死魂灵掉落没有时间限制,只要不再次死亡就一直留在海上。
- 当前没有任何界面标记沉没点位置(管理器记录了死亡坐标但无 UI 消费),玩家需要自己记路。
来源三:实体 AI 船被击沉
Section titled “来源三:实体 AI 船被击沉”实体化的 AI 船(敌对巡逻船、海盗船等,由 AIShipFactory.cs 标记 AI 模式)沉没后:
- 延迟 2 秒(代码常量,
ShipBuoyancy.cs)后船体销毁; - 销毁前把船上所有容器的全部物品生成为掉落物,无损失比例、无概率判定,100% 全掉;
- 每件物品同样按沉没点 ±5 米散布;
- 不掉金币(AI 船的金币不会变成掉落物);
- AI 船没有复活,也不触发死魂灵清除。
来源四:远海虚拟战损残骸(休眠掉落)
Section titled “来源四:远海虚拟战损残骸(休眠掉落)”公海上的巡逻船在玩家视野外以“虚拟船”形式运转(数据层模拟,见阵营与外交与城市与国家)。虚拟船之间每 1 秒结算一次战斗(50 米交战距离、敌对阵营判定),血量归零判定为战损(PatrolSimulationManager.cs),在战损点留下残骸:
残骸堆数 = 随机整数(2 ~ 4)每堆物品 = 从残骸表等概率抽取一行,数量在该行区间内随机(含两端)每堆位置 = 战损点 + 半径 10 米圆内随机存活时间 = 600 秒(10 分钟),到期连记录带实体一起删除残骸表(代码常量,PatrolSimulationManager.cs 的 DebrisTable,全量收录):
| 物品 ID | 数量下限 | 数量上限 |
|---|---|---|
| Wood(木材) | 3 | 6 |
| CannonShell(炮弹) | 2 | 4 |
| Bullet(子弹) | 5 | 10 |
休眠机制:玩家离开后掉落物怎么处理
Section titled “休眠机制:玩家离开后掉落物怎么处理”残骸掉落走**休眠(hibernation)**机制(LootHibernationManager.cs / VirtualDrop.cs),与虚拟巡逻船同一套设计哲学——数据层永远存在,实体按需生成:
| 规则 | 值 | 来源 |
|---|---|---|
| 激活半径:玩家船距离掉落点小于此值时,生成真实掉落物实体 | 60 米 | LootHibernationManager.cs 字段默认值(该管理器为运行时懒加载单例,场景中无实例,改值等同改代码) |
| 休眠半径:玩家船距离大于此值时,销毁实体、退回数据记录 | 80 米 | 同上 |
| 激活/休眠检查间隔 | 2 秒 | 同上 |
| 过期检查间隔 | 10 秒 | 同上 |
| 残骸存活时间(注册方传入) | 600 秒 | 代码常量(PatrolSimulationManager.cs) |
策划角度的行为结论(有 PlayMode 测试佐证,LootHibernationPlayModeTests.cs):
- 玩家路过又离开:实体销毁,但数据记录保留——再回来(10 分钟内)残骸会原地重新出现,不会因为离开而丢失。
- 玩家拾取:实体被收集建筑吸走后,数据记录随之删除,不会刷回。
- 超时:注册后 600 秒无人拾取,无论玩家在不在场、实体是否已激活,记录与实体一并删除——在玩家眼前消失也是可能的。
- 激活与休眠半径间有 20 米滞回带,避免玩家在边界处反复横跳导致实体闪烁。
- 检查每 2 秒一轮,所以驶入激活半径后残骸实体最多延迟 2 秒才出现。
注意休眠机制只覆盖虚拟战损残骸。怪物掉落和死亡惩罚掉落都是直接生成的真实实体:没有存活时间、不会休眠、距离再远也不消失(怪物掉落直到被收集为止一直存在;死魂灵掉落直到被捡回或玩家再次死亡为止一直存在)。
拾取全部是自动磁吸,没有手动点击拾取。两条通道分工明确:
金币 → 玩家船体(ShipPickup.cs,挂在 mvp_002 场景玩家船上):
| 参数 | 值 | 来源 |
|---|---|---|
| 扫描间隔 | 0.3 秒 | Inspector(mvp_002 场景 _detectionInterval) |
| 检测半径 | 8 米 | Inspector(_detectionRadius) |
| 吸引速度 | 8 米/秒(先慢后快) | Inspector(_attractionSpeed) |
| 入账判定距离 | 0.8 米 | Inspector(_collectDistance) |
金币到达船体后直接计入船只金币(无需仓储空间),见物品与库存。
物品 → 收集建筑(ItemCollector.cs,建筑组件;当前配在 WoodContainer.prefab 与 MagicContainer.prefab 两种容器建筑上,建筑系统见建筑):
| 参数 | 预制体实配值 | 脚本默认值 | 来源 |
|---|---|---|---|
| 扫描间隔 | 0.5 秒 | 0.5 秒 | Inspector(容器预制体上的 detectionInterval) |
| 检测半径 | 40 米 | 10 米 | Inspector(detectionRadius,两个容器预制体都覆盖成了 40) |
| 吸引速度 | 5 米/秒(先慢后快) | 5 米/秒 | Inspector(attractionSpeed) |
| 入库判定距离 | 0.5 米 | 0.5 米 | Inspector(collectDistance) |
物品入库规则:
- 开始吸引前检查目标容器能否容纳(含堆叠规则);容不下则不吸。
- 吸引途中容器满了 → 中途取消,物品停在半路原地,等待其他建筑或下次扫描。
- 到达后入库失败 → 物品状态重置,留在原地可被再次收集。
- 玩家船体不直接拾取物品掉落——船上没有收集建筑就捡不了东西。
另注意区分:船员中断任务时把携带物丢在甲板上的“地面物品”走的是地板容器系统(TaskBase.cs、Crew.cs → FloorContainerManager),属于物品与库存的范畴,不是本页的掉落物,也不能被 ItemCollector 磁吸。
| 公式 | 出处 |
|---|---|
| 怪物掉落判定:随机数(0~100) ≤ DropChance 则掉落 | DropManager.cs |
| 死亡金币损失 = 向下取整(当前金币 × 0.5) | ShipBuoyancy.cs |
| 死亡物品堆损失 = 向下取整(堆数量 × clamp(正态(0.375, 0.125), 0, 0.75)) | ShipBuoyancy.cs |
| 死亡物品掉落散布 = 沉没点 + XZ 各 ±5 米均匀随机 | ShipBuoyancy.cs |
| 残骸堆数 = 随机整数 2~4;每堆位置 = 战损点 + 10 米圆内随机 | PatrolSimulationManager.cs |
| 虚拟船战损判定的伤害 = 四舍五入(10 × 攻方战力 ÷ max(1, 守方战力)),每 1 秒一轮 | PatrolSimulationManager.cs |
| 磁吸飞行时间 = 距离 ÷ 吸引速度(先慢后快加速曲线) | ShipPickup.cs、ItemCollector.cs |
| 数值 | 值 | 单位 | 来源类型 |
|---|---|---|---|
| 全部怪物掉落概率 | 100 | % | CSV(StaticMonsterConfig.csv DropChance 列) |
| 怪物单次掉落数量 | 1 | 个 | Inspector(DropTest.prefab _itemCount) |
| 死亡金币损失比例 | 50 | % | Inspector(mvp_002 玩家船 _goldLossPercent) |
| 死亡物品损失均值 / 标准差 / 上限 | 37.5 / 12.5 / 75 | % | 均值、标准差为 Inspector(_itemLossMean / _itemLossStdDev);上限为代码常量(ShipBuoyancy.cs) |
| 玩家复活倒计时 | 3 | 秒 | Inspector(mvp_002 玩家船 _respawnDelay;脚本默认 6) |
| AI 船沉没到销毁的延迟 | 2 | 秒 | 代码常量(ShipBuoyancy.cs) |
| 落地动画时长 / 弹跳高度 | 0.8 / 2 | 秒 / 米 | Inspector(各掉落预制体) |
| 金币磁吸:扫描 / 半径 / 速度 / 入账 | 0.3 / 8 / 8 / 0.8 | 秒 / 米 / 米每秒 / 米 | Inspector(mvp_002 玩家船 ShipPickup) |
| 物品磁吸:扫描 / 半径 / 速度 / 入库 | 0.5 / 40 / 5 / 0.5 | 秒 / 米 / 米每秒 / 米 | Inspector(WoodContainer.prefab、MagicContainer.prefab) |
| 休眠激活 / 休眠半径 | 60 / 80 | 米 | 代码(LootHibernationManager.cs 字段默认值,无场景实例) |
| 休眠激活检查 / 过期检查间隔 | 2 / 10 | 秒 | 同上 |
| 残骸存活时间 | 600 | 秒 | 代码常量(PatrolSimulationManager.cs) |
| 怪物超距回收距离(回收时仍判定掉落) | 100 | 米 | 代码常量(EncounterSpawnConstants.cs) |
| 怪物尸体最大堆叠 | 5 | 个 | CSV(StaticItemConfig.csv) |
| 屠宰配方:1 尸体 → 3 怪物肉 + 2 兽油 | 耗时 5.0 | 秒 | CSV(RecipeConfig.csv) |
与其他系统的交互
Section titled “与其他系统的交互”- 怪物:怪物死亡是掉落判定的触发方;怪物 CSV 的 DropItemId / DropChance 两列归本系统消费。
- 遭遇与刷怪:怪物超距回收(100 米)与遭遇区清场同样触发掉落判定。
- 船只:玩家船沉没/复活流程驱动死亡惩罚掉落与死魂灵状态;AI 船销毁触发全船掉落。
- 伤害与护甲:血量归零的判定来自战斗系统,掉落只消费死亡事件。
- 物品与库存:物品掉落最终进入容器系统;金币直接进船只账户;地板物品系统与掉落物是两套并行机制。
- 生产与制作:怪物尸体经屠宰台转化为怪物肉与兽油,是当前打怪收益的唯一变现路径。
- 阵营与外交:虚拟巡逻船的敌对判定决定谁和谁打、谁战损掉残骸。
- 城市与国家:巡逻船舰队由城市派出,是残骸掉落的源头。
- 物品数据表:MonsterCorpse、Wood、CannonShell、Bullet 等掉落物的物品属性。
- 开发者工具:遭遇场景测试(
ScenarioExitCleanup.cs)以“三类死因总数对账”间接验证掉落流程必然执行。
配置与调参指南
Section titled “配置与调参指南”| 想调的体验 | 改哪里 | 类型 |
|---|---|---|
| 某种怪掉什么 / 掉率 | Assets/StreamingAssets/StaticMonsterConfig.csv 的 DropItemId、DropChance 列(none / easy / hard 难度集在 DataSets/monsters/ 下各有一份) |
CSV,改完需重启或重载配置 |
| 新增一种掉落物 | ① 做一个挂 DropItem 组件的预制体,填 _itemId(须存在于 StaticItemConfig.csv)和 _itemCount;② 在 DropItemMapping.asset 加一行映射;③ CSV 里把怪物的 DropItemId 指过去 |
Inspector + CSV |
| 怪物单次掉落数量 | 对应掉落预制体(当前是 DropTest.prefab)的 _itemCount 字段 |
Inspector |
| 死亡惩罚轻重 | mvp_002 场景玩家船 ShipBuoyancy 组件:_goldLossPercent(金币比例)、_itemLossMean / _itemLossStdDev(物品损失分布);75% 硬上限需程序改 ShipBuoyancy.cs |
Inspector(上限为代码) |
| 复活等待时间 | 同上 _respawnDelay |
Inspector |
| 金币吸取手感(范围/速度) | mvp_002 场景玩家船 ShipPickup 组件四个字段 |
Inspector |
| 物品收集范围/速度 | WoodContainer.prefab、MagicContainer.prefab 内 ItemCollector 所在节点的 detectionRadius 等字段 |
Inspector |
| 哪些建筑能收物品 | 给目标建筑预制体加 ItemCollector 组件 |
Inspector |
| 残骸内容/数量/存活时间 | PatrolSimulationManager.cs 的 DebrisTable、堆数 2~4、ttlSeconds: 600——全是代码 |
代码常量,需程序改 |
| 残骸激活/消失距离 | LootHibernationManager.cs 的 _activationRadius / _deactivationRadius 字段默认值——该管理器运行时懒加载,场景里没有实例,等同改代码 |
代码 |
| 落地动画手感 | 各掉落预制体的 _bounceHeight / _bounceDuration / _scaleAnimationDuration |
Inspector |
已知限制与注意事项
Section titled “已知限制与注意事项”- 打包版怪物掉落会失效:
DropManager.cs在非编辑器运行时从Resources/DropItemMapping加载映射表,但DropItemMapping.asset实际放在Assets/Scripts/Service/Monster/下、不在任何 Resources 目录——编辑器内走专用路径正常,构建版会报“映射表未加载”且不生成任何怪物掉落。 - 掉落表极简(MVP 状态):映射表只有 MonsterCorpse 一条;全部 8 种怪物(含 Boss)都是 100% 掉 1 个尸体,没有按怪物种类/强度差异化,也没有多物品掉落、权重表或数量随机。怪物掉落预制体名为
DropTest.prefab,命名仍是测试痕迹。 - 超距回收的怪物也掉东西:离玩家超过 100 米被回收的怪物照常判定掉落,会在远处留下无人能捡的掉落实体;普通掉落物没有存活时间也不休眠,理论上会无限堆积(
DropManager.cs提供的全场清理方法当前没有任何调用方)。 - AI 船战利品会被玩家的死亡连坐清除:实体 AI 船的掉落物在实现上被标记为“死亡掉落物”并注册进死魂灵管理器(
ShipBuoyancy.cs的物品掉落生成路径对玩家惩罚和 AI 全掉统一打标)——玩家下次沉船时,没来得及收的敌船战利品会和上次的死魂灵一起被清除;玩家处于死亡状态期间它们也暂时无法被拾取。 - 没有沉没点标记:死魂灵管理器记录了上次死亡坐标,但当前没有任何 UI 或地图标记消费它,跑尸全凭玩家记忆。
- 掉落物不进存档:死魂灵掉落、怪物掉落实体、休眠残骸记录均无持久化,退出游戏即消失,详见存档。
- 物品掉落的旋转速度字段无效:
DropItem.cs的_rotationSpeed(默认 180)声明了但动画未使用,实际落地旋转固定为 0.8 秒内转完 720 度以上;调它没有效果。 - 金币掉落只有一种来源:当前版本怪物、AI 船、残骸都不产金币掉落物,金币掉落实体仅由玩家死亡惩罚生成(与之相对,交易收入直接改账户数字,不走掉落,见交易)。
- 设计文档一致性:
Docs/Notion/设计/玩法系统/怪物 Monster的 R9 掉落规则(类型数量由配置决定、死亡位置生成)与实现一致;文档“待细化”中列出的“具体掉落物品配置”对应当前的极简映射表;死魂灵、休眠残骸两套机制设计文档未提及,本页以代码为准。