10分钟在Unreal Engine中搭建可交互3D地球与城市漫游

发布时间:2026/8/6 19:13:30
10分钟在Unreal Engine中搭建可交互3D地球与城市漫游 1. 项目概述与核心价值最近在社区里看到不少朋友对Cesium for Unreal这个插件感兴趣但一上手就被它庞大的功能体系和复杂的空间坐标系给整懵了。很多人问不就是想快速在虚幻引擎里放个地球然后飞过去看看某个城市吗有没有一个最直接、最不绕弯子的方法今天这个“地球仪”小Demo就是针对这个需求来的。它的目标极其明确在10分钟内从一个空白的Unreal关卡开始搭建出一个可以交互的3D地球并实现从太空视角到芝加哥城市上空的动态漫游。这听起来像是个玩具但对于想快速验证想法、制作原型或者给客户展示地理空间概念的开发者来说这种“最小可行产品”的构建能力至关重要。Cesium for Unreal的核心价值在于它将专业级的全球地理空间数据与虚幻引擎顶级的实时渲染能力无缝结合。你不用再去折腾复杂的地理服务器、处理海量的高程和影像切片Cesium ion云端服务或自托管方案已经为你准备好了现成的、不断更新的全球3D Tiles数据。通过这个插件你可以像调用本地资产一样在虚幻编辑器里直接拖拽出整个地球并基于真实的地理坐标放置你的模型、角色和特效。这对于数字孪生、模拟训练、城市规划、影视预演等领域是一个效率上的飞跃。这个Demo虽然简单但它完整地走通了“数据接入 - 场景搭建 - 交互控制”的核心链路是理解整个工作流的最佳切入点。2. 环境准备与插件安装2.1 引擎版本与项目创建工欲善其事必先利其器。首先确保你有一个可用的Unreal Engine 5环境。经过实测UE 5.2至5.4的版本与当前主流的Cesium for Unreal插件兼容性最好。我强烈建议使用5.3或5.4它们在Nanite虚拟几何体和Lumen全局光照方面更加稳定这对后续加载大规模城市模型至关重要。打开Epic Games启动器安装或切换到对应版本的引擎。创建一个新项目时选择“游戏”模板下的“空白”项目。项目设置里暂时不需要启用任何初学者内容包因为我们所有的核心资产都将来自Cesium。给项目起个名字比如“CesiumGlobeDemo”路径不要有中文或特殊字符。这里有个小技巧在创建项目时直接选择“包含C”即使你打算主要用蓝图开发。这是因为Cesium插件的一些底层功能需要C项目模块的支持提前勾选可以避免后续手动添加的麻烦。当然如果你确定只用蓝图也可以先创建纯蓝图项目后续在编辑器里“添加C类”来转换项目类型。2.2 Cesium插件安装与配置插件安装有两种主流方式各有利弊。第一种是通过Epic商城安装推荐给大多数用户在虚幻编辑器中点击菜单栏的“编辑” - “插件”在打开的插件浏览器窗口的搜索框里输入“Cesium”。你应该能看到“Cesium for Unreal”插件。直接勾选其右侧的复选框编辑器会提示重启。重启后插件就安装并启用了。这种方式最省心版本管理由Epic商城负责适合快速开始。第二种是通过GitHub源码编译安装适合需要定制或开发插件的用户你需要先克隆Cesium for Unreal的GitHub仓库到本地。然后将克隆下来的整个插件文件夹通常名为“CesiumForUnreal”复制到你项目的“Plugins”目录下。如果项目没有“Plugins”文件夹就在项目根目录.uproject文件所在目录下自己创建一个。之后右键点击项目的.uproject文件选择“Generate Visual Studio project files”来重新生成解决方案。用Visual Studio打开.sln文件编译整个项目。编译成功后启动编辑器同样在插件管理器中启用Cesium for Unreal。这种方式能让你用到最新的特性但可能会遇到编译依赖问题对新手挑战较大。插件启用后你会在虚幻编辑器的内容浏览器左侧看到新增的“Cesium”文件夹里面包含了插件自带的各种资产、材质和地图。同时在模式面板通常位于视口左侧的“放置Actor”区域你会找到“Cesium”分类里面就是我们可以拖入场景的核心组件了。注意首次使用Cesium插件它会提示你配置Cesium ion访问令牌。你需要注册一个Cesium ion账户有免费额度并在账户设置中创建一个新的访问令牌。将这个令牌填入插件设置中这是你访问全球3D Tiles数据服务的“钥匙”。没有它地球将是一片灰色。3. 从零搭建基础地球场景3.1 创建空白关卡与添加Cesium World Terrain启动编辑器后我们从一个完全空白的关卡开始。首先删除默认的地面网格和天空球等所有初始Actor。然后进入“放置Actor”面板的“Cesium”分类找到“Cesium World Terrain”Actor将其拖拽到场景中。当你松开鼠标时奇迹发生了——一个完整的、覆盖着基础卫星影像的3D地球瞬间出现在你的视口中。这个“Cesium World Terrain” Actor是整个场景的基石。它负责从Cesium ion服务流式加载全球的地形高程数据和基础影像。在细节面板中你可以看到它的关键属性Origin Latitude/Origin Longitude/Origin Height: 这是场景的“本地原点”坐标。为了简化数学计算、避免浮点数精度问题Cesium for Unreal会以这个点作为Unreal世界坐标系的原点(0,0,0)。对于我们的地球仪Demo保持默认的(0,0,0)即可这意味着地理经纬度(0,0)的点对应Unreal世界的(0,0,0)。Enable Water Mask: 勾选此项Cesium会尝试渲染海洋水面效果。对于全球视图建议开启能让地球看起来更真实。Material: 这里可以指定地形使用的材质。默认材质已经足够好但后期我们可以创建自定义材质来实现更复杂的效果比如根据海拔着色。拖入后你可能需要按“F”键聚焦到该Actor上或者手动调整视角。由于地球尺度巨大默认的编辑器摄像机可能“嵌”在地球内部。一个快速调整的方法是在World Outliner中选中“CesiumWorldTerrain”然后在视口右上角的“透视”下拉菜单中选择“从上往下看”再按“F”聚焦你就能获得一个清晰的全球俯瞰视图了。3.2 叠加高精度影像与地形细节基础地形有了但默认的卫星影像可能分辨率不够高或者不是你想要的区域。这时我们需要添加“Cesium Cartographic Polygon”和“Cesium 3D Tileset”来增强特定区域的细节。添加高精度影像在“放置Actor”的Cesium分类下找到“Cesium Cartographic Polygon”。拖入场景后在细节面板中你需要为它指定一个“Polygon”数据源。简单的方法是使用“Cesium Polygon Editor”点击“Edit Polygon”按钮会在场景中生成一个可编辑的平面多边形。你可以拖动它的顶点在球面上圈出你关心的区域比如整个北美洲。然后在“Raster Overlay”属性中点击加号添加一个覆盖层。从下拉菜单中你可以选择Cesium ion提供的各种影像源例如“Bing Maps Aerial”提供全球航拍图“Sentinel-2”提供卫星影像。选择后这个多边形区域内的影像就会被替换为更高清或更特定的图层。添加3D城市建筑以芝加哥为例这才是让场景“活”起来的关键。在“放置Actor”面板找到“Cesium 3D Tileset”并拖入场景。在它的细节面板找到“Url”属性。这里就是输入特定3D Tiles数据源的地方。Cesium ion提供了许多城市的开源3D建筑模型。对于芝加哥一个可用的公开数据源URL是https://assets.cesium.com/开头的特定标识符具体标识符需在Cesium ion资产库中查找。更直接的方法是使用Cesium ion的“Cesium OSM Buildings”全球开源建筑数据集但加载全球建筑数据量太大。我们可以通过“Source Type”选择“Cesium ion”然后在“Cesium ion Asset ID”中填入芝加哥区域对应的资产ID。如何找到这个ID你需要登录Cesium ion网站在“我的资产”中浏览或搜索“Chicago”找到对应的3D Tiles资产其详情页会提供用于Unreal的资产ID。添加后你可能需要等待片刻取决于网速芝加哥的3D建筑模型就会逐渐从地面“生长”出来。由于数据是流式加载的你会看到建筑从粗糙的块状逐渐细化成带窗户和纹理的精细模型这个过程本身就很有未来感。4. 构建动态漫游摄像机系统4.1 设计摄像机运动逻辑一个静态的地球仪没什么意思我们要的是“飞过去”的体验。在Unreal中实现动态漫游核心是控制摄像机或代表摄像机的Pawn的运动。我们将创建一个蓝图类来实现这个功能。首先在内容浏览器中右键选择“蓝图类” - 以“Pawn”为父类创建命名为“BP_GlobeCameraPawn”。打开这个蓝图我们需要为其添加移动组件。在组件面板中添加一个“Spring Arm”组件命名为“SpringArm”然后在Spring Arm下添加一个“Camera”组件命名为“Camera”。Spring Arm的作用类似于自拍杆可以让摄像机与Pawn主体保持一定距离并在碰撞时自动收缩避免穿模。摄像机的运动逻辑我们打算这样设计全局缩放滚轮通过鼠标滚轮控制Spring Arm的长度实现拉近俯冲和拉远升空的效果。绕点旋转鼠标拖动按住鼠标右键并拖动时让Pawn也就是地球上的观察点绕其正下方的地球表面点进行旋转从而改变观察的经纬度和角度。这比直接旋转摄像机更符合地理空间的交互直觉。平滑移动WASD/箭头键通过键盘输入让Pawn在地球表面进行前后左右的平移。这里的难点在于在地球曲面上“前后左右”是沿着球面的切线方向运动需要将输入向量转换到Pawn的本地切平面坐标系。4.2 蓝图节点实现详解打开“BP_GlobeCameraPawn”的事件图表我们来逐一实现上述功能。1. 全局缩放在“事件图表”中右键搜索并添加“InputAction Mouse Wheel Up”和“InputAction Mouse Wheel Down”事件。对于“Mouse Wheel Up”事件拖出SpringArm组件的引用获取其“Target Arm Length”当前值然后减去一个增量如50000再使用“Set Target Arm Length”节点设置回去。为了有平滑的阻尼效果不要直接设置而是使用“Interp To”节点进行插值将当前长度插值到目标长度插值速度可以设为10.0。“Mouse Wheel Down”事件同理只是将减去增量改为加上增量。别忘了给“Target Arm Length”设置一个最小值和最大值例如最小值1000最大值10000000防止摄像机钻入地心或飞到外太空。2. 绕点旋转鼠标拖动这需要用到鼠标的“Mouse X”和“Mouse Y”轴输入。添加“InputAxis LookRight”和“InputAxis LookUp”事件。在“LookRight”事件中我们想要实现绕地球法线的水平旋转。获取Pawn自身的“Get Actor Rotation”然后将其Yaw偏航角加上输入值乘以一个旋转速度系数如0.5。使用“Set Actor Rotation”节点应用新的旋转。注意这里旋转的是Pawn自身摄像机通过SpringArm跟随从而实现了以Pawn为支点的环绕观察。“LookUp”事件稍微复杂它控制摄像机的俯仰。我们不能直接旋转Pawn的Pitch因为那会导致Pawn倾斜。正确的做法是旋转SpringArm组件自身的相对旋转。获取SpringArm的“Relative Rotation”调整其Pitch值同样加上输入值乘以速度系数但通常为负值因为鼠标向上拉是抬头并限制在一个合理范围内如-80到10度然后“Set Relative Rotation”。3. 平滑移动WASD添加“InputAxis MoveForward”和“InputAxis MoveRight”事件。这是最核心也最容易出错的部分。我们不能直接用输入值去“Add Actor World Offset”因为那是在世界空间直线移动会直接飞离地球。正确思路我们需要计算Pawn当前位置在地球球面上的切平面然后在这个平面内移动。步骤 a. 获取Pawn的世界位置Get Actor Location。 b. 将这个位置向量单位化得到从地心指向Pawn的法线向量。 c. 根据输入的前向值MoveForward我们想要的是Pawn“面前”的方向在切平面上的投影。获取Pawn的“Get Actor Forward Vector”然后使用“Project Vector On Plane”节点将其投影到垂直于法线向量的平面上得到切向前向量。对这个向量进行归一化。 d. 同理根据输入的右向值MoveRight获取Pawn的“Get Actor Right Vector”投影到同一平面得到切向右向量。 e. 将前向输入值 * 切向前向量 右向输入值 * 切向右向量得到一个切平面内的移动方向向量。 f. 将这个方向向量乘以移动速度和Delta Seconds得到本帧的位移量。 g. 将Pawn的当前位置加上这个位移量得到一个新的目标位置。但是这个新位置可能偏离了地球表面。我们需要将其重新投影到地球表面。将目标位置向量单位化然后乘以地球半径Cesium World Terrain的半径通常是Ellipsoid.WGS84.getMaximumRadius()约6378137米。这一步是关键它保证了Pawn始终贴在地球表面。 h. 最后使用“Set Actor Location”并勾选“Sweep”进行碰撞检测让Pawn平滑地“走”到新的球面位置。实操心得这个球面移动算法是Demo的精华也是新手最容易卡住的地方。建议单独创建一个函数“CalculateSurfaceMovement”来封装这些步骤使蓝图更清晰。调试时可以打印出法线向量、切向向量和最终位移量确保计算逻辑正确。5. 实现芝加哥定位与自动飞行5.1 地理坐标与虚幻世界坐标的转换我们已经可以手动操控摄像机在地球上漫游了但如何让它精确地飞到芝加哥上空呢这就需要用到Cesium提供的坐标转换工具。Cesium for Unreal的核心优势之一就是它内置了高精度的地理坐标经纬度高程与虚幻引擎本地坐标厘米之间的双向转换功能。在蓝图中我们可以通过“Cesium Geographic Coordinates”和“Cesium Cartesian Coordinates”相关的节点来完成这个任务。假设我们知道芝加哥市中心的经纬度大约是41.8781, -87.6298海拔高度我们设为1000米便于俯瞰。步骤一定义目标地理坐标在蓝图中我们可以创建一个“CesiumGeoreference”类型的变量通常场景中会自动有一个或者通过“Get Cesium Georeference”节点获取场景中唯一的Georeference Actor。这个Actor管理着整个场景的坐标转换基准。步骤二转换到虚幻坐标使用“Transform Longitude Latitude Height Position to Unreal”节点。这个节点需要输入Target连接到上一步获取的CesiumGeoreference。Longitude Latitude Height一个结构体填入-87.6298, 41.8781, 1000.0。注意Cesium的惯例是经度纬度高度。节点的输出就是对应的Unreal世界坐标系下的FVector位置。步骤三应用位置将得到的FVector位置设置给我们的“BP_GlobeCameraPawn”或者直接设置给摄像机。5.2 创建平滑的自动飞行序列直接“闪现”过去太生硬我们需要一个平滑的飞行动画。这可以通过Unreal的“Timeline”或“Lerp线性插值”节点配合“Tick”事件来实现。这里介绍一个用Timeline的直观方法。记录起点和终点在飞行开始时记录摄像机Pawn的当前位置StartLocation和旋转StartRotation。终点位置EndLocation就是上一步转换得到的芝加哥坐标。终点旋转EndRotation可以计算出来例如让摄像机看向芝加哥市中心的地面点经纬度相同高度为0可以使用“Find Look at Rotation”节点。设置Timeline在蓝图中添加一个Timeline组件命名为“FlyToChicagoTimeline”。双击打开添加两条轨道一条浮点型用于位置插值的Alpha值一条向量型用于旋转插值的Alpha值但通常用一条浮点同时控制位置和旋转的插值就够了。将浮点轨道设置为从0到1时长5秒并应用一个“Ease In-Out”的曲线让飞行启动和停止时更平滑。驱动插值在Timeline的“Update”事件中获取当前的浮点输出值Alpha。使用“Lerp (Vector)”节点对StartLocation和EndLocation进行插值Alpha作为插值系数。同样使用“RLerp”旋转插值节点对StartRotation和EndRotation进行插值。应用插值结果将插值得到的新位置和新旋转通过“Set Actor Location and Rotation”节点应用到摄像机Pawn上。同时为了飞行过程中视角自然可以同步调整SpringArm的长度从一个较远的初始值如5000000插值到一个较近的最终值如500000。触发飞行可以创建一个自定义事件“FlyToChicago”或者绑定到一个按键如“F”键。当事件触发时先记录起点然后播放Play这个Timeline。为了让体验更完整你还可以在飞行开始和结束时播放音效或者在飞行过程中用WidgetUMG在屏幕上显示“正在飞往芝加哥...”的文字提示。6. 场景美化与性能优化6.1 光照、大气与后期处理一个默认光照下的地球可能看起来有点“平”。我们可以通过简单的设置大幅提升视觉质量。天空与大气删除关卡中默认的“SkyAtmosphere”和“SkyLight”因为Cesium for Unreal有自己的“Cesium SunSky”组件它能根据真实的地理位置和时间计算太阳位置和大气散射效果更准确。从“放置Actor”的Cesium分类中找到“Cesium SunSky”并拖入场景。在细节面板中你可以调整时间、日期甚至开启“Dynamic Sun”让太阳根据时间自动运动。指数级高度雾添加一个“Exponential Height Fog” Actor。适当调整其密度、起始距离和颜色可以设置为淡蓝色模拟大气边缘能极大地增强场景的纵深感让远处的地平线自然融入天空。后期处理体积添加一个“Post Process Volume”勾选“Infinite Extent (Unbound)”使其影响整个关卡。在里面你可以启用“Auto Exposure”让画面亮度自适应微调“Color Grading”中的饱和度、对比度让影像色彩更鲜艳。最关键的是可以开启“Bloom”泛光效果让太阳和城市灯光产生光晕质感立刻提升一个档次。水体材质如果觉得Cesium默认的水体效果不够好你可以创建一个新的材质使用“CesiumWaterMaterial”作为父类然后自定义水的颜色、波浪法线贴图和反射强度并将其指定给Cesium World Terrain Actor的“Water Material”参数。6.2 3D Tiles流送优化与LOD设置当加载像芝加哥这样的大型3D Tileset时性能是关键。我们需要确保在保持视觉质量的同时帧率依然流畅。调整流送参数选中场景中的“Cesium 3D Tileset (Chicago)” Actor在细节面板中找到“Tileset”部分。Maximum Screen Space Error这是最重要的LOD细节层次控制参数。它定义了像素误差阈值。值越小加载的细节越高性能消耗越大。对于桌面端Demo可以从16开始尝试如果帧率低可以适当调大到32或64。这个值需要根据目标平台和视距动态调整。Maximum Simultaneous Tile Loads同时加载的瓦片数量。增加此值可以加快初始加载速度但会占用更多带宽和内存。默认值通常够用。Preload Ancestors和Preload Siblings勾选这些选项可以让系统预加载当前视图周围以及更粗糙层级的瓦片减少移动时因等待加载造成的卡顿。Show Credits务必勾选这会在地图上显示数据源的归属信息尊重数据提供者的版权要求。视锥体裁剪与遮挡剔除Unreal引擎本身会进行视锥体裁剪。对于Cesium确保“Frustum Culling”是开启的。对于非常密集的建筑群可以考虑在项目设置中启用“Occlusion Culling”但这需要构建光照和遮挡信息对于动态地球场景可能不适用。使用Nanite如果数据支持如果芝加哥的3D Tiles数据是以支持Nanite的格式提供的如GLTF with Mesh Optimizations并且你使用的是UE5.3可以尝试在Tileset的材质上启用Nanite。这能革命性地提升海量几何体的渲染性能。在材质编辑器中勾选材质属性中的“Use with Nanite”并在项目设置中启用Nanite。7. 常见问题与排查技巧实录在实际操作中你几乎一定会遇到下面这些问题。这里是我踩过坑后总结的排查清单。问题现象可能原因排查与解决步骤地球一片灰色没有纹理1. Cesium ion令牌未配置或无效。2. 网络连接问题无法访问Cesium ion服务。1. 检查“编辑”-“插件”-“Cesium for Unreal”-“Settings”中是否已填入正确的“Default Ion Access Token”。2. 尝试在浏览器中打开Cesium ion网站确认网络通畅。重启编辑器。3D建筑模型不显示或显示为方块1. 资产ID或URL错误。2. 数据仍在流式加载中。3. 该区域无3D建筑数据。1. 在Cesium ion网站确认资产ID并检查蓝图或Tileset Actor中的ID/URL是否完全一致包括https前缀。2. 查看屏幕左下角或输出日志是否有“Streaming tiles...”提示。稍等片刻。3. 尝试加载其他知名城市如纽约、东京的资产ID进行对比测试。摄像机移动时抖动或穿入地下1. 球面移动算法中重新投影到球面的半径错误。2. SpringArm碰撞设置不当。3. Tick事件中的计算顺序或DeltaSeconds使用有误。1. 确保用于重新投影的地球半径与CesiumWorldTerrain使用的椭球体最大半径一致~6378137米。2. 检查SpringArm的“Collision Radius”和“Do Collision Test”设置确保其能正确与地形碰撞。3. 在移动计算中务必乘以“Delta Seconds”以使移动速度与帧率无关。将复杂的向量计算封装成函数便于调试和复用。性能帧率FPS过低1. 同时加载的3D Tiles细节过高。2. 后期处理效果开销大。3. 蓝图Tick逻辑过于复杂。1. 逐步调高Tileset的“Maximum Screen Space Error”如从16调到32、64观察帧率变化。2. 暂时禁用“Bloom”、“Color Grading”等后期效果看是否是主因。3. 使用Unreal Insights或内置的Stat命令如stat unit分析性能瓶颈是在GPU还是GameThread。优化蓝图避免在Tick中做每帧都需要的复杂计算可以考虑用Timer间隔执行。地理坐标转换后位置不对1. 经纬度顺序错误。2. 高度基准混淆。3. 没有使用场景中正确的CesiumGeoreference。1.牢记顺序Cesium API通常使用经度纬度高度。很多错误源于把经纬度填反了。2. 高度值是基于WGS84椭球体椭球高还是平均海平面正高Cesium默认使用椭球高。如果你有正高数据需要转换。3. 确保转换节点中“Target”引用的CesiumGeoreference Actor就是场景中管理坐标原点的那个不要用“Get All Actors Of Class”随便抓一个。打包后程序崩溃或地球不显示1. 插件内容未正确打包。2. Cesium ion令牌未包含在打包版本中。1. 在项目设置的“Packaging”中确保“List of maps to include in a packaged build”包含了你的主关卡。并检查“Advanced”下的“Additional Non-Asset Directories to Copy”是否包含了Cesium插件所需的资源目录通常插件会自动处理但需确认。2.这是最常见的打包问题Cesium ion令牌存储在编辑器的配置文件中不会自动打包。你需要在项目的“Config”文件夹下创建一个“DefaultEngine.ini”文件如果已有则编辑在[/Script/CesiumRuntime.CesiumIonServer]部分添加DefaultIonAccessToken你的令牌。或者在运行时通过蓝图UI让用户输入令牌。最后分享一个调试小技巧在场景中放置一个“Cesium Camera Manager” Actor它提供了一个现成的、可切换的摄像机控制器包含了多种漫游模式自由飞行、地球表面锁定等。当你自己的摄像机控制逻辑出问题时可以快速切换到这个管理器来验证是否是Cesium场景本身的问题这能帮你快速定位问题是出在数据流、坐标转换还是你自己的控制逻辑上。这个10分钟的Demo麻雀虽小五脏俱全打通了从数据到交互的全流程。希望它能成为你探索Cesium for Unreal这个强大世界的坚实起点。