當兩個3D對象在3D世界中發生衝突時,BasePart有一組衝突事件和衝突過濾器技術,讓您可以控制哪些物理組合會與其他人相碰。
衝突事件
當兩個 Class.BasePart|BaseParts 觸摸或停止觸摸在 3D 世界中發生衝突時,您可以通過 BaseParts 和 Class.BasePart.TouchEnd
- 零件的 CanCollide 屬性會影響它是否會 物理 與其他零件碰撞並造成力量對它們作用。即使 Class.BasePart.CanCollide|
- Class.BasePart.Touched|Touched 和 TouchEnded 事件只會在結果是 物理 運動,而不是從 1>Class.BasePart.Position|Position1> 或 4>Class.BasePart.CFrame|CFrame4> 變更,
- 頂層 Terrain 類繼承自 BasePart ,因此您可以為 Class.Terrain 指定一個 1>衝突群組1> 來確定其他 4>Class.BasePart|BaseParts4> 與地形 7>voxels7> 是否碰
已觸摸
Class.BasePart.Touched|Touched 事件發生,當 Class.BasePart 與其他物體或地形 voxel 接觸時,它只會發火為結果 of 物理模擬
下列代碼示例顯示了如何連接 Class.BasePart.Touched|Touched 事件到自訂 onTouched() 函數。 注意,事件將 otherPart 參數傳送到函數,表示與碰撞相關的另一個部分。
零件碰撞
local part = workspace.Part
local function onTouched(otherPart)
print(part.Name .. " collided with " .. otherPart.Name)
end
part.Touched:Connect(onTouched)
注意,Touched 事件可以在快速成功連鎖中發射多次,因為許多微妙的物理衝突,例如當移動對象 "settles" 到休息位置或當衝突涉及多重
零件碰撞冷卻時間
local part = workspace.Part
local COOLDOWN_TIME = 1
local function onTouched(otherPart)
if not part:GetAttribute("Touched") then
print(part.Name .. " collided with " .. otherPart.Name)
part:SetAttribute("Touched", true) -- 將屬性設為 true
task.wait(COOLDOWN_TIME) -- 等待冷卻時間
part:SetAttribute("Touched", false) -- 重設屬性
end
end
part.Touched:Connect(onTouched)
已結束
Class.BasePart.TouchEnded|TouchEnded 事件發生當 BasePart 的整個衝突邊界超出另一個 Class
下列代碼示例顯示了如何連接 TouchEnded 事件到自訂 onTouchEnded() 函數。 喜歡 Touched ,事件將 1> otherPart1> 參數傳送到函數,指示其他部分。
非碰撞偵測
local part = workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " is no longer touching " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)
衝突過濾
碰撞 過濾 定義哪些物理零件與其他零件碰撞。您可以通過碰撞群組或零件-對零件基礎來控制碰撞對象的過濾。您可以通過1> Class.NoCollisionConstraint1> 實例來控制4>零件-對零件4>基礎上的碰撞。
衝突群組
衝突 群組 讓您可以將 BaseParts 分配給專用群組,並指定是否與其他群組衝突。 非衝突群組內的零件通過互相完全通過,即使兩個零件都有其 CanCollide 屬性集設為 2>
您可以通過 Studio 的 碰撞群組編輯器 設定碰撞群,這可以通過點擊 碰撞群組 按鈕在 模型 標籤中存取。
編輯器會在左側或右側的 Studio 會議室處理<a href=\"#listview\">列表檢視</a>,或在更寬廣的<a href=\"#tabeliew\">桌子檢視</a>中,會議室會議室處理。
注冊團體
編輯器包含一個 預設 碰撞群組,不能重命名或刪除。所有 BaseParts 自動屬於此預設群組,除非指派到其他群組,否則將與群組中的所有其他對象碰撞。
要創建新的衝突群組:
在編輯器面板的上方,單擊添加群組按鈕,輸入新群組名稱,然後按輸入。新群組會在兩個列表檢視中,或在左邊檢視行中上方的兩個行中顯示。
如有必要,請重複此過程,為每個群組選擇一個獨一無二的名稱。請注意,在開發中,您可以通過單擊其欄位或選擇它並點擊 重命名 按鈕來變更群組的名稱。
設定群組碰撞
在預設設定中,所有群組中的對象會碰撞。若要防止一個群組中的對象碰撞另一個群組中的對象,請在各個行/柱中的檢查框中取消選擇。
在下面的例子中, 方塊 群組中的對象將不會與 門 群組中的對象碰撞。
將對象分配給群組
要將對象指定給你所註冊的群組:
選擇一個或多個 BaseParts 以確認它們是否屬於衝突群組。
按一下行為 ⊕ 按鈕為其行,為對象分配群組,因此將它們放置在新群組中會從其當前群組中移除。
一旦分配,新群組將在對物件的 CollisionGroup 屬性下反射。
StudioSelectable 碰撞群組
工具在 Studio 使用衝突過濾系統來決定在 3D 視角中單擊時哪些對象是選擇候選人時候候選人。 衝突組的對象不會與 StudioSelectable 一起被忽略。
舉例來說,如果你在賽車體驗中有檢查點,其有效區域由大型透明零件定義,你可以將它們分配到 檢查點 衝突群組,然後使用 StudioSelectable 將該群組非碰撞,以便在編輯基礎地圖形狀時,它們不會發生在2>碰撞2>。
對於插件代碼,建議您為 "StudioSelectable" 下的零件找到 RaycastParams 作為碰撞群組過濾器,當您在鼠標下找到零件時,這允許您的插件匹配建造於 Studio 工具的選擇機制,與創作者所學到的預期建造工具相同。
建議的插件選擇射線
local UserInputService = game:GetService("UserInputService")local raycastParams = RaycastParams.new()raycastParams.CollisionGroup = "StudioSelectable" -- 跟隨約定raycastParams.BruteForceAllSlow = true -- 因此,可以選擇 "false" CanQuery 的零件local mouseLocation = UserInputService:GetMouseLocation()local mouseRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)local filteredSelectionHit = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)
零件到零件篩選
若要防止兩個特定零件之間的碰撞,而不設定 碰撞群組,例如車輪和車身之間,請考慮 無碰撞 限制。優點包括:
- 不需要衝突群組和/或設定指令碼,因此您可以輕鬆創建並分享自訂衝突過濾器的模型。
- 連接的零件不會相互撞擊,但它們仍然可以相互撞擊其他物件。
停用角色碰撞
Roblox 玩家角色會因為預設而相互碰撞。這可能會導致意外的遊遊玩行為,例如角色跳上 друг друг以達到特定區域。如果此行為不是預期的,您可以通過以下 Script 在 ServerScriptService 中禁止此行為。
腳本 - 停用角色碰撞
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)
local function onDescendantAdded(descendant)
-- 設定任何零件的衍生物的衝突後代組
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Characters"
end
end
local function onCharacterAdded(character)
-- 處理現有和新的子孫以設定物理學
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- 偵測玩家角色添加時間
player.CharacterAdded:Connect(onCharacterAdded)
end)
模型碰撞
Model 對象是從 BasePart 継承的零件,因此它們不能直接連接到 BasePart.Touched 或
下列代碼示例連接所有 BaseParts 的多重零件模型到碰撞事件和跟蹤總共碰撞次數。
模型碰撞
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- 忽略模型與自身交叉的實例
if otherPart:IsDescendantOf(model) then return end
-- 增加觸摸模型零件的次數
numTouchingParts += 1
print(model.Name, "intersected with", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- 忽略模型與自身交叉的實例
if otherPart:IsDescendantOf(model) then return end
-- 減少觸摸模型零件的次數
numTouchingParts -= 1
print(model.Name, "un-intersected from", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
end
網格與固體模型碰撞
MeshPart 和 PartOperation (由 固體建模 加入的零件) 是 0> Class.Base
Class.TriangleMeshPart.CollisionFidelity|CollisionFidelity 屬性有以下選項,由低到高的順序來評估穩定性和性能影響:
- 箱子 — 建立一個限定碰撞方塊,適合小型或非互動物件。
- 船體 — 生成一個圓弧船體,適合擁有較小凹陷或較小的空間的對象。
- 預設值 — 產生一個大約相互撞擊形狀,適用於具有半積分交互需求的複雜物體。
- 精準矢量分解 — 提供最精準的穩定性,但仍不是 1:1 代表圖像。此選項有最高的成本效能,並且需要更長的時間來計算。
有關衝突精準度選項的性能影響和如何滷滿它們的性能,請參閱「<a href=\"#performance\">PerformanceOptimization</a>」。有關選擇衝突精準度選項,以及如何選擇能平衡您的精準度需求和性能需求的選項,請參閱「<a href=\"#performance\"> here </a>」。