概要
API 參考
屬性
Generator
範例程式碼
預設生成器模組
-- 生成器模組是一個 ModuleScript,定義了 ProceduralModel 如何構建其內容。
-- 詳情請參見 https://create.roblox.com/docs/reference/engine/classes/ProceduralModel。
--
-- 作為生成器使用時,ModuleScript 必須返回一個包含兩個欄位的表:
-- * `Attributes` - 一個預設值的表。每個鍵成為使用此生成器的每個
-- ProceduralModel 的屬性。用戶可以在屬性面板中調整這些
-- 屬性,以使用新輸入重新運行生成。
-- * `OnGenerate` - 引擎調用的函數,用於 (重新)構建模型的內容。
--
-- 此腳本或其位置沒有特殊之處。它可以在 DataModel 的任何位置存在,
-- 並且 ProceduralModel 的 `Generator` 屬性可以重新指向它。
-- 以下類型註解是可選的,但在此記錄,以使所需形狀明確。
-- `GenerationFunctionParams` 每次生成運行時傳遞給 `OnGenerate`。它暴露:
-- * `Attributes` - ProceduralModel 上的當前屬性值。
-- * `Size` - 生成範圍的邊界體積(來自 `ProceduralModel.Size`)。
-- * `Pause` - 一個協作的暫停。在長循環中調用 `parameters:Pause()`,以便大型
-- 生成不會阻礙調用執行緒;引擎可能稍後會恢復你。
type GenerationFunctionParams<Attributes> = {
Attributes: Attributes,
Size: Vector3,
Pause: (self: GenerationFunctionParams<Attributes>) -> (),
}
-- `GeneratorModuleDefinition` 是 ModuleScript 必須返回的表。
-- `OnGenerate` 不得返回值;而是將生成的實例父項進入 `targetContainer`。
-- 任何父項到 `targetContainer`(或其後代)的內容都成為生成的輸出。
type GeneratorModuleDefinition<Attributes> = {
Attributes: Attributes,
OnGenerate: (
parameters: GenerationFunctionParams<Attributes>,
targetContainer: GeneratedFolder
) -> (),
}
-- 預設屬性。這裡的每個條目在 ProceduralModel 上顯示為可編輯的屬性。
-- 固定的 `RandomSeed` 保持生成的確定性:相同的輸入總是產生相同的
-- 輸出,這很重要,因為生成可能會隨著用戶編輯屬性而運行多次。
local defaultAttributes = {
BorderThickness = 1,
RandomSeed = 142376088,
}
local Generator: GeneratorModuleDefinition<typeof(defaultAttributes)> = {
Attributes = defaultAttributes,
OnGenerate = function(parameters, targetContainer)
-- 輸入。`parameters.Attributes` 反映用戶在
-- ProceduralModel 上設置的內容;`parameters.Size` 是構建的邊界框。
local borderThickness = parameters.Attributes.BorderThickness
local random = Random.new(parameters.Attributes.RandomSeed)
local size = parameters.Size
-- 派生值。上面的隨機數使這些對每個 RandomSeed 可重複。
local minSize = math.min(size.X, size.Y, size.Z)
local baseColor = Color3.fromHSV(random:NextNumber(0.5, 0.8), 0.7, 0.8)
local outlineColor = Color3.fromHSV(random:NextNumber(), 0.4, 0.25)
-- 小幫助器使下面的構建過程自上而下可讀。您不需要
-- 像這樣的幫助器來編寫生成器;它們只是減少了重複。
local function assignProperties(instance: Instance, properties: { [string]: unknown })
-- 最後設置 Parent,以便其他屬性在實例進入
-- DataModel 並觸發 Changed 事件之前就位。
for name, value in properties do
if name ~= "Parent" then
(instance :: any)[name] = value
end
end
if properties.Parent ~= nil then
instance.Parent = properties.Parent :: Instance
end
return instance
end
local function createInstance(className: string, properties: { [string]: unknown })
return assignProperties(Instance.new(className), properties)
end
local function createPartWithDefaults(properties: { [string]: unknown })
-- 生成的零件通常是固定的且不會碰撞;根據需要重寫每個零件。
local part = createInstance("Part", {
Anchored = true,
CanCollide = false,
Color = baseColor,
Material = Enum.Material.SmoothPlastic,
BottomSurface = Enum.SurfaceType.Smooth,
TopSurface = Enum.SurfaceType.Smooth,
})
return assignProperties(part, properties)
end
-- 以下所有內容都以 `targetContainer` 為父項,這就是實例成為
-- 生成輸出的一部分的方式。未被這裡父項的實例將被丟棄。
-- 用作廣告牌的不可見邊界部件。
local bounds = createPartWithDefaults({
Name = "Bounds",
Parent = targetContainer,
Transparency = 1,
Size = size,
})
-- 一個有邊界輪廓的凹陷平台。
local base = createPartWithDefaults({
Name = "PlatformBase",
Parent = targetContainer,
Color = baseColor,
CFrame = CFrame.new(0, (-size.Y + 1) / 2, 0),
Size = Vector3.new(
size.X - 2 * borderThickness,
1.01,
size.Z - 2 * borderThickness
),
})
local outline = createPartWithDefaults({
Name = "PlatformOutline",
Parent = targetContainer,
Color = outlineColor,
Position = Vector3.yAxis * (-size.Y + 1) / 2,
Size = Vector3.new(size.X, 1, size.Z),
})
-- "Hello World!" 廣告牌。生成器可以創建任何實例類型,而不僅僅是零件。
local billboard = createInstance("BillboardGui", {
Name = "Text",
Parent = targetContainer,
Adornee = bounds,
LightInfluence = 0,
Size = UDim2.fromScale(minSize, minSize),
})
local textLabel = createInstance("TextLabel", {
Name = "HelloWorld",
Parent = billboard,
AnchorPoint = Vector2.new(0.5, 0.5),
BackgroundTransparency = 1,
Position = UDim2.fromScale(0.5, 0.5),
Size = UDim2.fromScale(1, 1),
Text = "Hello World!",
TextColor3 = baseColor,
TextScaled = true,
TextStrokeTransparency = 0,
})
local textStroke = createInstance("UIStroke", {
Parent = textLabel,
Color = outlineColor,
Thickness = borderThickness * 3,
})
end,
}
-- 返回模組定義使此 ModuleScript 可用作 `Generator`。
return Generator經典梯子生成器模組
-- 生成器模組是一個返回包含 `Attributes` 和 `OnGenerate` 的表的 ModuleScript。
-- 將此 ModuleScript 指定給 ProceduralModel 的 `Generator` 屬性會在模型的 Size、
-- 屬性或模組源發生變化時運行 `OnGenerate`。
-- 參見 https://create.roblox.com/docs/reference/engine/classes/ProceduralModel。
local ClassicRobloxLadderGenerator = {}
-- 預設屬性值。每個鍵成為任何使用此生成器的 ProceduralModel 上可編輯的屬性,
-- 並在 Studio 屬性面板的屬性下顯示。編輯其中任何一個
-- 會使用新值重新運行 `OnGenerate`。
ClassicRobloxLadderGenerator.Attributes = {
RungSpacing = 2,
RungThickness = 1,
PostSize = 1,
Color = Color3.new(0.5, 0.3, 0),
}
-- `OnGenerate` 是由引擎調用來構建模型的內容。
-- 約定:
-- * `parameters.Size` - 要構建的邊界框(來自 `ProceduralModel.Size`)。
-- * `parameters.Attributes` - 當前 ProceduralModel 上的屬性值。
-- * `parameters:Pause()` - 合作讓出控制;在長循環內調用以便大型生成
-- 不會阻塞線程。
-- * `targetContainer` - 這裡(或其後代)任何父物件將成為輸出。
-- * 不要從 `OnGenerate` 返回一個值;輸出是通過 `targetContainer` 傳遞的。
ClassicRobloxLadderGenerator.OnGenerate = function(parameters, targetContainer)
local size = parameters.Size
local rungThickness = parameters.Attributes.RungThickness
local postSize = parameters.Attributes.PostSize
local count = (size.Y - rungThickness) // parameters.Attributes.RungSpacing + 1
local function createPart(position, size)
local part = Instance.new("Part")
part.Size = size
part.Position = position
part.Anchored = true
part.Color = parameters.Attributes.Color
part.TopSurface = Enum.SurfaceType.Smooth
part.BottomSurface = Enum.SurfaceType.Smooth
-- 將部分放入 `targetContainer` 是將其添加到生成輸出的方式。
part.Parent = targetContainer
end
-- 梯條,從邊界框的底部堆疊向上。
local position = Vector3.new(0, -size.Y / 2 + rungThickness / 2, 0)
for i = 1, count do
-- 在梯條之間讓出控制,以便擁有許多梯條的梯子不會阻塞線程。
parameters:Pause()
createPart(position, Vector3.new(size.X - 2 * postSize, rungThickness, size.Z))
position += Vector3.new(0, parameters.Attributes.RungSpacing, 0)
end
-- 左側和右側支柱跨越整個高度。
createPart(Vector3.new(-0.5 * size.X + postSize / 2, 0, 0), Vector3.new(postSize, size.Y, size.Z))
createPart(Vector3.new(0.5 * size.X - postSize / 2, 0, 0), Vector3.new(postSize, size.Y, size.Z))
end
-- 返回模組定義使這個 ModuleScript 可以用作 `Generator`。
return ClassicRobloxLadderGenerator方法