Unity3D里搓一个旋转的地球听起来确实是个入门级练手项目新建场景、拖个球体、贴一张世界地图、写几行旋转脚本好像十分钟就能交差。但如果你真的照着这个流程跑一遍十有八九会卡在半路——球是黑的、贴图是紫的、或者按了Play之后纹丝不动。这篇文章想从我上个月做大屏展示背景地球时的完整经历说起把球体搭建、材质贴图、灯光、旋转脚本以及后面可以继续扩展的玩法视频纹理、外部模型合入都摊开讲一遍。特别适合刚接触Unity3D、想用一个能跑能看的项目摸清3D基本流程的朋友有经验的老手可以直接跳到最后一章看看有没有踩过同样的坑。1. 搭场景的三个前提球体、相机与单位比例1.1 为什么用Unity内建球体而不是外部模型新建一个Unity3D项目之后第一步不是去网上找什么地球模型而是直接在场景里创建一个Sphere。Unity的GameObject菜单下3D Object里就有Sphere默认半径0.5个单位缩放是(1,1,1)直接用就行。有人可能会问要不要去Assets Store下载一个带国家边界的地球模型我的建议是除非你要做非常精细的行政区域划分交互否则完全没必要。原因有两点第一Unity内建球体用的是标准的球体UV展开贴图直接贴上去就是正常的经纬线分布不会出现两极扭曲或者接缝错位。很多第三方模型为了配合点选、高亮功能UV拆得很碎反而不好贴材质。第二内建Sphere的网格顶点数恰到好处做旋转展示时性能开销几乎可以忽略。如果你后续还要加大气层、云层内建球体也方便套多层Material。1.2 默认场景里的相机和灯光先别急着删很多教程会告诉你先删掉默认物体从空场景开始但我不建议在这个项目里这么做。Unity新建3D项目时场景里默认会有Main Camera和Directional Light这两个物体在这个项目里全都用得上。你需要做的只是在Hierarchy面板右键选择3D Object → Sphere把球体放到世界原点(0,0,0)。然后调整Main Camera的位置把它放到球的斜前方比如(0, 2, -4)到(0, 2, -8)这个区间。为什么要放在这个位置因为Sphere的直径只有1个单位相机太近会看到球体局部太远又显得太小。FOV默认60度的情况下距离4到8个单位球体在画面中央会占大约四分之一到三分之一的高度作为展示主体正合适。这里有个容易忽略的点相机默认看向(0,0,0)球体也在原点所以不需要反向调整旋转直接改Position就行。1.3 别和真实尺寸较劲地球的真实半径大约是6371公里但在Unity里做视觉项目完全没有必要把这个数值填进去。如果非要用真实比例Sphere的Scale得写成(6371,6371,6371)相机得放得极远灯光距离也得跟着调整最后只是给自己找麻烦。Unity的单位默认是米但这个米在纯视觉项目里没有物理意义。你要记住的是球体的Scale决定它在画面里的相对大小而不是它代表多么大的一颗行星。做旋转地球展示时Scale保持在1到3之间都是舒服的范围后续要做的轴倾角、公转也都是在Scale为1的基础上计算的。先把视觉调对了再谈比例。2. 给地球穿上皮贴图来源、材质管线和灯光缺一不可2.1 找对贴图等距圆柱投影是硬性条件球体建好以后身上是默认的白色材质下一步就是给贴图。这一步最大的坑是随便百度一张世界地图就拖进Unity。普通的地图截图和球体贴图需要的等距圆柱投影Equirectangular Projection不是一回事。等距圆柱投影贴图有非常明显的外部特征图片宽高比是2:1横向上均匀展开360度经度纵向上从北极到南极均匀展开180度纬度。为什么Unity的Sphere需要这种投影因为球体的UV就是把球面从北极剪开、铺平成一个矩形而Unity的Sphere默认UV坐标恰好和等距圆柱投影一一对应。推荐几个靠谱的地球贴图来源都是公开科普资源Solar System Scope提供2K、4K、8K的日景地球贴图命名一般是earth_daymap还有夜景灯光版本earth_nightmap。NASA的Blue Marble系列老牌高清地球影像适合追求真实感的大屏效果。下载时直接选择4K分辨率就够了。2K在近距离看会糊8K则对显存和载入内存都不友好。把图片拖进Project窗口后Unity会自动导入但导入设置需要手动确认一下。导入参数推荐设置原因Texture TypeDefault让引擎把它当作颜色纹理处理sRGB勾选地球贴图是颜色数据不是法线或数据图Max Size2048或4096视觉清晰度和性能的平衡点Generate Mip Maps开启旋转时远景会平滑过渡减少闪烁CompressionASTC移动端/ 默认PC减少包体和内存占用2.2 材质球Shader不匹配是紫色球的元凶右键Project面板Create → Material新建的材质球在Built-in渲染管线里默认Shader是Standard。如果你的项目是用默认3D模板创建的那直接用Standard没问题但如果你的项目是URPUniversal Render Pipeline模板创建的Standard材质会直接显示成紫色。这个紫球问题太经典了我见过不少人以为是贴图坏了其实只是Shader不匹配。在URP项目下新建材质时应该把Shader手动改成Universal Render Pipeline/Lit在HDRP项目下则要改成HDRP/Lit。判断自己项目用的什么渲染管线看Project Settings → Graphics里的Scriptable Render Pipeline Settings字段就能确定。材质球建好后把地球贴图拖到Base MapURP或AlbedoBuilt-in上。Smoothness可以调到0.5到0.8这样海洋部分会有轻微反光看起来更像真实地球。Metallic保持0地球毕竟不是金属球。2.3 灯光方向和环境光决定球是亮的还是黑的一半材质贴好之后如果球体还是一片黑问题几乎都出在灯上。默认场景里的Directional Light旋转角度大概是(50,-30,0)按理说能照亮原点处的物体。但如果你转到了其他角度让平行光从相机背面往前打球体正面就会是黑的。选中Directional Light在Inspector里旋转Rotation看着球面出现明显的亮暗分界就能确认光照方向正确了。注意背光面保持黑暗是正常物理现象不用慌。如果你想要球体正面和背面都没那么大的反差有两个办法一是增加一个平行光从反方向打过去强度设为0.3左右作为补光二是调环境光打开Window → Rendering → Lighting → Environment把Ambient Intensity从1调低到0.3到0.6之间让暗部摊上一层淡淡的底色。顺带提醒一句如果这个地球是要做大屏背景或者录屏素材的阴影可以先关掉。选中Directional Light把Shadow Type设为No Shadows。太空环境里的大地球自身阴影往往会让观众觉得画面太脏关掉之后球的轮廓会干净很多。3. 手写旋转脚本Update、Time.deltaTime与自转轴的秘密3.1 最小可用脚本7行代码让球转起来材质和灯光就位接下来是核心动作——旋转。在Project面板右键Create → C# Script命名EarthRotation双击打开编辑器填入下面的代码using UnityEngine; public class EarthRotation : MonoBehaviour { [SerializeField, Range(0f, 200f)] private float rotateSpeed 10f; [SerializeField] private Vector3 rotationAxis Vector3.up; private void Update() { transform.Rotate(rotationAxis, rotateSpeed * Time.deltaTime, Space.World); } }把脚本拖到Sphere上按Play球就开始转了。转速10度每秒是比较慢的匀速适合放在页面角落做氛围如果想让转动更明显可以调到20到30。地球真实的自转周期是24小时折合15度每小时放视觉项目里根本看不出来所以这里追求的是看起来舒服不是科学仿真。3.2 Time.deltaTime到底在干什么很多新手会把这行代码写成transform.Rotate(Vector3.up * 10f)结果就是转动速度忽快忽慢。原因很简单Unity的Update是每帧执行一次但每帧的耗时不一样。60帧每秒时每秒会转600度降到30帧每秒时每秒只转300度。帧率越低转速越慢。Time.deltaTime返回的是上一帧花费的真实秒数单位是秒。用它乘以角速度就把每帧转多少度换算成了每秒转多少度转速就和帧率解耦了。这是Unity里所有平滑运动的通用写法不只是旋转位移、颜色渐变、数值插值都这么处理。3.3 Space.World与Space.Self的选择transform.Rotate的第三个参数是旋转坐标系我们传了Space.World意思是让物体绕世界坐标轴旋转。有人会问球体挂在场景根节点下用Self不也一样吗区别在于如果球体的父物体有旋转或缩放Space.Self会在父物体的局部坐标系里旋转转着转着轴向就可能跑偏。而Space.World永远以世界坐标的Y轴为基准不管父物体怎么折腾地球始终朝同一个方向自转。说句实在的单球体场景里两个参数看不出差别但写成Space.World是个好习惯。后面做轴倾角时这个细节直接决定你会不会绕晕。3.4 自转轴倾斜23.44度的玩法真实地球的自转轴与公转平面法线之间夹角约23.44度这个倾斜导致四季变化。视觉项目里如果想让球更像真的可以加一个倾斜结构。正确做法不是改Sphere自身的Rotation而是新建一个空物体命名为EarthPivot把Sphere拖进去作为子物体然后把EarthPivot的Rotation.z设为23.44。为什么倾斜要加在父物体上因为旋转脚本是挂在Sphere上的Sphere自身旋转时它的轴始终是自己局部坐标的Y轴。Pivot负责把整根轴先歪到23.44度Sphere再绕这根歪着的轴转出来的效果才符合直觉。代码里继续保持rotationAxis为Vector3.up不用改任何东西。这个父物体负责倾斜、子物体负责自转的结构以后做公转也直接用得上——给EarthPivot再加一个速度更慢的公转脚本让EarthPivot绕太阳转就能模拟地球绕恒星的效果。4. 从静态球到动态地球星空背景、视频纹理与外部模型扩展4.1 星空背景把默认Skybox换成深空贴图默认场景的背景是灰蓝色的渐变天空在地球项目里显得很突兀。改成深空星空是让整体质感上一个台阶的最快手段。打开Window → Rendering → Lighting → Environment看到Skybox Material这一栏。默认是内置的Default-Skybox把它换成你自己准备的星空材质即可。具体做法是在Project面板右键Create → MaterialShader选择Skybox/Panoramic然后找一张2:1的全景星空贴图拖到这个材质球上再把材质球赋给Skybox Material字段。这里有个取舍Skybox方案简单高效但星空是钉在场景远端的相机怎么转星星的视角都跟着变。如果你的相机基本不动或者旋转角度很小Skybox完全够用。如果你要做一个大范围移动的场景星星最好用粒子系统做那样星星会分布在真实的三维空间里移动相机时会有视差。对旋转地球这个项目来说Skybox是性价比最高的选择。4.2 动态表面VideoPlayer把视频流变成长在地球上的纹理静态贴图玩腻之后可以尝试让地球表面实时播放视频内容这种需求在会议大屏、展厅可视化里很常见。你可以在网上找一段循环的云图动画或者全球气象数据可视化视频把它映射到球体表面。操作流程不复杂在Project里导入一段视频文件Asset Store拖入即可。创建一个Render Texture资源分辨率建议1280×720或1920×1080。给球体挂上VideoPlayer组件把Video Clip指定为那段视频Target Texture指向准备好的Render Texture。把原来赋给材质球的贴图直接换成这个Render Texture结果就是视频画面实时显示在地球表面。不需要写代码纯编辑器操作就能打通。需要注意VideoPlayer组件的Audio Output Mode要设为None否则它会尝试播放视频音轨。另外视频类型选Movie Texture还是Video Clip取决于你的视频编码前者适合老式导入方式后者支持更多格式。这类动态纹理方案本质上就是unity3d视频流的一种落地场景——把外部视频源接到3D物体的材质上很适合做直播间的动态星球背景、产品展示底座这类效果。4.3 外部模型合入SolidWorks模型导入Unity的单位坑如果后续业务需要把卫星、火箭、机械臂这类CAD模型放到地球旁边做展示一般会从SolidWorks导出模型。这条路有坑主要坑在单位换算。SolidWorks里默认长度单位是毫米而Unity默认单位是米。直接从SolidWorks导出STL再拖进Unity模型通常会变成巨大的怪物。稳妥的流程是把SolidWorks模型先导出为STEP或IGES再用Blender或3ds Max等中间软件转成FBX或GLB。转换时注意Blender的Unit Scale和SolidWorks的单位设置要保持一致导出FBX时勾选Apply Transform。FBX导入Unity后在ModelImporter的Inspector里确认Scale Factor和单位换算是否合理如果模型是从毫米转过来的Scale Factor可能是0.001如果中间软件已经处理过单位Scale Factor保持1即可。验证方式很简单导入后看模型在Scene视图里的尺寸是不是符合你的直觉比如1米左右的卫星应该和球体差不太多而不是大得把场景都撑爆。外部模型挂到地球的演示场景时旋转脚本的逻辑完全通用新建一个空物体作父级把模型的坐标零点归到父级原点再把这个父级拖到EarthPivot下挂上同一套旋转脚本即可。模型自身的轴方向跟Unity不统一时就在父级加一个Rotation修正值别去改模型内部网格。4.4 性能与表现阴影、贴图大小和Draw Call控制球体旋转只是基础但如果把场景做到半成品就卡顿掉帧那就不划算了。几个容易忽视的性能点第一个是阴影。Directional Light开实时阴影时场景里最消耗GPU的往往就是阴影贴图渲染。展示类项目中我会把Directional Light的Shadow Type关掉或者只保留球体的简单投影。第二个是贴图串流。8K地球贴图加上8K星空全景再加上视频RenderTexture显存占用会明显上升。不是所有屏幕都需要8K用4K贴图配合Mip Maps在大部分显示设备上看不出差别加载速度还快不少。第三个是Draw Call。一个球体加一个天空盒本身Draw Call很少所以基本不必优化。但如果你为了美观叠了云层球、大气层球、边缘发光球那Draw Call每加一层就多一份。这种时候把云层贴图的Alpha Blend材质换成同一Shader的粒子版本或者用GPU实例化可以省出不少开销。5. 排错实录地球不转、半边黑、贴图发紫怎么查5.1 球不转的排查链路从脚本到视角逐个排除我先说结论90%的球不转不是代码没写而是组件没挂对或视角被干扰。下面是一条完整排查链路照着走基本能找到病根。第一步看Console窗口有没有红色报错。Unity有个特性只要脚本有编译错误整个项目里的任何脚本都不会运行场景正常Play也不会报错。你写的代码语法越简单越不容易踩这个坑但一旦踩了所有脚本全部失效球自然不转。第二步选中Sphere看Inspector里的EarthRotation组件是否存在、是否被勾选。组件在的话展开rotateSpeed和rotationAxis两个字段确认rotateSpeed不为0、rotationAxis不等于(0,0,0)。第三步在Play状态下观察Sphere的Transform里的Rotation数值有没有跳动。数值在变说明旋转逻辑正常数值不动脚本没执行。第四步检查视角。这是最容易被忽略的如果相机本身也挂了EarthRotation脚本或者相机被放进了EarthPivot的子级那相机跟着球同步转看起来球就像不动一样。还有一种情况是Sphere的Scale被调成(100,100,100)相机在(0,0,-10)位置其实已经钻进球体内部了此时你看到的是球内壁旋转时画面是一堆扭曲的贴图在翻滚也完全看不出地球在转。5.2 球是黑的光照方向与环境光的校准球体全黑或大半黑通常有三个原因按优先级排查第一Directional Light的Rotation不对。平行光本质上没有位置概念只有方向概念方向由Rotation决定。选中平行光旋转它的Rotation让方向光从相机所在的一侧照向球体球面就会出现高光。这一步是立竿见影的。第二环境光太暗。即使有方向光如果Environment Lighting里的Ambient Intensity被调到0背光面就会黑得发闷。把Ambient Intensity恢复到0.5左右球体暗部会透出微弱冷色整体更自然。第三贴图根本没赋上。如果材质的Base Map还是空的球再亮也是灰白色谈不上黑。所以还要顺手检查一下材质球上有没有真实贴图。5.3 材质发紫/贴图花管线和UV问题的对症下药发紫的问题前面说过几乎全是Shader与渲染管线不匹配。Built-in管线下用StandardURP下用Universal Render Pipeline/LitHDRP下用HDRP/Lit。遇到紫球先改Shader试试基本能治愈。贴图花或者接缝明显则分两种情况。一种是贴图文件本身不是等距圆柱投影比如你拿了一张墨卡托投影的地图贴到球体上之后纬度越高拉伸越严重甚至能看到明显的两极褶皱。这种问题只能换图解决去下载2:1的Day Map专用贴图。另一种是贴图左右接缝处颜色对不上地球从接缝处裂开了。这是贴图本身在180度经线处颜色不连续导致的解决方式是用Krita或Photoshop把图左右各偏移一半用修复画笔把接缝修掉再偏移回来。5.4 顺手补充的三个细节速度参数、双脚本叠加与控制台习惯最后补充三个容易出现但在文档里不太起眼的点。第一rotateSpeed用[SerializeField, Range(0f, 200f)]限制之后Inspector里会直接出现一个滑条拖动比输入数字方便得多。但如果你把上限设成200手一抖调到150球会转得肉眼根本看不清纹理看起来就像花屏。一般情况下10到30是舒适区间。第二检查某个物体上是不是挂了不止一个EarthRotation脚本。我在实际项目里挂重过一次结果转速翻倍我还以为是斜率搞错了查了半天才发现是脚本拖了两次。建议每次挂完脚本都看一眼Inspector确认只挂了一份。第三养成Play前看Console、Play中看Transform的习惯。看Transform里Rotation数字是不是连续变化比看画面更直观排查效率能提高很多。做这种小项目最磨人的不是功能实现而是明明每一步都对球却不转的挫败感。我自己的习惯是第一次转起来之后不要急着加星空和特效先Play模式下拖动相机绕球转一圈确认旋转轴、光照角度、贴图接缝都没问题再做后续扩展。这个套路其实不只是地球能用——所有旋转展示类场景零件展示、卫星绕行、机械臂动画都是同一套思路。等你想清楚了父物体摆倾斜、子物体做自转的分层结构之后以后遇到任何3D展示需求都不用慌改改转速和轴向量就能复用整套方案。