ProceduralModels 是一种以参数驱动的 Model,使您能够使用代码构建和生成 3D 对象。您无需手动编辑模型的内容,而是通过一个 生成器模块 和一组属性来定义其结构。当这些属性发生变化,或者模型被调整大小时,生成器会自动运行以更新模型。
程序化模型使得以下操作更加容易:
- 通过更改参数而不是重建模型以非破坏性方式调整模型。例如,更改螺旋楼梯上的 StepSize 值会自动用更新的步骤数量重新生成楼梯。
- 通过实现一个单一的 OnGenerate 函数,自动与现有的 Studio 系统(如撤销/重做,团队创作和拖拽工具)集成。
- 保持高性能,模型在参数改变之前表现得像标准对象。
- 在编辑时和运行时都生成内容,在 Studio 和游戏中使用相同的系统。
- 在创作者商店分享带参数的模型,使资产更加灵活和可定制。
插入程序化模型
您可以通过以下方式将程序化模型添加到您的游戏中:
手动将 ProceduralModel 对象插入工作区。此选项包括一个模板生成器 ModuleScript,可以帮助您入门。

使用 Assistant 或 Roblox Studio MCP 服务器 生成程序化模型。
从创作者商店插入一个程序化模型,以使用或自定义现有模型。
要定制程序化模型的生成方式,您可以定义自己的生成器模块。
OnGenerate 函数
OnGenerate 函数是每个 ProceduralModel 的核心,形式为 OnGenerate(params, targetContainer)。
这个开发者定义的函数负责根据提供的参数生成模型的内容,并将结果写入给定的容器中。
OnGenerate 有两个主要职责:
- 处理输入参数以确定模型的结构
- 根据该结构将生成的结果写入提供的 targetContainer
以下部分描述了:
- 引擎何时以及如何调用 OnGenerate
- 引擎如何处理写入 targetContainer 的内容
生成器模块
OnGenerate 函数在一个称为 生成器模块 的 ModuleScript 内定义。ProceduralModel 通过其 Generator 属性识别要使用的生成器模块。
生成器模块是标准的 Luau 模块,但作为生成过程的一部分由引擎直接要求。它们遵循定义的结构并返回一个包含标准化字段的表。
生成器模块结构
local MyGenerator = {}
MyGenerator.Attributes = {
DoSomething = true,
AmountOfSomething = 137,
}
type Params = {
Size: Vector3,
Attributes: typeof(MyGenerator.Attributes),
Pause: (self: any) -> (),
}
function MyGenerator.OnGenerate(params: Params, targetContainer: GeneratedFolder)
end
return MyGenerator
标准化字段包括:
- Attributes:一个映射,定义参数名称及其默认值。
- OnGenerate:接收 params 表和 targetContainer 的函数。
OnGenerate 中的 params 表包含:
- Attributes:一个包含模块定义属性或所有模型属性的表(如果未指定)。
- Size:反映模型在比例为 1 时的尺寸的参数。
- Pause:一个允许在复杂生成任务中有效地停止生成的方法。
OnGenerate 函数应在 targetContainer 中围绕原点生成内容。它不应直接修改主 DataModel 层次结构。
参数
参数 是控制生成的输入。这些包括 ProceduralModel 的内置 Size 属性,以及生成器模块中指定的自定义属性。这些 显式参数 直接传递给 OnGenerate。隐式参数,如模块的源代码或沙盒状态,在发生变化时也触发再生成,但不会传递给 OnGenerate。
完整的参数集合包括:
- 显式参数:
- Size:定义围绕原点生成内容的区域。
- Attributes:一个包含当前输入属性值的映射。
- 隐式参数:
- Generator:提供生成逻辑的模块。
- 源代码:对生成器模块的 Luau 代码的更改。
- 沙盒:对生成器模块的沙盒状态的更改。
再生行为
为了保持性能和简化 API 交互,OnGenerate 在参数更改时 不 会立即调用。相反,ProceduralModel 被标记为 脏,表示再生待定。此待定再生通常在同一帧稍后发生。
如果再生失败,脏状态将被清除,直到发生另一个参数更改。如果在模型处于脏状态时保存游戏,该状态将持续,并且模型将在下一次加载游戏时添加到生成队列中。
执行过程
在处理时间可用时,引擎通过执行以下步骤再生脏模型:
- 需要生成器模块,根据需要进行等待。
- 为生成过程启动一个新线程。
- 构建参数表,通过模型的当前缩放归一化 Size。
- 将默认属性值应用于任何缺失的属性。
- 初始化一个临时的 GeneratedFolder 作为 targetContainer。
- 调用 OnGenerate。
- 在 OnGenerate 返回后:
- 如果成功,将 targetContainer 中的结果迁移到 ProceduralModel。
- 如果生成失败,则使用失败占位符代替。
如果在生成线程被挂起时再次更改参数,则取消未完成的生成并用更新的参数重新启动。
生成结果
将生成结果放入模型涉及以下步骤:
- 终止生成过程中泄露的任何子线程。
- 使用 PivotTo 定位结果。
- 如果模型的 Scale 不是 1,则使用 ScaleTo 取消大小归一化。
- 将结果父元素设置为模型的 GeneratedFolder。
- 如果生成器模块处于沙盒状态,确保结果中的 ModuleScripts 不超出生成器模块能力。
- 用默认值填充模型上缺失的任何属性。
- 清除模型的脏状态。
生成细节
除了核心生成流程外,以下细节描述了影响 ProceduralModel 生成的行为和考虑事项。
尺寸调整
由于在生成过程中应用了缩放归一化,ProceduralModel 支持多种尺寸调整工作流程:
- 更改 Size 属性会使用新内容重新生成模型。
- 更改 Scale 将使用 ScaleTo 均匀缩放现有结果。

超时
作为安全措施,执行过多工作而未进行等待的生成器模块将被终止。如果生成遇到 "脚本超时" 错误,请添加额外的调用 parameters:Pause() 以允许引擎将剩余工作推迟到以后的帧。
调用 parameters:Pause() 是非常便宜的,通常在正常生成器执行期间立即返回,因此可以在循环开始时随意调用,而不影响性能。
撤消历史
生成的结果与触发它们的参数变更一起使用撤消路径覆盖进行分组。如果在同一帧内发生多次参数更改,则结果与最近的路径关联。
沙盒
ProceduralModel 支持沙盒。您从创作者商店插入的所有第三方程序化模型默认都是沙盒化的,以帮助防止对您的游戏进行意外更改。
生成代码在生成器模块的上下文中运行,并使用该模块的沙盒状态。这些设置默认不可见。要查看或修改它们,请设置 Workspace.SandboxedInstanceMode = Experimental。这将暴露 ModuleScript 上的 Sandboxed 和 Capabilities 属性。
一个沙盒的生成器模块通常至少需要以下能力:
- RunServerScript(执行模块)
- CreateInstances
- Basic
程序化模型及其生成器模块的沙盒是相互独立的。应用于生成器模块的沙盒不会影响 ProceduralModel 内的正常运行时脚本。这使您能够在不影响游戏内行为的情况下保持编辑时生成的严格限制。
嵌套
ProceduralModels 可以生成其他 ProceduralModels。在这种情况下,引擎尽可能在同一生成步骤中自上而下处理层次结构,深层嵌套的模型最后生成。
限制
- 不支持在 Actor 实例内进行生成。
- 模型不能转换为包。
- 使用启用 关节表面 的拖动工具时创建的关节在 ProceduralModel 再生过程中无法保留。