做Unity项目这几年,跟“船”打过不少交道。最开始是在商店里看到一堆标注“帆船”“游艇”的3D资源,觉得挺好看,直接买了拖进场景里,结果船是浮在水面上了,但一开起来就像块肥皂在澡盆里打转,完全没法看。后来陆陆续续在好几个项目里碰船,从模拟航海、休闲竞速到数字孪生展示,慢慢把船类资源的选型、物理模拟、操控手感和画面表现这几个环节摸清楚了。这篇主要分享我在Unity里折腾船资源(重点说帆船和游艇)的一系列经验,从资源导入、浮力实现到操控系统、性能优化都有涉及,希望能帮正准备做水上玩法、航海模拟或数字孪生场景的朋友少踩几个坑。
适合谁看:刚拿到船模型不知道从哪下手的Unity新手,想把手头帆船/游艇做得“开起来像真的”的进阶开发者,以及需要在微信小游戏、WebGL或数字孪生项目里集成水上场景的技术同学。下面内容不依赖某个具体插件,大部分是用Unity自带组件和轻量代码就能落地的方案。
1. 船资源的选型与导入细节
1.1 商店里挑船资源,到底在挑什么
很多新手在Asset Store或者各种资源站找船的时候,第一眼只看“渲染图好不好看”,这个方向偏差很大。船类资源和普通角色、道具不太一样,它有几个关键指标需要重点检查。
第一个是三角面数。商店里那些标着“AAA”“电影级”的游艇模型,动辄几十万甚至上百万三角面。如果项目目标是PC端,这个数字咬咬牙还能用;如果是做微信小游戏或者移动端,这种模型基本没法直接用。我的建议是,帆船和游艇这类带大面积甲板和平滑曲面的船体,目视质量可接受的情况下,面数控制在5万到15万之间比较合理。太低了,船壳、船舱接缝处会看到明显棱线;太高了,后面优化会让你怀疑人生。
第二个是模型结构是否干净。打开导入设置,检查层级结构里是不是有大量空的子物体、冗余的节点、或者嵌套过深的分组。有些资源作者会把每个窗户、每个栏杆都拆成独立物体,导致后续挂载碰撞体、做水面浮力布点的时候非常痛苦。尽量选择那种“船体一个Mesh、甲板一个Mesh、上层建筑一个Mesh”的干净结构,如果结构乱了,先在3D软件里整理好再导出。
第三个是材质是否兼容你的渲染管线。现在Unity项目很多已经迁到URP或者HDRP了,但商店里不少老资源还停留在内置管线(BiRP)的标准着色器上。导入后如果发现船体材质变成洋红色,说明着色器不兼容。解决办法有两个:一是用URP的转换工具批量转换,二是重新给船体赋一套URP/Standard风格的新材质。这里我强烈建议先确认好项目管线再买资源,不然光是修材质就得搭进去大半天。
1.2 导入后的模型检查与调整
模型拖进场景之前,有几个常规检查项我会每次过一遍,能省掉后面大量排查时间。
Scale和轴向。Unity的默认单位是米,但不少第三方模型导出时是按厘米或英寸建模的。导入后如果船的尺寸显示为几百甚至几千,说明缩放比例不对,需要先在导入设置的Scale Factor里调回真实比例。一艘40英尺的游艇换算过来大概12米左右,帆船根据级别不同,常见的10米到15米都有,导入后对照这个数值就能大致判断比例是否正确。
碰撞体的处理。船体最好不要直接挂Box Collider或者Mesh Collider拿来当物理底盘——船是浮在水面上的,碰撞体如果包裹了整个船体,浮力计算会变得非常诡异。我一般会把碰撞体拆成两部分:一个简化船体的碰撞盒用于和岛屿、码头、其他船只碰撞,另外单独做一套浮力采样点系统(后面会细讲)处理水面交互。碰撞盒的尺寸要尽量贴合水线以下的船体轮廓,太大容易“空气墙”,太小又会穿帮。
轴心和坐标方向。船的模型轴心建议放在船体重心大致位置,Z轴朝船头方向更利于后续控制脚本编写。有些资源导出来轴心在船底或者船尾,虽然旋转和位移也能算,但写起来别扭,而且做摄像机跟随、转向控制时容易出错。我习惯导入后先建一个空父节点,把船体模型挂进去,再在父节点上统一调整位置和旋转,相当于手动“打磨”一个标准控制根节点。
把船体单独放进一个空的场景里做一次目视验收,检查法线方向、破面、漏光、UV接缝这些基础问题。这一步非常值得做,尤其是那些免费资源,经常能挑出好几个地方需要返工修补。花钱买还好,免费资源里很多都是作者早期练手作品,Bug不少。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 船体物理模拟:浮力与稳定的核心实现
2.1 浮力计算的基本原理
船能浮在水面上,靠的是阿基米德浮力定律:物体在液体中受到的浮力等于它排开液体的重力。公式很简单:
F = ρ × g × V
其中ρ是液体密度,g是重力加速度,V是船体浸入水下的体积。在Unity里,重力加速度默认是9.81,水的密度如果按现实来取就是1000 kg/m³。这意味着一个排水量为1
