
简介基于Unity3D的太阳系模拟项目资源包面向Unity初中级开发者及天文科普爱好者可用于系统学习场景搭建、物理引擎运动模拟、C#脚本控制与UI交互设计等核心环节。压缩包共包含2522个文件以C#脚本242个、meta资源映射542个、info配置656个为主体辅以Shader、预制体、材质贴图、动画片段、程序集定义asmdef及多种编辑器资源整体约77.65MB目录结构完整可直接导入Unity工程进行参考与二次开发。目前已有419人学习参考。资源覆盖了太阳系场景从零搭建的全过程包括行星公转与自转的牛顿万有引力参数设置如椭圆轨道与自转周期、光源阴影调节、自由摄像机控制等并给出了UI信息展示、点击交互等功能的脚本实现与资源组织思路能帮助读者理解如何使用Unity3D完成科学可视化模拟并掌握面向此类项目的中型工程文件管理方法有助于快速理清Unity3D在科学可视化项目中的典型开发路径。1. 从 Unity3D 项目里翻出 MyTestSolarSystem 这个压缩包第一反应大多是好奇打开能看到什么我拆过不少这类教学资源结论很直接——它不是完整的太空游戏而是把「公转、自转、轨道层级、时间缩放」四个 Unity3D 高频知识点揉在一起的场景工程。跑起来你看到太阳在中心发亮几颗行星按不同周期绕太阳走圆周同时每颗球体还在自转。对刚学到 Transform 旋转的新手这是少有的能立刻看到理论变成效果的练手项目对要交课程设计的人把它改成「模拟太阳系」演示也够。前提是你得先搞懂它的层级结构别一上来就乱拖 Inspector。这一篇就按我平时拆包的顺序从场景结构、运动脚本一路说到最容易翻车的几个坑。2. 场景层级与搭建从压缩包到跑通第一次运行2.1 解压后先认一遍目录结构这类教学包解压后通常没有复杂依赖Assets 下主要三个文件夹Scenes 放主场景Scripts 放 C# 脚本Materials 放材质。打开 Unity Hub 时注意版本兼容——如果是 2019 或 2020 版本建的工程用更新的版本打开会有一次升级提示多数情况直接确认就行反过来用旧版本打开新版本工程反而容易出问题。在 Unity 里有两个导入方式一是用 Unity Hub 打开整个文件夹作为工程这时能直接看到场景里的所有物体二是把 Assets 里的内容复制到现有工程再打开场景。常见做法是第一种因为场景里物体之间的引用比如点光源挂在太阳下已经建好不破坏组织关系。我的建议是拿到包先备份再升级尤其要留意 Project 窗口里有没有 Library 文件夹那东西是本地缓存打包给别人的时候通常不带上。打开后你大概率会看到一组这样的物体根节点叫 SolarSystem下面挂了 Sun 和几个以 Planet 开头的中间层。如果作者把结构封装成 Prefab那更省事直接把 Prefab 拖进场景就能用。这一步别急着运行先在 Hierarchy 里把层级结构展开看一遍确认根节点下面有什么因为整个运动逻辑都依赖这套父子关系。2.2 两级节点结构轨道支点与行星本体这里要重点讲清楚「两级节点」的设计。结构大致是这样SolarSystem (0, 0, 0) ├─ Sun ├─ Anchor_Mercury │ └─ Mercury ├─ Anchor_Venus │ └─ Venus └─ Anchor_Earth └─ EarthAnchor 也就是轨道支点位置固定在太阳中心。行星本体挂在支点下面但它的 localPosition 不是 (0,0,0)而是沿 X 轴偏移一段距离这个距离就是轨道半径。当 Anchor 绕 Y 轴旋转时子物体被带着走圆周——这就是 Unity3D 最常用的「父节点旋转带动子节点公转」方案。为什么推荐这个结构而不是在 C# 脚本里每帧算 position两个原因一是性能transform.Rotate 的开销远小于每帧构造 Vector3 再赋值而且不会因为三角函数累积误差导致轨道漂移二是调试友好想在 Inspector 里改轨道半径直接拖子物体 localPosition 的 X 值就行不用打开脚本改常量。缺点是椭圆轨道做不了只能做正圆但对教学场景完全够用。注意一个细节Anchor 和它下面所有子物体的 Scale 必须保持 1:1:1。如果有人在根节点缩放过子物体旋转时往往出现变形。养成习惯打开场景先检查根节点 Transform 的 Scale 是否正常。现在的资源包大多遵守这个约定但保不齐哪次更新误拖了 Scale。2.3 摄像机全局视角与跟随视角默认摄像机的摆放决定了第一眼效果。我建议不要用 Scene 视图直接运行而是在 Hierarchy 里新建一个 CameraPosition 放到 (0, 55, 35)朝向原点这样整个轨道平面都在视野内。FOV 设在 40 到 50 之间数值太小会切掉两侧行星太大则有鱼眼变形。如果要做跟随视角比如跟着地球观察单独挂一个脚本比直接把摄像机拖进地球子物体更好。直接拖进去的话摄像机会跟着子物体一起自转画面会持续晃动这是新手最容易犯的错。写一个 FollowTarget 脚本挂到摄像机上using UnityEngine; public class FollowTarget : MonoBehaviour { public Transform target; public Vector3 offset new Vector3(0f, 8f, -12f); void LateUpdate() { if (target null) return; transform.position target.position offset; transform.LookAt(target); } }逻辑说明Position 取目标点加偏移LookAt 让镜头永远盯着行星中心。用 LateUpdate 而不是 Update是因为 Unity3D 里所有物体的运动都在 Update 阶段完成摄像机如果在 Update 里取值可能取到上一帧的位置画面会出现一卡一卡的感觉LateUpdate 保证在所有物体更新完之后再移动相机这一行差异就是流畅和玄学的分界线。参数说明offset 决定观察距离和角度觉得行星太小就把 Y 值放大或者把 Z 的绝对值减小。target 拖到对应的星球本体上即可。如果还想验证层级搭得对不对可以先手动旋转某个 Anchor 的 Y 轴看行星本体是否沿轨道走要是本体自己在翻转就说明轴没对齐回 2.2 节检查父子结构。3. 公转与自转脚本两级节点的运动学实现与周期换算3.1 用旋转还是位置计算正圆轨道的取舍多数太阳系教学资源有两种实现轨道的方式。第一种是旋转轨道支点上一章已经讲过第二种是在 Update 里实时求坐标float theta speed * Time.deltaTime; transform.position center new Vector3(Mathf.Cos(theta) * radius, 0, Mathf.Sin(theta) * radius);这段代码能跑但有两个隐患一是 theta 无限增长浮点数精度会慢慢丢失运行一两个小时以上轨道会肉眼可见地偏移二是 center 不能是离原点太远的大数值否则同样吃精度。旋转支点的方案里Unity 引擎内部对旋转矩阵做了归一化处理长时间运行更稳定这就是我在教学包里优先推荐的原因。如果是做行星碰撞或者引力效果才需要位置计算因为要拿到精确坐标去检测距离。3.2 公转脚本周期参数与角度换算公转脚本的核心是把「一圈的时间」换算成「度/秒」。Unity 的 transform.Rotate 接口接收的是度数不像数学库默认弧度新手最容易在这搞混。一个完整的公转脚本写法using UnityEngine; public class OrbitMotion : MonoBehaviour { [Tooltip(公转一圈所需秒数60 表示 60 秒转一圈)] public float orbitPeriod 60f; private float degreesPerSecond; void Start() { degreesPerSecond 360f / orbitPeriod; } void Update() { transform.Rotate(0f, degreesPerSecond * Time.deltaTime, 0f, Space.World); } }逻辑说明360f 是一圈的度数除以周期得到角速度再乘 Time.deltaTime 保证旋转速率与帧率无关。旋转轴选择 Y是因为场景的轨道平面是 XZ 平面法线方向就是 Y。把脚本挂到 Anchor 节点上而不是行星本体上——这个区别决定了公转还是自转。这里给出一张以「地球公转 60 秒」为基准的压缩周期换算表教学场景里实测手感最好的一组参数行星真实公转周期(天)压缩后周期(秒)水星88.014.5金星224.722.7地球365.360.0火星687.0112.9木星4332.6375.0土星10759.2930.0别直接拿真实天数填周期太长运行起来像静态图完全看不出轨道运动。教学场景一般把最快那颗压到 15 秒左右肉眼能明显看到差距又不至于晃眼。换算逻辑很简单目标秒数 60 × (该行星天数 / 365.3)取整后微调。3.3 自转脚本与轴倾角自转思路一样但挂在行星本体上旋转轴仍然选 Y使用 Space.Self。这里 Self 和 World 的区别要讲清楚行星本体挂在已经旋转的 Anchor 下面如果仍用 World自转轴会跟着父节点一起倾斜看起来像在翻滚用 Self 则绕自身局部轴转更符合直观using UnityEngine; public class SelfRotation : MonoBehaviour { [Tooltip(自转一圈所需秒数10 表示 10 秒转一圈)] public float rotationPeriod 10f; private float degreesPerSecond; void Start() { degreesPerSecond 360f / rotationPeriod; } void Update() { transform.Rotate(0f, degreesPerSecond * Time.deltaTime, 0f, Space.Self); } }逻辑说明rotationPeriod 给 10 秒在演示里比较有动感但别小于 3 秒否则转太快像广告图。轴倾角比如地球的 23.4 度在资源包里通常被省略。想加的话不要直接在自转脚本里改轴向量而是给行星本体套一层空物体 Pivot把 Pivot 的 X 轴旋转 23.4 度SelfRotation 挂在行星本体上。这样「轴向固定、绕轴自转」的物理关系被拆成了两个 Transform后续调倾角不会污染自转逻辑。我处理其它机械旋转类 Demo比如风扇、轮胎时也惯用这个结构。3.4 运行验证怎么看轨道周期是否正确跑起来以后用手机秒表掐一圈是笨办法更硬核的做法是写个脚本验证。等公转角累计超过 360 度后打印耗时判断周期偏差是否在预期内。这里有个很容易被忽略的点改完 orbitPeriod 后Start 里重新算角速度只会在运行时生效一次如果你在运行状态下从 Inspector 直接改数值不会即时生效。很多新手以为「改了没反应」就是卡在这。要支持运行时热调把角速度计算挪到 Update 里或者用 OnValidateprivate float degreesPerSecond; void OnValidate() { if (orbitPeriod 0f) orbitPeriod 1f; degreesPerSecond 360f / orbitPeriod; } void Update() { if (degreesPerSecond 0f) OnValidate(); transform.Rotate(0f, degreesPerSecond * Time.deltaTime, 0f, Space.World); }逻辑说明OnValidate 在 Inspector 值变化时触发省去手动重开游戏。加一个保护判断防止周期误填成 0 导致除零。这属于实用小技巧源码模板里不一定会给你写但做课程演示时很救场。4. 光照与材质让太阳系看起来不像是色块拼盘4.1 太阳材质Emission 与自发光陷阱在 Unity3D 里做太阳最省的做法是给太阳一个 Standard 材质勾上 EmissionEmission Color 调到接近全白Intensity 给 1 到 3。另一种做法是建一个 Unlit 自发光材质不吃光照更亮但少了层次感。教学包多用前者。有一个经常被忽略的坑Emission 开大了太阳在 Scene 视图里过曝但你放一个 Point Light 后行星受光面正常时才发现太阳本身是「假亮」——它并没有照亮周围。所以正统做法是材质负责外观光照交给单独挂的 Point Light。Light 组件的 Range 必须覆盖最远行星的轨道半径否则边缘行星永远只有暗面。Intensity 给 2 左右、Shadow Type 设 Hard 或 Soft看性能取舍。太阳本体的 MeshRenderer 可以勾掉 Shadow Casting避免自阴影导致表面出现奇怪的黑色斑块。4.2 行星材质颜色、纹理与明暗面没有真实纹理的行星贴图时Standard 材质配一个基础色就够。各行星常用参考色水星偏灰、金星米黄、地球蓝绿、火星砖红、木星棕白相间、土星淡黄。代码方式生成颜色渐变纹理也可以但教学场景里不值当直接用 Material 的 Albedo 改色更直观。明暗面是否正常是检验光照配置的试金石。行星背对太阳的那一面如果完全漆黑说明 Point Light 强度太小或 Range 没盖住如果整颗球亮得像自发光说明 Standard 材质的 Metallic 和 Smoothness 调过头了反光把暗面补亮了。我的经验值是 Metallic 给 0 到 0.2、Smoothness 给 0.3 左右比较接近石质行星的观感。气态巨行星可以适当拉高 Smoothness 到 0.6反光会更有「大气层」的感觉但别全拉到 1。4.3 小行星带与土星环粒子系统的两个使用姿势如果资源包里有小行星带大多是粒子系统用环形轨道发射器粒子数 2000 到 3000 之间Shape 设成 Circle半径与木星和火星之间的小行星带匹配。关键技巧是让发射器跟着公转速度缓慢旋转粒子本身不移动视觉上小行星带在缓慢转动。如果给每个粒子都做物理运动Draw Call 会爆表帧率直线下降。土星环同理可以用一个 Ring Mesh 加透明贴图也可以再开一套粒子系统半径更大、宽度更窄。两套系统的旋转速率差一点看起来更真实。注意粒子材质里的渲染模式设成 Billboard否则从侧面看会变成一条线。这些参数没有固定标准边运行边调 Shape 的 Radius 和 Rotation Speed 就行。4.4 性能检查合批与 Draw Call行星模型大多只有几百个面不必担心面数倒是 Draw Call 容易被忽略。场景里十来个星球各用各的材质就会产生十几次绘制调用。教学场景无所谓但要做到 60 帧稳定有两个免费手段一是把同色的静态物体标记为 Static让 Unity 做静态合批二是把多个小行星共用一个材质实例Unity 会自动合批同材质的物体。这里注意如果给每个行星都用 Create Material Instance合批会被打断因为实例化材质相当于告诉引擎「我的材质和别人的不一样」。所以优化和单独调参是矛盾的我的取舍是主角行星用独有材质背景小行星带统一用一个材质合批效果最明显。5. 避坑专题Unity 太阳系模拟里高频踩到的五个现场5.1 复制行星后所有星球材质一起变色现象选中地球复制出一个新星球改颜色后其它所有行星也跟着变。原因Unity 的材质默认是按引用共享的。复制物体不会复制材质你从 Inspector 修改颜色时操作的是同一个材质文件所有引用它的物体一起变。解决在 Inspector 右上角齿轮菜单里选 Create Material Instance生成独立材质副本再改或者在脚本里用 new Material(originalMat) 复制一份再赋给 MeshRenderer。养成这个习惯操作任何共享资源都要先问一句这个引用是我独享还是大家共用5.2 暂停后恢复星球不转了现象把 Time.timeScale 设成 0 做暂停菜单恢复成 1 后所有旋转停住或者直接跳了一大截。原因有的写法在暂停时驻留了累计角度恢复时 deltaTime 跳变导致计算异常或者用了 unscaledDeltaTime 补帧逻辑混在一起。解决运动统一走 Time.deltaTime不要自己缓存上一帧角度暂停只改 timeScale不动其它逻辑。若要支持暂停时的镜头移动用 unscaledDeltaTime 单独控制摄像机别让它影响旋转逻辑。5.3 行星离原点太远出现抖动现象把轨道半径设成 5000运行平移镜头时球体边缘疯狂抖动像隔了一层热浪。原因Unity 的世界坐标用 float 存储大约 7 位有效数字离原点越远分辨率越低两个相近的大数作差时精度就丢了。解决压缩场景整体比例轨道半径控制在几百单位内前文那张周期表就遵守这个约束或者把太阳和行星的世界坐标整体偏移回原点附近再运行。5.4 公转太快导致残影和穿模现象周期设成 0.1 秒星球像甩鞭子一样拖着残影摄像机完全跟不住。原因每帧旋转角度远大于人的视觉捕捉范围物体移动弧长过大帧与帧之间的位置不连续。解决周期别低于 9 到 10 秒非要高速演示调 Time.timeScale 而不是改周期。这个区别很关键因为 timeScale 会等比例缩放所有运动摄像机也能跟着走而只改周期只会让单颗星球发疯。5.5 行星位置正确但看起来在「摇摆」现象轨道没有错但运行后行星的圆周运动一会儿扁一会儿鼓像在画椭圆。原因根节点或父节点带了非均匀缩放比如 Scale 是 (1, 0.5, 1)旋转矩阵与缩放叠加产生了剪切的视觉效果。解决所有轨道节点的 Scale 保持 1:1:1缩放只放根节点且用统一比例。改星球大小用 localScale 乘一个标量不要在父节点单独拉 X 轴。打开场景先检查一遍三个轴的 Scale 是否一致这是我拆资源包的第一习惯。6. 进阶调参把真实轨道数据压进场景单位而不丢精度真实尺度没法直接搬进 Unity地球轨道约 1.5 亿公里海王星约 45 亿公里直接把公里数当场景单位坐标数值会爆掉 float 精度所有旋转轴都会漂。网上很多资源「看着跟真实差别很大」问题不在脚本在比例尺选错了。使用天文单位 AU 压缩轨道半径是通用做法1 AU 取 10 个场景单位行星半长轴(AU)场景轨道半径(单位)水星0.393.9金星0.727.2地球1.0010.0火星1.5215.2木星5.2052.0土星9.5895.8天王星19.20192.0海王星30.05300.5300 单位还在 float 的合理区间内点光源 Range 给到 350 就能覆盖全场景。但行星本体的视觉半径不要按同一比例木星和地球的半径比约 11 倍按轨道比例缩放的话木星会大到两个场景单位直接挡住后面几十颗行星。常见做法是轨道半径严格按 AU 比例球体半径单独按显示需要缩放教学演示都这么处理别被「真实感」带偏。时间轴同样要压缩地球一圈 60 秒其它行星按「真实公转天数 / 365.3 × 60 秒」计算就是第三章那张表的来源。自转周期可以统一给 8 到 12 秒真实自转差异在教学演示里不明显强行按真实比例会让部分行星慢到看不出在转。验证方法也很简单跑起来后给地球轨道打个空物体标记用秒表掐一圈看是不是 60 秒左右然后把摄像机设到海王星外围Position 用 (0, 20, 320)LookAt 太阳确认最远轨道在视野内。我从那以后每次拿到这类资源第一件事就是检查根节点 Scale 是不是 1、轨道半径是不是百量级再谈颜色和光照。这套检查流程救过我好几次项目交付希望帮到你。本文还有配套的精品资源点击获取