衝突

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

當兩個3D對象在3D世界中發生衝突時,BasePart有一組衝突事件和衝突過濾器技術,讓您可以控制哪些物理組合會與其他人相碰。

衝突事件

當兩個 Class.BasePart|BaseParts 觸摸或停止觸摸在 3D 世界中發生衝突時,您可以通過 BaseParts 和 Class.BasePart.TouchEnd

  • 零件的 CanTouch 屬性決定是否會啟動衝突事件。如果設為 false,那麼 Touched 和 1> Class.BasePart.TouchEnded|TouchEnded1> 都不會發觸發。
  • 零件的 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 的 碰撞群組編輯器 設定碰撞群,這可以通過點擊 碰撞群組 按鈕在 模型 標籤中存取。

Collision Groups tool indicated in Model tab of Studio

編輯器會在左側或右側的 Studio 會議室處理<a href=\"#listview\">列表檢視</a>,或在更寬廣的<a href=\"#tabeliew\">桌子檢視</a>中,會議室會議室處理。

List View example in Collision Groups Editor

注冊團體

編輯器包含一個 預設 碰撞群組,不能重命名或刪除。所有 BaseParts 自動屬於此預設群組,除非指派到其他群組,否則將與群組中的所有其他對象碰撞。

要創建新的衝突群組:

  1. 在編輯器面板的上方,單擊添加群組按鈕,輸入新群組名稱,然後按輸入。新群組會在兩個列表檢視中,或在左邊檢視行中上方的兩個行中顯示。

    New group added to Collision Groups Editor in List View
  2. 如有必要,請重複此過程,為每個群組選擇一個獨一無二的名稱。請注意,在開發中,您可以通過單擊其欄位或選擇它並點擊 重命名 按鈕來變更群組的名稱。

    Button and field indicated for renaming a group in the Collision Groups Editor

設定群組碰撞

在預設設定中,所有群組中的對象會碰撞。若要防止一個群組中的對象碰撞另一個群組中的對象,請在各個行/柱中的檢查框中取消選擇。

在下面的例子中, 方塊 群組中的對象將不會與 門 群組中的對象碰撞。

Group configured in List View of Collision Groups Editor

將對象分配給群組

要將對象指定給你所註冊的群組:

  1. 選擇一個或多個 BaseParts 以確認它們是否屬於衝突群組。

  2. 按一下行為 按鈕為其行,為對象分配群組,因此將它們放置在新群組中會從其當前群組中移除。

    Plus button indicated in Collision Groups Editor for adding selected parts to a group

一旦分配,新群組將在對物件的 CollisionGroup 屬性下反射。

Chosen collision group indicated as the part's CollisionGroup property

StudioSelectable 碰撞群組

工具在 Studio 使用衝突過濾系統來決定在 3D 視角中單擊時哪些對象是選擇候選人時候候選人。 衝突組的對象不會與 StudioSelectable 一起被忽略。

舉例來說,如果你在賽車體驗中有檢查點,其有效區域由大型透明零件定義,你可以將它們分配到 檢查點 衝突群組,然後使用 StudioSelectable 將該群組非碰撞,以便在編輯基礎地圖形狀時,它們不會發生在2>碰撞2>。

Checkpoints group configured to be non-collidable with StudioSelectable group

對於插件代碼,建議您為 "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 玩家角色會因為預設而相互碰撞。這可能會導致意外的遊遊玩行為,例如角色跳上 друг друг以達到特定區域。如果此行為不是預期的,您可以通過以下 ScriptServerScriptService 中禁止此行為。

腳本 - 停用角色碰撞

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

網格與固體模型碰撞

MeshPartPartOperation (由 固體建模 加入的零件) 是 0> Class.Base

Class.TriangleMeshPart.CollisionFidelity|CollisionFidelity 屬性有以下選項,由低到高的順序來評估穩定性和性能影響:

  • 箱子 — 建立一個限定碰撞方塊,適合小型或非互動物件。
  • 船體 — 生成一個圓弧船體,適合擁有較小凹陷或較小的空間的對象。
  • 預設值 — 產生一個大約相互撞擊形狀,適用於具有半積分交互需求的複雜物體。
  • 精準矢量分解 — 提供最精準的穩定性,但仍不是 1:1 代表圖像。此選項有最高的成本效能,並且需要更長的時間來計算。
Original mesh of castle tower

有關衝突精準度選項的性能影響和如何滷滿它們的性能,請參閱「<a href=\"#performance\">PerformanceOptimization</a>」。有關選擇衝突精準度選項,以及如何選擇能平衡您的精準度需求和性能需求的選項,請參閱「<a href=\"#performance\"> here </a>」。