跳转到内容

战利品与掉落

怪物、敌船与玩家自己的沉船都会在海面上留下可拾取的掉落物:金币由玩家船自动磁吸入账,物品由收集建筑磁吸入库;玩家死亡掉落遵循“死魂灵”规则(下次死亡前可捡回,再死即消失),远海虚拟战斗的残骸则走休眠机制(数据常驻、靠近才生成实体、10 分钟后过期)。

战利品系统是战斗与经济之间的桥梁:玩家击杀怪物获得可屠宰的怪物尸体、击沉敌船获得对方船舱里的全部物资,这些资源进入船上容器后流向生产与制作交易。同时它也是死亡惩罚的载体——玩家船沉没时损失的金币和物品并非凭空蒸发,而是以掉落物形式留在沉没点,给玩家一次“跑尸”捡回的机会。

玩家接触本系统的四条路径:

  1. 打怪:怪物死亡后在原地弹出掉落物(当前全部为“怪物尸体”),由船上的收集建筑自动吸取入库。
  2. 击沉敌船:实体 AI 船沉没后掉出船上所有容器里的物品。
  3. 自己沉船:损失一半金币和约三分之一物品,全部掉在沉没点,复活后驶回原地可捡回;但如果在捡回之前再次沉船,上一次的掉落会全部消失。
  4. 远海残骸:不在玩家视野内的虚拟巡逻船相互战损后,会在战损点留下木材/弹药残骸记录,玩家航行靠近时残骸实体才会出现,10 分钟无人拾取则永久消失。

掉落物分两种实体:物品掉落DropItem.cs,记录物品 ID 与数量)和金币掉落GoldDrop.cs,金色圆币,记录金额)。两者都有约 0.8 秒的落地弹跳动画,动画播完前不可被拾取。拾取没有手动操作——全部依靠自动磁吸(金币吸向玩家船体,物品吸向收集建筑),掉落物本身没有点击交互。

本页涉及的两个管理器(死魂灵管理器 DeathDropManager.cs、休眠管理器 LootHibernationManager.cs)都是运行时懒加载的全局单例,场景里没有摆放实例——它们身上的字段默认值实际等同于代码配置。

掉落物生成后立即播放“弹出—落地”动画,动画结束前处于不可拾取状态(防止物品在空中就被吸走)。

参数 说明 来源
弹跳高度 2 米 向上弹出的最高点 Inspector(ItemDrop.prefabGoldDrop.prefabDropTest.prefab_bounceHeight
弹跳总时长 0.8 秒 上抛 0.32 秒 + 回落 0.48 秒(总时长的 40% / 60%) Inspector(_bounceDuration);40%/60% 拆分为代码常量(DropItem.csGoldDrop.cs
弹出顶点水平随机偏移 X、Z 各 ±1 米 掉落物在空中的散布 代码常量(DropItem.csGoldDrop.cs
缩放动画 0.3 秒,从 30% 放大到 100% 出现时的弹性缩放 Inspector(_scaleAnimationDuration);30% 起始比例为代码常量
金币落地后自转 90 度/秒,绕 Y 轴无限循环 金币闪烁提示 Inspector(GoldDrop.prefab_spinSpeed

可拾取条件(DropItem.cs / GoldDrop.cs):

可拾取 = 落地动画已完成 且 物品数据有效 且 (不是死亡掉落物 或 玩家已复活)

触发:任何怪物血量归零。注意三种死亡路径都会走掉落判定(BaseMonster.cs 的死亡处理对所有死因统一):

  • 被玩家击杀;
  • 离玩家超过 100 米被系统回收(EncounterSpawnConstants.csDespawnRange = 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):

  1. 沉没瞬间,上一次死亡的掉落物(若还没捡回)全部销毁,然后才生成本次掉落——掉落物只保留一代。
  2. 沉没到复活之间为“死亡状态”,本次掉落物(金币和物品都包括)不可被任何方式拾取——防止复活前被船上收集建筑原地吸回,惩罚失效。
  3. 复活(倒计时 3 秒,mvp_002 场景 Inspector 值 _respawnDelay;脚本默认值为 6 秒)后死亡状态解除,掉落物恢复可拾取。玩家从复活港口驶回沉没点即可捡回。
  4. 死魂灵掉落没有时间限制,只要不再次死亡就一直留在海上。
  5. 当前没有任何界面标记沉没点位置(管理器记录了死亡坐标但无 UI 消费),玩家需要自己记路。

实体化的 AI 船(敌对巡逻船、海盗船等,由 AIShipFactory.cs 标记 AI 模式)沉没后:

  • 延迟 2 秒(代码常量,ShipBuoyancy.cs)后船体销毁;
  • 销毁前把船上所有容器的全部物品生成为掉落物,无损失比例、无概率判定,100% 全掉
  • 每件物品同样按沉没点 ±5 米散布;
  • 不掉金币(AI 船的金币不会变成掉落物);
  • AI 船没有复活,也不触发死魂灵清除。

来源四:远海虚拟战损残骸(休眠掉落)

Section titled “来源四:远海虚拟战损残骸(休眠掉落)”

公海上的巡逻船在玩家视野外以“虚拟船”形式运转(数据层模拟,见阵营与外交城市与国家)。虚拟船之间每 1 秒结算一次战斗(50 米交战距离、敌对阵营判定),血量归零判定为战损(PatrolSimulationManager.cs),在战损点留下残骸:

残骸堆数 = 随机整数(2 ~ 4)
每堆物品 = 从残骸表等概率抽取一行,数量在该行区间内随机(含两端)
每堆位置 = 战损点 + 半径 10 米圆内随机
存活时间 = 600 秒(10 分钟),到期连记录带实体一起删除

残骸表(代码常量,PatrolSimulationManager.csDebrisTable,全量收录):

物品 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.prefabMagicContainer.prefab 两种容器建筑上,建筑系统见建筑):

参数 预制体实配值 脚本默认值 来源
扫描间隔 0.5 秒 0.5 秒 Inspector(容器预制体上的 detectionInterval
检测半径 40 米 10 米 Inspector(detectionRadius,两个容器预制体都覆盖成了 40)
吸引速度 5 米/秒(先慢后快) 5 米/秒 Inspector(attractionSpeed
入库判定距离 0.5 米 0.5 米 Inspector(collectDistance

物品入库规则:

  • 开始吸引前检查目标容器能否容纳(含堆叠规则);容不下则不吸。
  • 吸引途中容器满了 → 中途取消,物品停在半路原地,等待其他建筑或下次扫描。
  • 到达后入库失败 → 物品状态重置,留在原地可被再次收集。
  • 玩家船体不直接拾取物品掉落——船上没有收集建筑就捡不了东西。

另注意区分:船员中断任务时把携带物丢在甲板上的“地面物品”走的是地板容器系统(TaskBase.csCrew.csFloorContainerManager),属于物品与库存的范畴,不是本页的掉落物,也不能被 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.csItemCollector.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.prefabMagicContainer.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
  • 怪物:怪物死亡是掉落判定的触发方;怪物 CSV 的 DropItemId / DropChance 两列归本系统消费。
  • 遭遇与刷怪:怪物超距回收(100 米)与遭遇区清场同样触发掉落判定。
  • 船只:玩家船沉没/复活流程驱动死亡惩罚掉落与死魂灵状态;AI 船销毁触发全船掉落。
  • 伤害与护甲:血量归零的判定来自战斗系统,掉落只消费死亡事件。
  • 物品与库存:物品掉落最终进入容器系统;金币直接进船只账户;地板物品系统与掉落物是两套并行机制。
  • 生产与制作:怪物尸体经屠宰台转化为怪物肉与兽油,是当前打怪收益的唯一变现路径。
  • 阵营与外交:虚拟巡逻船的敌对判定决定谁和谁打、谁战损掉残骸。
  • 城市与国家:巡逻船舰队由城市派出,是残骸掉落的源头。
  • 物品数据表:MonsterCorpse、Wood、CannonShell、Bullet 等掉落物的物品属性。
  • 开发者工具:遭遇场景测试(ScenarioExitCleanup.cs)以“三类死因总数对账”间接验证掉落流程必然执行。
想调的体验 改哪里 类型
某种怪掉什么 / 掉率 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.prefabMagicContainer.prefab 内 ItemCollector 所在节点的 detectionRadius 等字段 Inspector
哪些建筑能收物品 给目标建筑预制体加 ItemCollector 组件 Inspector
残骸内容/数量/存活时间 PatrolSimulationManager.csDebrisTable、堆数 2~4、ttlSeconds: 600——全是代码 代码常量,需程序改
残骸激活/消失距离 LootHibernationManager.cs_activationRadius / _deactivationRadius 字段默认值——该管理器运行时懒加载,场景里没有实例,等同改代码 代码
落地动画手感 各掉落预制体的 _bounceHeight / _bounceDuration / _scaleAnimationDuration Inspector
  • 打包版怪物掉落会失效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 掉落规则(类型数量由配置决定、死亡位置生成)与实现一致;文档“待细化”中列出的“具体掉落物品配置”对应当前的极简映射表;死魂灵、休眠残骸两套机制设计文档未提及,本页以代码为准。