模型是容器對象,意味著它們會將對象組合在一起。它們最適合用來存儲 BaseParts 集合,並擁有一系列擴展其功能的功能。
模型的目的是代表 幾何 集群。如果你的分組沒有幾何解釋,例如一個集合 Scripts , 則使用 Folder 取代。
模型的構成部分與關節一起連接(以便它們可以通過物理模擬移動或被摧毀)通常會有 PrimaryPart 設設定,因為它規定模型中哪一部分的支點和盒子將「追蹤隨」模型移動。留在一個地方的靜態模型無法從擁有主要零件設定中受益。
模型具有廣泛的應用程式,包括 Roblox 玩家角色。它們也有一些獨特的行為,值得留意:
- 當在地方使用 Workspace.StreamingEnabled 設為真實時, ModelStreamingMode 控制將複製和/或從客戶端移除模型和任何子模型的各種行為。此外,LevelOfDetail影響模型的渲染。
與所有 Instance 類型一樣,父親 Model 被複製到客戶端並不保證所有其子女都被複製。如果這些實例被客戶端上的代碼存取,例如在 LocalScript 中,這非常重要。使用 ModelStreamingMode 與值如 Atomic 一起可以確保父模型存在在客戶端上或不想要原子性時使用 WaitForChild() 來確保整個模型和所有其子模型都存在。
範例程式碼
The following sample includes a basic function that takes a table of objects and parents them into a new Model, returning that Model.
local function groupObjects(objectTable)
local model = Instance.new("Model")
for _, object in pairs(objectTable) do
object.Parent = model
end
return model
end
local objects = {
Instance.new("Part"),
Instance.new("Part"),
}
groupObjects(objects)
概要
屬性
為啟用實例傳輸的體驗設置模型的細節程度。
在啟用實例傳輸時,控制模型傳輸行為在 Models 上。
Model 的主要部分,或 nil 如果未明確設設定。
僅用於編輯器的屬性,用於擴展模型周圍的旋轉點。設置此屬性會將比例移至如果 Model/ScaleTo 被呼叫在它上面。
決定哪裡是 不具有設置的 軸心所在的地方。
方法
將此模型設為指定玩家的持久模型。Model.ModelStreamingMode必須設為 永久每個玩家 以便行為在添加後發生變更。
返回包含模型所有部分的卷的說明。
返回包含所有 BaseParts 在 Model 中最小綁定箱的尺寸,並與 Model.PrimaryPart 一起對齊,如果已設定。
返回此模型對象持有的所有 Player 對象。行為取決於此方法是否從 Script 或 LocalScript 中呼叫。
返回模型的正常比例,預設為新建模型的 1,並且在通過 Model/ScaleTo 縮放時會變更。
將 PrimaryPart 移動到指定位置。如果未指定主要零件,將使用模型的根部分。
使此模型對指定玩家不再持久。Model.ModelStreamingMode必須設為 永久每個玩家 以便在移除後變更行為。
設置模型的縮放因子,調整所有子模塊的大小和位置,使其具有與初始大小和位置相關的縮放因子,當縮放因子為 1 時。
以給定的 Model 偏移值移動 Vector3 ,保留模型的方向。如果另一個 BasePart 或 Terrain 已在新位置存在,那麼 Model 將覆蓋該對物件。
獲得 PVInstance 的軸心。
將 以及所有其子孫 轉換為指定的 位置,使旋轉點現在位於指定的 位置。
屬性
LevelOfDetail
將模型上的細節等級設為啟用實例 串流 的體驗。
當設為 StreamingMesh 時,解析度較低的「擾亂者」網格(顏色、粗糙的網格,包圍了模型所有子零件)在傳輸範圍之外呈現。
ModelStreamingMode
控制實例 播放 時,如何將 傳送進來和出去,當啟用實例 傳輸 時。行為取決於選擇的枚號。當未啟用傳輸時沒有效果。
此屬性只能在啟用串流時在 Studio 的 屬性 視窗中更改,或在 Scripts 中,但永遠不要在 LocalScripts 中更改(這樣會導致無定義的行為)。
PrimaryPart
指向 Model 的主要部分。主要部分是 BasePart ,作為模型軸心的物理參考。即,當模型內的零件因物理模擬或其他原因移動時,軸心將與主要零件同步移動。
請注意,Models 沒有預設設置 PrimaryPart。如果您正在創建一個需要物理進行操作的模型,您應該手動在 Studio 或腳指令碼中設置此屬性。如果主要部分是 不 設設定,旋轉點將保持在世界空間中的同一位置,即使模型內的零件被移動。
請注意,當設置此屬性時,必須是模型的子孫 BasePart 。如果您嘗試將 Model.PrimaryPart 設置為 BasePart 那是 不是 模型的子孫,它將被設置為該部分,但在下一步模擬時重置為 nil — 這是舊的行為來支持那些假設可以暫時將主部分設置為 BasePart 而不是模型子孫的腳本。
對於模型的一般規則是:
- 其零件通過物理聯結,例如 WeldConstraints 或 Motor6Ds 連接在一起的模型應該有一個主要部分。例如,Roblox 角色模型的默認設定是將 Model.PrimaryPart 設為 HumanoidRootPart 。
- 靜態(通常是 Anchored)模型,如果沒有明確移動它們,就會留在同一位置,不需要 Model.PrimaryPart 並且通常不會受益於擁有一設定。
範例程式碼
This code sample creates and throws a dice model, then outputs whether it landed with the blue side facing up. If Model.PrimaryPart was not set, the pivot / bounding box of the dice would rotate, as the parts inside of it are physically simulated during the roll.
-- Create a dice model with two halves and attach them together
local diceModel = Instance.new("Model")
diceModel.Name = "ChanceCube"
local diceTop = Instance.new("Part")
diceTop.Size = Vector3.new(4, 2, 4)
diceTop.Position = Vector3.new(0, 1, 0)
diceTop.Color = Color3.new(0, 0, 1)
diceTop.Parent = diceModel
local diceBottom = diceTop:Clone()
diceBottom.Position = Vector3.new(0, -1, 0)
diceBottom.Color = Color3.new(1, 0, 0)
diceBottom.Parent = diceModel
local weld = Instance.new("WeldConstraint")
weld.Part0 = diceTop
weld.Part1 = diceBottom
weld.Parent = diceModel
-- Put the dice up in the air above the workspace origin (does not require a primary part)
diceModel.Parent = workspace
diceModel:PivotTo(CFrame.new(0, 10, 0))
-- Assign the primary part before physical simulation
-- Without this line, the script will always output the same thing and the bounding box of the model will not change orientation
diceModel.PrimaryPart = diceTop
-- Wait a bit before rolling the dice (let it settle onto the floor)
for i = 5, 1, -1 do
print("Rolling dice in...", i)
task.wait(1)
end
diceTop:ApplyAngularImpulse(Vector3.new(15000, 1000, 5000))
diceTop:ApplyImpulse(Vector3.new(0, 3000, 0))
task.wait(1)
-- Wait for the roll to complete
while diceTop.AssemblyLinearVelocity.Magnitude > 0.1 or diceTop.AssemblyAngularVelocity.Magnitude > 0.1 do
task.wait()
end
-- Get the dice orientation, impacted by the primary part
local orientation = diceModel:GetBoundingBox()
if orientation.YVector.Y > 0.5 then
print("It's the boy!")
else
print("It's his mother!")
end
Scale
在屬性面板中設置此屬性會將模型視為已被呼叫過的Model/ScaleTo,將模型中的所有子模型縮放,使模型具有指定的比例因子與原始尺寸相關。
此屬性只在工作室中可用,並且在 Script 或 LocalScript 中使用時會發生錯誤。Model/ScaleTo 和 Model/GetScale 應該從腳本中使用。
WorldPivot
這個屬性決定了哪個 Model 上的斧頭位置決定了哪個 不 有設置的 Model.PrimaryPart 位置。如果 Model 有 一個 PrimaryPart ,那麼 Model 的軸心將與該主要部分的軸心相等,而這個 WorldPivot 屬性將被忽略。
對於剛剛創建的 Model ,其軸心將被視為其內容綁定箱的中心,直到 第一次 設置其 Model.WorldPivot 屬性為止。一旦世界軸首次設置,就無法恢復這種初始行為。
最常見的情況是,使用 Studio 工具或模型移動功能,例如 PVInstance:PivotTo() 和 Model:MoveTo(),將設置世界軸心並因此結束新模型行為。
這種行為的目的是讓 Luau 代碼只需創建一個新模型並將其作為父來獲得一個合理的旋轉,避免每次創建模型在代碼中明確設置 Model.WorldPivot 。
local Workspace = game:GetService("Workspace")local model = Instance.new("Model")Workspace.BluePart.Parent = modelWorkspace.RedPart.Parent = modelmodel.Parent = Workspaceprint(model:GetPivot()) -- Currently equal to the center of the bounding box containing "BluePart" and "RedPart"model:PivotTo(CFrame.new(0, 10, 0)) -- This works without needing to explicitly set "model.WorldPivot"
範例程式碼
This code sample shows a custom function for resetting the pivot of a model back to the center of that model's bounding box.
local function resetPivot(model)
local boundsCFrame = model:GetBoundingBox()
if model.PrimaryPart then
model.PrimaryPart.PivotOffset = model.PrimaryPart.CFrame:ToObjectSpace(boundsCFrame)
else
model.WorldPivot = boundsCFrame
end
end
resetPivot(script.Parent)
方法
GetBoundingBox
此功能返回包含所有 BasePart 子在 Model 內的卷的描述。音量的方向基於 PrimaryPart 的方向,並與 Studio 中選擇框中渲染的模型匹配。鏡射 Terrain:FillBlock() 的行為,它返回一個 CFrame 代表該綁定箱的中心和一個 Vector3 代表其尺寸的 。
如果模型沒有 PrimaryPart,綁定框將會對世界軸進行校正。
local Workspace = game:GetService("Workspace")local model = Workspace.Modellocal part = Workspace.Partlocal orientation, size = model:GetBoundingBox()-- 調整並位置化與模型綁定箱相同的零件大小part.Size = sizepart.CFrame = orientation
返回
GetExtentsSize
返回包含所有 BaseParts 在 Model 中最小綁定盒的尺寸。如果 Model.PrimaryPart 存在,則綁定框將對準該部分。如果主要部分尚未設置,則函數會選擇模型中的一個部分來對綁定盒進行校正。由於這部分的選擇不是決定性的,建議設置 Model.PrimaryPart 以獲得與此函數一致的結果。
請注意,此功能只返回最小綁定方塊的尺寸,開發者必須使用自己的方法來獲得綁定方塊的位置。
返回
範例程式碼
The code sample below demonstrates how Model.GetExtentsSize can be used to get the size of the bounding box containing the parts.
local model = Instance.new("Model")
model.Parent = workspace
local RNG = Random.new()
for _ = 1, 5 do
local part = Instance.new("Part")
part.Anchored = true
part.Size = Vector3.new(RNG:NextNumber(0.05, 5), RNG:NextNumber(0.05, 5), RNG:NextNumber(0.05, 5))
part.Parent = model
end
print(model:GetExtentsSize())
GetPersistentPlayers
當此方法從 Script 中呼叫時,它會返回此模型持有的所有 Player 對象。當從 LocalScript 呼叫此方法時,此方法只檢查此模型是否持久於 LocalPlayer 。
返回
一個包含這個模型對象持久的所有 Player 對象的表。
GetScale
模型包含永久的常見比例因子,其起始值為新建模型的 1,並隨著模型被縮放而變化,稱為 Model/ScaleTo 。此功能返回模型的當前標準縮放因子。
目前的縮放因子不會 直接 影響模型下的實例大小。它用於內容作者和腳本的目的,記住模型是如何相對於原始尺寸縮放的。
在指定的會作業內,模型會在第一次 Model/ScaleTo 呼叫後儲存後裔實例的準確原始尺寸資訊。這意味著呼叫 ScaleTo(x) 跟隨 ScaleTo(1) 將讓你回到 正確 模型的原始配置,沒有浮點漂移。避免浮點漂移是為了擁有一個比例 到 函數而不是一個比例 由 函數的動機。
縮放因子會對引擎行為產生一種影響:模型的縮放因子將被應用到在該模型下的共同偏移 上,因此動畫模型在縮放時仍能正確播放動畫,即使在縮放時也是如此。
返回
模型目前的正常比例因子。
範例程式碼
This code sample demonstrates substituting in a replacement for all the copies of a tree model using PivotTo and ScaleTo. The pivot and scale of the models are used as a reference ensuring that the relative sizes and locations of the replacement models match those of the originals.
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Find all the models with the tag we want to replace
local items = CollectionService:GetTagged("Tree")
local newModel = ReplicatedStorage.FancyTreeReplacementModel
for _, item in items do
-- Make the new item and scale / position it where the old one was
local newItem = newModel:Clone()
newItem:ScaleTo(item:GetScale())
newItem:PivotTo(item:GetPivot())
-- Add the same tag to the replacement
CollectionService:AddTag(newItem, "Tree")
-- Delete the old item and parent the new one
newItem.Parent = item.Parent
item:Destroy()
end
MoveTo
將 PrimaryPart 移動到指定位置。如果沒有指定主要部分,模型的根部分將被使用,但根部分不是決定性的,並建議您在使用 MoveTo() 時總是設置主要部分。
如果模型要移動的地方有障礙物,例如 Terrain 或其他 BaseParts,模型將縱向向上移動,直到沒有障礙物為止。如果這種行為不是想要的,PVInstance:PivotTo()應該使用其他方式。
請注意,旋轉在移動模型時 MoveTo() 不會保留。建議使用 TranslateBy() 或 PVInstance:PivotTo() 如果需要保留目前模型的旋轉。
參數
返回
範例程式碼
This sample demonstrates how Model:MoveTo avoids collisions.
A simple two part Model is created, and its PrimaryPart is set. An large obstruction part is placed next to it.
After 5 seconds Model:MoveTo is used to direct the model to move inside the obstruction part. However, as MoveTo will not move a model inside of an obstruction the Model is moved up on the Y axis and placed above the obstruction.
local START_POSITION = Vector3.new(-20, 10, 0)
local END_POSITION = Vector3.new(0, 10, 0)
local model = Instance.new("Model")
model.Parent = workspace
local part1 = Instance.new("Part")
part1.Size = Vector3.new(4, 4, 4)
part1.Position = START_POSITION
part1.Anchored = true
part1.BrickColor = BrickColor.new("Bright yellow")
part1.Parent = model
local part2 = Instance.new("Part")
part2.Size = Vector3.new(2, 2, 2)
part2.Position = START_POSITION + Vector3.new(0, 3, 0)
part2.Anchored = true
part2.BrickColor = BrickColor.new("Bright blue")
part2.Parent = model
model.PrimaryPart = part1
model.Parent = workspace
local obstruction = Instance.new("Part")
obstruction.Name = "Obstruction"
obstruction.Size = Vector3.new(10, 10, 10)
obstruction.Position = Vector3.new(0, 10, 0)
obstruction.Anchored = true
obstruction.BrickColor = BrickColor.new("Bright green")
obstruction.Parent = workspace
task.wait(3)
model:MoveTo(END_POSITION)
ScaleTo
模型包含永久的常見比例因子,新建模型的起始值為 1。此功能會將模型縮放到傾斜位置,相對於使用縮放因子 1 的外觀。為了達成這一目標,它會做兩件事:
- 將模型的當前比例因子設為指定值
- 適當地縮放和重新定位所有子 Instances
位置的縮放是在旋轉位置周圍完成的。
所有「幾何」性質的子實例特性將被縮放。這顯然包括零件的尺寸,但這裡有一些其他縮放的屬性的例子:
- 像 WeldConstraints 和 Class.Rope|Ropes 這樣的節點長度
- 物理速度和力,例如 Hinge.MaxServoTorque
- 像粒子發射器的尺寸等視覺特性
- 其他長度屬性,例如 Sound.RollOffMinDistance
參數
返回
TranslateBy
以給定的 Model 偏移值移動 Vector3 ,保留模型的方向。如果另一個 BasePart 或 Terrain 已在新位置存在,那麼 Model 將覆蓋該對物件。
翻譯在對象空間而不是世界空間中應用,這意味著即使模型的零件以不同方向旋轉,它仍然會沿標準軸移動。
參數
返回
範例程式碼
This sample demonstrates how Model:TranslateBy ignores collisions and respects the orientation of the model.
A simple two part Model is created, rotated 45 degrees on the Y axis, and its PrimaryPart is set. An large obstruction part is placed next to it.
After 5 seconds Model:TranslateBy is used to direct the model to move inside the obstruction part. The model will move inside of the obstruction and maintain it's current orientation.
local START_POSITION = Vector3.new(-20, 10, 0)
local END_POSITION = Vector3.new(0, 10, 0)
local model = Instance.new("Model")
local part1 = Instance.new("Part")
part1.Size = Vector3.new(4, 4, 4)
part1.CFrame = CFrame.new(START_POSITION) * CFrame.Angles(0, math.rad(45), 0)
part1.Anchored = true
part1.BrickColor = BrickColor.new("Bright yellow")
part1.Parent = model
local part2 = Instance.new("Part")
part2.Size = Vector3.new(2, 2, 2)
part2.CFrame = part1.CFrame * CFrame.new(0, 3, 0)
part2.Anchored = true
part2.BrickColor = BrickColor.new("Bright blue")
part2.Parent = model
model.PrimaryPart = part1
model.Parent = workspace
local obstruction = Instance.new("Part")
obstruction.Name = "Obstruction"
obstruction.Size = Vector3.new(10, 10, 10)
obstruction.Position = Vector3.new(0, 10, 0)
obstruction.Transparency = 0.5
obstruction.Anchored = true
obstruction.BrickColor = BrickColor.new("Bright green")
obstruction.Parent = workspace
task.wait(3)
-- use TranslateBy to shift the model into the obstruction
model:TranslateBy(END_POSITION - START_POSITION)