1. 项目概述
在Unity3D中创建一个可交互的3D地球模型是一个既有趣又实用的练习项目。这个项目不仅能帮助我们熟悉Unity的基本操作流程,还能掌握3D对象创建、材质应用、脚本编写等核心开发技能。通过这个教程,你将学会如何从零开始构建一个可以旋转、缩放和自由观察的地球模型。
这个项目特别适合Unity初学者和3D开发爱好者。无论你是想为游戏添加一个精美的地球场景,还是单纯想学习3D交互开发,这个教程都能为你提供实用的指导。最终效果是一个逼真的地球模型,支持鼠标右键旋转视角、滚轮缩放,以及自动旋转功能。
2. 环境准备与基础设置
2.1 Unity项目创建
首先,我们需要创建一个新的Unity项目。打开Unity Hub,点击"New Project"按钮,选择"3D Core"模板。建议使用较新的Unity版本(如2021 LTS或更高),以确保所有功能都能正常工作。
项目命名可以设为"RotatingEarth"或其他你喜欢的名称。创建项目后,Unity会自动生成一个包含Main Camera和Directional Light的默认场景。我们将在SampleScene基础上进行开发。
2.2 资源准备
在开始创建地球前,我们需要准备一张高质量的地球贴图。可以在网上搜索"earth texture map"找到合适的图片,建议选择4096×2048或更高分辨率的贴图以获得更好的视觉效果。将下载的图片保存为earth.png或earth.jpg格式,然后拖入Unity项目的Assets文件夹中。
提示:选择贴图时,最好找一张包含云层效果的图片,这样地球看起来会更加真实。NASA等机构提供了一些高质量的免费地球贴图资源。
3. 创建地球模型
3.1 创建基础球体
在Hierarchy面板中,右键点击SampleScene,选择"3D Object"→"Sphere"创建一个球体。创建完成后,将其重命名为"Earth"。
选中Earth对象,在Inspector面板中找到Transform组件。将Position和Rotation的X/Y/Z值都设为0,确保地球位于场景中心。然后点击Scale前面的锁链图标,使三个轴向的缩放比例相关联,将Scale值统一设为2,这样地球会有一个合适的大小。
3.2 应用地球材质
接下来,我们需要为球体创建并应用地球材质。在Project面板中,右键点击Assets文件夹,选择"Create"→"Material",将新材质命名为"Earth_Mat"。
选中Earth_Mat材质,在Inspector面板中找到"Base Map"(在旧版Unity中可能显示为"Albedo")。将之前准备的earth贴图拖拽到Base Map的槽中,或者点击槽旁边的圆点选择earth贴图。
注意:确保贴图的Texture Type设置为"Default",并勾选"sRGB"选项(这些通常是默认设置)。如果贴图看起来模糊,可能需要调整Max Size设置。
最后,将Earth_Mat材质拖拽到Hierarchy中的Earth对象上,或者选中Earth后在Inspector的Mesh Renderer组件中将材质替换为Earth_Mat。现在你应该能看到一个带有地球贴图的球体了。
4. 实现摄像机控制
4.1 创建摄像机控制脚本
为了让用户能够自由观察地球,我们需要编写一个摄像机控制脚本。在Project面板中右键点击Assets文件夹,选择"Create"→"C# Script",将其命名为"camCtrl"。
双击camCtrl脚本打开编辑器,替换默认代码为以下内容:
csharp复制public class camCtrl : MonoBehaviour
{
public Transform target; // 目标对象(地球)
public float dist = 5f; // 初始距离
public float xSpeed = 120f; // 水平旋转速度
public float ySpeed = 120f; // 垂直旋转速度
public float zoomSpeed = 50f; // 缩放速度
float x, y; // 旋转角度
void Start()
{
// 初始化旋转角度
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
}
void LateUpdate()
{
if (Input.GetMouseButton(1)) // 右键拖拽旋转
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
}
// 滚轮缩放
dist -= Input.GetAxis("Mouse ScrollWheel") * zoomSpeed * 0.1f;
dist = Mathf.Clamp(dist, 1, 20); // 限制缩放范围
// 计算新的位置和旋转
Quaternion rotation = Quaternion.Euler(y, x, 0);
Vector3 position = rotation * new Vector3(0, 0, -dist) + target.position;
// 应用变换
transform.rotation = rotation;
transform.position = position;
}
}
4.2 配置摄像机
保存脚本后,回到Unity编辑器。在Hierarchy中选中Main Camera对象,将camCtrl脚本拖拽到Inspector面板底部,为摄像机添加该组件。
在camCtrl组件的参数中:
- 将Target设置为Earth对象(可以拖拽Hierarchy中的Earth到Target槽,或点击右侧圆点选择Earth)
- 根据需要调整dist(初始距离)、xSpeed/ySpeed(旋转速度)和zoomSpeed(缩放速度)参数
现在按下Play按钮运行游戏,你应该能够:
- 按住鼠标右键拖动来旋转视角
- 使用鼠标滚轮缩放
- 从各个角度观察地球
5. 实现地球自转
5.1 创建自转脚本
为了让地球更加真实,我们需要添加自转功能。创建一个新的C#脚本,命名为"EarthRot"。
打开EarthRot脚本,替换为以下代码:
csharp复制using UnityEngine;
public class EarthRot : MonoBehaviour
{
[Header("deg/s, 可负值倒转")]
public float speed = -15f; // 15°/秒 ≈ 24h 一圈
void Update()
{
transform.Rotate(0, speed * Time.deltaTime, 0, Space.Self);
}
}
5.2 应用自转脚本
保存脚本后,在Hierarchy中选中Earth对象,将EarthRot脚本拖拽到Inspector面板为其添加组件。
speed参数控制自转速度:
- 默认值-15表示每秒逆时针旋转15度
- 正值表示顺时针旋转
- 计算:360°/24小时 = 15°/小时 ≈ 0.00417°/秒,但这样太慢了,所以放大到15°/秒
运行游戏,现在地球应该会自动旋转了。你可以随时在Inspector中调整speed值来改变旋转速度。
6. 优化与发布设置
6.1 窗口模式设置
默认情况下,Unity游戏会以全屏模式运行。为了方便测试和演示,我们可以设置为窗口模式:
- 点击菜单栏的"Edit"→"Project Settings"
- 选择"Player"→"Resolution and Presentation"
- 将"Fullscreen Mode"改为"Windowed"
- 勾选"Resizable Window"选项
这样游戏运行时将显示为可调整大小的窗口,而不是全屏。
6.2 光照与阴影优化
为了获得更好的视觉效果,我们可以调整光照设置:
- 在Hierarchy中选中Directional Light
- 在Inspector中调整Rotation,使光线以一定角度照射地球(如X:50, Y:-30, Z:0)
- 调整Intensity(强度)和Color(颜色)使光照更自然
- 启用Shadow Type为"Soft Shadows"以添加柔和阴影
6.3 添加背景
为了让场景更完整,我们可以添加一个星空背景:
- 创建一个新的材质"Skybox_Mat"
- 将其Shader改为"Skybox/6 Sided"
- 添加6张星空贴图到各个面(或使用Unity内置的天空盒)
- 在菜单栏选择"Window"→"Rendering"→"Lighting"
- 在Environment标签下,将Skybox Material设置为你创建的材质
7. 常见问题与解决方案
7.1 贴图显示问题
问题:地球贴图显示模糊或拉伸
- 原因:贴图导入设置不正确
- 解决方案:
- 在Project面板中选中earth贴图
- 在Inspector中确保Texture Type为"Default"
- 检查Wrap Mode是否为"Repeat"
- 调整Max Size为贴图原始分辨率或更高
7.2 摄像机控制不流畅
问题:摄像机旋转或缩放不流畅
- 原因:速度参数设置不当或帧率不稳定
- 解决方案:
- 调整camCtrl脚本中的xSpeed/ySpeed/zoomSpeed参数
- 确保使用Time.deltaTime进行与帧率无关的运动计算
- 在Quality Settings中调整图形质量以获得稳定帧率
7.3 自转速度不准确
问题:地球自转速度不符合预期
- 原因:speed值计算错误或Time.deltaTime使用不当
- 解决方案:
- 检查EarthRot脚本中的speed值
- 确保在Update中使用Time.deltaTime
- 计算公式:实际速度 = speed × Time.deltaTime
7.4 性能优化建议
对于更复杂的场景或移动平台,可以考虑以下优化:
- 使用适当分辨率的贴图(不必过高)
- 简化阴影质量
- 考虑使用LOD(细节层次)系统
- 对静态对象启用"Static"标记以允许Unity进行优化
8. 扩展功能建议
8.1 添加标记点
可以在球体表面添加城市或地标标记:
- 创建小Sphere作为标记点
- 使用经纬度计算其位置
- 添加鼠标悬停或点击事件
8.2 昼夜变化效果
通过调整光照和材质实现:
- 添加第二个平行光模拟太阳
- 根据自转角度调整光照强度
- 使用Shader实现昼夜分界线效果
8.3 大气层效果
创建半透明球体包裹地球:
- 创建稍大的Sphere对象
- 使用透明材质和特殊Shader
- 添加光晕或散射效果
8.4 云层动画
让云层独立于地表移动:
- 使用第二张贴图作为云层
- 创建双层材质或使用Shader混合
- 以不同速度旋转云层
在实际项目中,我发现调整自转速度时,15°/秒的默认值虽然视觉效果不错,但若追求真实比例,可以设置为0.00417°/秒(即真实地球自转速度)。不过这样旋转会非常缓慢,可能需要添加加速功能。另一个实用技巧是在摄像机脚本中添加平滑阻尼效果,使视角移动更加自然流畅。