主题
3D 场景创建、SpaceModel 与场景产物
本文档说明如何在编辑器中创建和配置 3D 场景,什么时候选择 Surface2D / Volumetric3D,以及为什么 3D 场景需要手动生成体素、导航和碰撞等场景产物。
如果还不确定项目是否应该使用 SCE 场景和 Unit/技能系统,先读 游戏架构路线、SCE 场景空间模型与 Canvas/GameGraph 边界。直接用 SceneGraph / Node 构造的 GameGraph 游戏,或纯 Canvas/GameUI 游戏,不一定需要本文档里的 SCE 场景流程。
运行时代码层面的 Scene.Load()、ScenePoint、空间查询见 场景系统。单位控制器、物理角色和 locomotion 见 3D 单位移动控制器。
角色模型尺寸先按厘米统一
星火编辑器的 3D 世界采用厘米制:1 个世界单位等于 1 厘米。制作或导入角色模型时,1.8 米高的人形角色应在编辑器中表现为约 180 高,而不是 1.8。角色模型、骨架、动画、挂点和附加模型应保持同一单位与比例,标准资源优先保持缩放为 (1, 1, 1)。
FBX 导入为了兼容既有资源,默认不会只凭文件中的单位元数据自动完成米到厘米换算。建议在 DCC/导出阶段直接使用厘米,或在导出前完成 100 倍换算,并在导入后检查模型包围盒高度。如果模型和动画明确按照 Unity 的 Y 轴向上、左手系和米制约定制作,可以在导入时选择“使用 Unity3D 规格”;模型和独立动画应保持相同选择。模型尺寸、物理胶囊和单位碰撞半径是独立配置,不要只看模型高度推断碰撞已经正确。完整说明见 WasiCore 3D 坐标系统指南。
推荐工作流
1. 新建项目时选择 3D 模板
如果当前编辑器版本的项目模板列表里已经开放 3D 相关模板,优先从模板创建项目。3D 模板通常会预置:
- 适合 3D 玩法的默认场景和相机。
- 3D 单位示例或主控单位数据。
GameDataUnit.MovementController、JumpLaunchSpeed、ExtraAirJumps等 3D 控制器相关预设。- 调试 UI 或 overlay 示例,用于验证导航、体素、物理世界和 character motor。
模板只负责给项目一个起点。新建或复制出来的每一个场景仍然需要单独检查 SpaceModel,并在修改 3D 地形或阻挡后重新生成 3D 场景产物。
2. 新建场景时选择 SpaceModel
新建场景时应根据玩法选择空间模型:
| 选择 | 适合 | 不适合 |
|---|---|---|
Surface2D | 普通俯视角、单层地表、坡面、高台、地形有 Z 高度但同一 XY 只有一层可走面 | 同一 XY 有桥洞、上下楼层、多层平台,或需要 Unit 物理角色模式 |
Volumetric3D | 多层地表、桥、隧道、上下平台、物理角色、3D 导航 | 只是画面是 3D 但玩法仍是单层地表的普通地图 |
SpaceModel 是寻路、高度和碰撞语义,不是渲染维度开关。Surface2D 场景仍然可以渲染 3D 地形、模型、粒子和光照;它只是把单位移动解释为 2.5D 单层地表。
3. 在地形编辑器属性面板检查场景属性
打开地形编辑器,不选中任何单位、物品、区域或装饰物时,右侧属性面板会显示当前场景属性。常用项:
| 属性 | 建议 |
|---|---|
| 场景名 | 写入 GameDataScene.Name,用于左侧场景列表显示。 |
| SpaceModel | 3D 物理角色或多层导航选择 Volumetric3D;普通单层地表选择 Surface2D。 |
| 尺寸(格) | 显示为地编格数,保存时按每格 256 世界单位写入 GameDataScene.Size。 |
| 包边 | 决定地形边界碰撞;不希望角色走出地图时应配置。 |
| 渲染环境 | 控制运行时是否渲染地形、装饰等静态环境。 |
| Vision | 正常视野、全开视野或精确视野,可独立于 SpaceModel 配置。 |
更完整的属性说明见 地形编辑器场景属性面板。
4. 生成 3D 场景产物
Volumetric3D 场景依赖额外生成产物。修改相关内容后,需要手动重新生成。常见入口:
- 地形编辑器右侧场景属性面板中的“生成3D场景产物”按钮。
- 顶部菜单“场景 -> 生成3d场景资产”。
- 左侧场景列表中右键场景名,选择生成 3D 场景资产的菜单项。
需要重新生成的典型情况:
- 新建或切换为
Volumetric3D场景。 - 修改地形高度、尺寸或可走面。
- 修改静态阻挡、碰撞角色、包边或会影响导航/物理的装饰物。
- 修改桥、隧道、楼层、坡道、台阶等多层结构。
- 发布或远端调试前,想确认本地场景产物是最新的。
生成产物包括 3D 体素、导航网格、静态阻挡和物理碰撞等内部数据。不要手工编辑这些二进制/派生文件,应通过编辑器重新生成。
生成完成后,可以打开调试 overlay 验证:
| Overlay | 用途 |
|---|---|
Nav3DMesh | 查看 3D 导航网格是否生成并覆盖可走区域。 |
Nav3DVoxels | 查看体素数据是否存在。 |
PhysicsWorld | 查看物理世界和碰撞体。 |
MotorProbe | 查看物理角色 motor 的落地、碰撞和移动探测。 |
如果在地形编辑器里看到半透明导航网格,通常表示 Nav3D 产物已生成。
2.5D 与 3D 的实际区别
Surface2D:2.5D 单层地表
SceneSpaceModel.Surface2D 的核心特点:
- 单位移动按 XY 平面上的单层可走面处理。
- 场景可以有高度、坡面、高台和 3D 模型。
- 同一 XY 位置只有一层有效地表。
- 适合传统 RTS、MOBA、塔防、生存刷怪等俯视角玩法。
- 运行成本和数据复杂度更低,普通 3D 画面不必为了“看起来是 3D”就切到
Volumetric3D。
Volumetric3D:真 3D 多层空间
SceneSpaceModel.Volumetric3D 的核心特点:
- 同一 XY 位置可以有多层可走面,例如桥上/桥下、楼上/楼下。
- 使用 3D 体素、导航网格和静态碰撞产物。
- 支持
UnitMovementMode.VolumetricNavigation。 UnitMovementMode.PhysicalCharacter只在该空间模型下激活。- 更依赖正确的场景产物生成和调试 overlay 验证。
如果不确定,先问一个问题:玩家或 AI 是否需要在同一水平位置的不同高度层独立移动?如果答案是否,通常先用 Surface2D。
3D 场景下的单位移动模式
Volumetric3D 只决定场景空间语义;单位具体如何移动由 GameDataUnit.MovementController / UnitMovementController 决定。
| 模式 | 适合 | 行为 |
|---|---|---|
VolumetricNavigation | AI 寻路、点击到目标点、沿 3D 导航网格移动 | 导航系统计算路径并移动 Unit;不使用物理胶囊,不提供跳跃/重力手感。 |
PhysicalCharacter | 玩家主控角色、平台跳跃、需要胶囊碰撞/台阶/坡度/重力的角色 | KinematicCharacterMotor 驱动绑定 node,node transform 写回 Unit;接受连续移动输入和跳跃,但不作为普通寻路模式。 |
更具体地说:
VolumetricNavigation可以接受寻路/路径请求,适合“走到某个点”。PhysicalCharacter可以接受连续移动意图,适合 WASD/摇杆实时控制;它不接受普通 pathing 请求,路径移动应先切回导航模式或由项目自己实现高层 steering。- 从
PhysicalCharacter切回导航时,使用unit.ReturnUnitToSceneNavigation(),框架会回到当前场景适用的导航模式。 - 物理角色需要完整的
Volumetric3D场景产物和可用碰撞,否则会出现无法落地、穿透或跳跃状态异常。
完整 API 和示例见 3D 单位移动控制器与 Locomotion。
运行时代码接线
场景创建和资产生成在编辑器中完成;运行时代码只引用生成好的 GameDataScene。
csharp
#if SERVER
var scene = Scene.GetOrCreate(ScopeData.GameDataScene.new_scene);
scene.Load();
var hero = MyLinks.Hero.Data?.CreateUnit(player, new ScenePoint(2048, 2048, scene), new Angle(0));
if (hero != null)
{
player.MainUnit = hero;
}
#endifGameDataGameMode 应把场景加入 SceneList,并设置默认场景:
csharp
_ = new GameDataGameMode(MyLinks.GameMode)
{
SceneList = [ScopeData.GameDataScene.new_scene],
DefaultScene = ScopeData.GameDataScene.new_scene,
};不要在代码里凭空创建地形资产。HostedSceneTag 必须对应项目中已有的 scene/<name>/ 场景资产。
调试清单
3D 场景或物理角色不符合预期时,按顺序检查:
- 当前项目是否来自 3D 模板,或者已正确引用需要的 3D 单位/控制器数据。
- 当前场景的
GameDataScene.SpaceModel是否是预期值。 Volumetric3D场景是否重新生成过 3D 场景产物。- 地形编辑器里
Nav3DMesh是否覆盖可走区域。 PhysicsWorldoverlay 是否能看到静态碰撞。- 使用物理角色时,
MotorProbe是否显示 motor 命中地面。 - 单位是否设置
UpdateFlags.Walkable = true。 - 单位是否配置
GameDataUnit.MovementController。 - 服务端切换物理角色失败时,查看
unit.GetUnitMovementControllerInfo()?.LastTransitionFailureReason。
常见误区
| 误区 | 正确理解 |
|---|---|
“画面是 3D,所以必须用 Volumetric3D。” | 不对。只要移动语义是单层地表,Surface2D 仍可用于 3D 画面。 |
| “用了 3D 模板,所有新场景都会自动是 3D。” | 不一定。每个场景都有自己的 SpaceModel,新建或复制后要单独检查。 |
“切到 Volumetric3D 后马上就能寻路。” | 不一定。需要生成 3D 体素/导航/阻挡等场景产物。 |
| “物理角色可以替代所有寻路。” | 不对。物理角色适合实时控制和跳跃手感;自动走到目标点仍优先用导航模式。 |
| “3D 场景产物可以手工改。” | 不推荐。它们是编辑器生成的派生资产,应通过编辑器重新生成。 |