此页面包含信息,以帮助经验丰富的 Unity 开发者开始使用 Roblox,包括基本的方向、概念比较以及两个平台之间的主要区别。
了解基础


Unity 的 Hierarchy 窗口和 Roblox Studio 的 Explorer 是组织 3D 场景中元素的主要窗口:
- 两者都允许你管理和组织对象(例如,角色和环境资产)。
- 两者都使用树状结构来表示对象之间的父子关系。
然而,Hierarchy 窗口没有预定义的结构,而 Explorer 窗口有一个严格的结构。可以把 Explorer 窗口视为 Unity 的 Hierarchy 和 Project 窗口的组合,Workspace 文件夹作为最显著的元素。
同样,Roblox Studio 的 Asset Manager 和 Toolbox 与 Unity Project 窗口重叠。Asset Manager 让你管理游戏内的所有资产,而 Toolbox 让你访问你已发布的任何资产。Toolbox 还允许你搜索来自 Roblox 或社区的资产 (Creator Store),与 Unity 的 Asset Store 类似。
哲学差异
Roblox 是一个“仿真引擎”,而不是传统的游戏引擎。Unity 的 GameObjects 和 Roblox 的 Parts 都作为创建 3D 环境中对象的基础构件,但在实践中,这两者是相当不同的:
- 表示:Unity 中的 GameObjects 是场景中任何对象的更高级概念,而 Roblox 中的 Parts 旨在表示实际物体,比如木块和塑料球,而不是 Unity 中的抽象几何体。
- 物理:在 Unity 中进行物理仿真时,您将 Rigidbody 和 Collider 等组件附加到 GameObject。在 Roblox 中,物理内置于 Parts 数据类型中;引擎自动处理交互。
如果你创建一个 GameObject 和一个 Part,你会立即看到区别。GameObject 仅具有位置、旋转和缩放。Part 拥有相同的信息——加上材料和颜色、反射率和透明度的值、质量和形状等等。将 Part 转换为更类似于空 GameObject 的东西意味着移除许多内置属性。相反,您可以通过将 MeshFilter、MeshRenderer、Collider 和 Rigidbody 组件添加到 GameObject 上来使其看起来更像 Part。
从脚本的角度来看,GameObject 最类似于 Roblox 的 Instance,这是所有其他 Roblox 类的基础类,但因为你不能(也不需要)创建 Instance 类型的对象,这种比较并不是特别实用。
另一个比较是 Unity 的 GameObject 和 Roblox 的 Model。模型作为一组相互连接的部分的容器,类似于你可能在 Unity 中建立许多 GameObjects 之间的父子关系。你可以指定模型的一个部分作为其 主要部分 以定义 pivot 点。模型也可以包含脚本、动画、音效、提示、约束、粒子发射器等等。
例如,Unity 的 GameObject 可能包含 ParticleSystem、Physics3D、SpringConstraint 和一个脚本。在层次窗口中,你会看到一个名为 SpringyFireball 的单一 GameObject。检查窗口显示组件和属性的集合。
在 Roblox 中,类似的 SpringyFireball 模型在 Explorer 窗口中的样子可能如下所示:
Model|- ParticleEmitter|- MeshPart|- SpringConstraint|- ClickDetector| |- Script
Roblox 的默认物理哲学也延伸到构建 3D 模型的过程。在 Roblox 中,将多个部件焊接在一起形成一个 assembly 是快速构建事物的绝佳方法,因为 Roblox 将焊接的部分视为单一的刚体。这种方法在 Unity 中不可用。
Roblox 使用被称为 studs 和 Roblox 质量单位 (RMUs) 的概念单位,而不是标准的公制单位进行长度和质量的测量。有关大概公制转换和使用建议,请参见 Units。
位置很重要
Roblox 游戏默认是多人游戏,因此 Roblox Studio 包含许多不同的存储位置,并具有特定的行为。有关更多信息,请参见 client-server runtime 和 object organization。
| Location | Description |
|---|---|
| Workspace | 表示游戏的 3D 世界。此位置非常适合直接附加到对象并控制其行为的服务器脚本。 |
| ReplicatedFirst | 包含在其他任何内容之前复制到客户端的对象。此位置非常适合显示加载屏幕所需的绝对最低限度的对象和客户端脚本。 |
| ReplicatedStorage | 包含复制到客户端和服务器的对象。此位置适用于您希望在服务器和客户端上都使用的 ModuleScripts。LocalScripts 不会从此位置运行,但具有 RunContext 为 Client 的 Scripts 会运行。 |
| ServerScriptService | 包含服务器脚本。此位置非常适合需要访问服务器端功能或对象(如游戏逻辑和云存储)的脚本。 |
| ServerStorage | 包含服务器端对象。此位置非常适合那些不需要在客户端加入游戏时立即复制的较大对象。脚本不会从此位置运行,但您可以在此存储服务器端的 ModuleScripts。 |
| StarterPlayer ⟩ StarterCharacterScripts | 包含在角色生成时运行的 LocalScripts。 |
| StarterPlayer ⟩ StarterPlayerScripts | 包含在玩家加入游戏时运行的一般用途 LocalScripts。 |
| StarterGui | 包含客户端在加载游戏时显示的 GUI 元素。LocalScripts 可以从此位置运行。此位置适合用于修改游戏用户界面的脚本,例如添加按钮、菜单和弹出窗口。 |
| StarterPack | 通常仅包含 Tools,但也可以包括用于设置玩家背包的 LocalScripts。 |
脚本编写
Roblox 游戏支持三种不同类型的 Luau 脚本:
客户端脚本
这些脚本在客户端运行,服务器无法看到它们的行为。出于遗留原因,这些脚本可以是 LocalScripts 或 Scripts,其 RunContext 值为 Client。客户端脚本通常位于 ReplicatedStorage、StarterPlayerScripts 或 StarterCharacterScripts 中。
服务器脚本
这些脚本在服务器上运行,客户端无法看到它们的行为。服务器脚本的 RunContext 值为 Server,并通常位于 ServerScriptService 中,该内容不会被复制到客户端。
模块脚本
这些脚本是可重用的代码块,返回一个值,通常是一个函数或表(或一个函数的表)。为了避免在客户端和服务器脚本中重复代码,使用模块脚本在两者之间共享代码和数据。模块脚本通常位于 ReplicatedStorage 中,但如果您想在客户端和服务器之间共享代码,它们也可以放在其他地方。
Unity 没有不同脚本类型的概念。如果你选择制作一个多人游戏,Unity 使用其网络库来指示何时 GameObject(及其脚本)应限于服务器。
在 Unity 中,许多引擎的功能可以通过 MonoBehaviour 的方法访问。例如,要在渲染循环之前运行代码,您需要将代码添加到 Update() 方法中。要处理物理碰撞事件,您需要将代码添加到 OnCollideEnter() 方法中。
Roblox 脚本更具事件驱动性。您通过订阅服务并侦听更新来访问类似的功能。
C# 和 Luau
在脚本编写中,Unity 使用 C#。Roblox 使用 Luau,这是一种源自 Lua 5.1 的脚本语言。
与 C# 相比,Luau 是逐步类型并且通常语法不那么冗长。然而,在较大的项目中,渐进类型可能会引入强类型语言(如 C#)所避免的错误类别,因此请考虑在 Roblox 脚本中启用 严格类型检查。
有关脚本语言之间的基本语法差异,请参见 Luau 和 C# 比较。
Luau 代码示例
以下 Luau 代码示例演示了在玩家装备钓鱼竿后,如何监听用户输入(在这种情况下是 E 键)并调用其他函数:
local ContextActionService = game:GetService("ContextActionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 从 ReplicatedStorage 获取一个返回单个函数的模块脚本
local performSomeAction = require(ReplicatedStorage.performSomeAction)
-- 假设这个脚本是钓鱼竿的子项
local fishingPole = script.Parent
local ACTION_CAST = "Cast"
-- 检查键是否被按下,然后调用另一个函数
local function castLine(_actionName, inputState, _inputObject)
if inputState == Enum.UserInputState.Begin then
performSomeAction()
end
end
-- 仅在玩家装备钓鱼竿时启用该动作
fishingPole.Equipped:Connect(function()
ContextActionService:BindAction(ACTION_CAST, castLine, true, Enum.KeyCode.E)
end)
-- 当玩家卸下钓鱼竿时禁用该动作
fishingPole.Unequipped:Connect(function()
ContextActionService:UnbindAction(ACTION_CAST)
end)
Roblox 脚本可以相对简洁,因为 Roblox 有许多内置假设:一个与服务器连接的 Player,带有 Humanoid 角色,可以装备 Tools。这些假设在 Unity 中不存在,因此实现会非常不同。
资产
Unity 和 Roblox 都支持以 .fbx 格式导入自定义网格和模型。某些类型的资产可能需要特定的配置和来自第三方建模软件的导出设置。有关更多信息,请参见以下页面:
在 Unity 中,对象导入到你的 Assets 目录,在 Project 窗口中可见。在 Roblox 中,资产导入到你的 Workspace 以及 Toolbox 或 Asset Manager。
Roblox 还提供一个开源 Blender 插件,以简化导入过程。
变换
Unity 的变换和 Roblox 的 CFrames 在表示对象的 3D 变换方面具有相似的目的:
- 两者都支持乘法以进行复杂的变换,并具有用于其他操作的内置方法。
协作
在 Unity 中,您可以与标准版本控制系统或付费服务(如 Unity 版本控制)协作。
Roblox 文件存储在云中(尽管您可以导出副本),因此 Roblox Studio 提供内置协作工作流程,以便同时编辑、群组管理、权限、脚本草拟等等。请参见 Collaboration。
插件
与 Unity 工具类似,Roblox Studio 支持 插件,可以简化或提供您对开发过程各个方面的额外控制。插件在 Creator Store 中可用,正如资产一样,许多是免费的。
术语表
| Unity | Roblox | 备注 |
|---|---|---|
| Scene | Place | |
| GameObject | Part 或 Model | 请参见 Philosophical differences. |
| Prefab | Package | |
| Transform | CFrame | CFrame 不包括缩放信息。请参见 Transforms. |
| Hierarchy | Explorer | |
| Inspector | Properties | |
| Scene view | 3D viewport | |
| Game view | 3D viewport | 当你测试游戏时,视口会过渡到游戏视图。 |
| Project window | Asset Manager 或 Toolbox | |
| Terrain Inspector | Terrain Editor | |
| Spawn point | SpawnLocation | |
| Console | Output | |
| Asset Store | Creator Store | |
| Overlays | Toolbar | |
| Tool | Plugin |