衝突

*このコンテンツは、ベータ版のAI(人工知能)を使用して翻訳されており、エラーが含まれている可能性があります。このページを英語で表示するには、 こちら をクリックしてください。

3D ワールド内で 2つの 3D オブジェクトが接触すると、衝突が発生します。カスタマイズされた衝突処理のために、BasePart には、衝突イベント衝突フィルタリング のセットがあり、物理アセンブリが他のものと衝突するかどうかを制御できます。

衝突イベント

衝突 イベント は、3D 世界で 2 つの BaseParts が触れたり、触れるのをやめたりすると発生します。これらの衝突を検出するには、Touched および TouchEnded イベントを介して、どちらのパーツの CanCollide プロパティ値に関係なく発生します。パーツの衝突処理を考慮するときは、フォロー中のことに注意してください:

  • パーツの CanTouch プロパティは、衝突イベントをトリガーするかどうかを決定します。false に設定すると、Touched または TouchEnded が発火しないようになります。
  • パーツの プロパティは、他のパーツと物理的に衝突し、力がそれらに作用するかどうかを決定します。パーツが無効になっていても、CanCollideTouched および TouchEnded イベントを通じてタッチと非タッチを検出できます。
  • The および イベントは、物理的な移動による結果としてのみ発動し、パーツが他のパーツと交差したり、交差を停止したりする原因となる 物理的な変更 または 変更 はありません。
  • トップレベルの Terrain クラスは BasePart から継承しているので、他の Terrain と衝突するかどうかを判断するために BasePartsテライン に割り当てることができます。

触った

Touched イベントは、BasePart が他のものと接触したり、地形 のボクセルと接触したりすると発動します。それは 物理シミュレーション の結果としてのみ発射し、パーツの Position または CFrame が別のパーツまたはボクセルと交差するように明示的に設定されると発射しません。

次のコードパターンは、Touched イベントをカスタムの onTouched() 機能にどのように接続できるかを示しています。イベントは、otherPart 引数を機能に送信し、衝突に関与する他の部分を示します。

パーツの衝突

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. " collided with " .. otherPart.Name)
end
part.Touched:Connect(onTouched)

イベントは、移動オブジェクトが静止位置に「落ち着く」か、衝突がマルチパーツモデルを含む場合など、微妙な物理的衝突に基づいて複数回連続発射できることに注意してください。必要以上の多くの Touched イベントをトリガーしないようにするには、インスタンスの 属性 を介して「クールダウン」期間を強制する単純なデバウンスシステムを実装できます。

クールダウンでのパーツの衝突

local Workspace = game:GetService("Workspace")
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) -- 属性を真に設定
task.wait(COOLDOWN_TIME) -- クールダウン期間を待つ
part:SetAttribute("Touched", false) -- 属性をリセット
end
end
part.Touched:Connect(onTouched)

タッチ終了

TouchEnded イベントは、BasePart の全体の衝突境界が他の BasePart または満たされた 地形 ボクセルの境界から出るときに発動します。それは 物理シミュレーション の結果としてのみ発射し、パーツの Position または CFrame が別のパーツまたはボクセルとの交差を停止するように明示的に設定されると発射しません。

次のコードパターンは、TouchEnded イベントをカスタムの onTouchEnded() 機能にどのように接続できるかを示しています。例えば、Touched のように、イベントは、関与する他の部分を示す otherPart 引数を機能に送信します。

衝突検出以外

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " is no longer touching " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)

衝突フィルタ

衝突 フィルタ は、物理パーツが他のものと衝突するのかどうかを定義します。衝突グループ を介して数多くのオブジェクトのフィルタリングを構成するか、パーツ・トゥ・パーツ ベースで衝突を NoCollisionConstraint で制御できます。

衝突グループ

衝突 グループ では、専用グループに BaseParts を割り当て、他のグループのものと衝突するかどうかを指定できます。非衝突グループ内のパーツは、両方のパーツの CanCollide プロパティが true に設定されていても、完全にお互いを通過します。

上のビデオでは、回転オブジェクトは異なる衝突グループにあり、他の色のオブジェクトと衝突しますが、自分の色のオブジェクトとは衝突しません

Studio の 衝突グループエディタ をクリックすると、ツールバーの 衝突グループ ボタンをクリックしてアクセスできる Studio の 衝突グループ編集者 で簡単に衝突グループを設定できます。

Collision Groups tool indicated in Model tab of Studio

エディタは、左側または右側に ドッキング を好ませる リストビュー またはより広い テーブルビュー で機能し、ドッキングを上部または下部に好ませる。

List View example in Collision Groups Editor

グループを登録する

エディタには、名前を変更または削除できない 1つの デフォルト 衝突グループが含まれています。すべての BaseParts は、別のグループに割り当てられていない限り、自動的にこのデフォルトグループに属し、 デフォルトグループ のすべての他のオブジェクトと衝突することになります。

新しい衝突グループを作成するには:

  1. エディタパネルの上部にある グループを追加 ボタンをクリックし、新しいグループ名を入力し、Enter を押します。新しいグループは、リストビューの両方の列またはテーブルビューの左列と上行に表示されます。

    New group added to Collision Groups Editor in List View
  2. 必要に応じてプロセスを繰り返し、それぞれのグループにユニークで説明的な名前を選択します。グループの名前を変更できるのは、フィールドをクリックして開発中にグループの名前を変更するか、または選択して 名前変更 ボタンをクリックすることです。

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

グループコリジョンを構成する

デフォルト設定では、すべてのグループのオブジェクトが互いに衝突します。1つのグループのオブジェクトが別のグループのオブジェクトと衝突しないようにするには、 チェックを外す それぞれの行/列のボックス。

次の例では、キューブ グループのオブジェクトは、ドア グループのオブジェクトと衝突しません。

Group configured in List View of Collision Groups Editor

オブジェクトをグループに割り当てる

Studio エディタを通じて登録したグループにオブジェクトを割り当てるには: To assign objects to groups you've registered through the Studio editor

  1. 衝突グループの一部として資格のある 1つまたは複数の BaseParts を選択します。

  2. 行の ボタンをクリックして、グループに割り当てます。オブジェクトは一度に 1つの衝突グループにのみ属することができるため、新しいグループに配置すると、現在のグループから削除されます。

    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

スタジオ選択可能な衝突グループ

スタジオのツールは、3D ビューポートでクリックすると、選択候補になるオブジェクトを決定するために衝突フィルターシステムを使用します。割り当てられた衝突グループが しない オブジェクトは、 StudioSelectable との衝突を無視されます。

たとえば、効果的な領域が大きな透明なパーツで定義されているレーシングエクスペリエンスにチェックポイントがある場合、それらを チェックポイント の衝突グループに割り当て、そのグループを StudioSelectable で非衝突にして、基本的なマップジオメトリを編集しているときに邪魔にならないようにすることができます。

Checkpoints group configured to be non-collidable with StudioSelectable group

プラグインコードの場合、カーソルの下でパーツを見つけるときに "StudioSelectable" を衝突グループフィルタとして割り当てることをお勧めします。For plugin code, it's recommended that you assign as the collision group filter of your RaycastParams when finding parts under the cursor.これにより、プラグインが、クリエイターがビルトインの Studio ツールから期待する選択メカニズムに一致できます。

おすすめのプラグイン選択レイキャスト

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
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)

パーツ対パーツフィルタリング

衝突グループ を設定せずに、車両の車輪とシャーシの間のような 2つの特定のパーツの衝突を防ぐには、衝突しない 制約を考慮してください。利点には次のものがあります:

  • 衝突グループと/または構成スクリプトは必要ありませんので、カスタマイズされた衝突フィルタリングでモデルを簡単に作成し、共有できます。
  • 接続されたパーツは互いに衝突しませんが、他のオブジェクトとまだ衝突する可能性があります。

キャラクターの衝突を無効にする

Roblox プレイヤーのキャラクターはデフォルトで互いに衝突します。これは、キャラクターが互いに飛び乗って特定の領域に到達するなど、意図しない面白いゲームプレイにつながる可能性があります。この動作が望ましくない場合は、次の ScriptServerScriptService を防ぐことができます。

スクリプト - キャラクターの衝突を無効にする

local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
local CollisionGroupName = "Characters"
PhysicsService:RegisterCollisionGroup(CollisionGroupName)
PhysicsService:CollisionGroupSetCollidable(CollisionGroupName, CollisionGroupName, false)
local function setCollisionGroup(model)
-- モデルのすべての既存パーツに衝突グループを適用する
for _, descendant in model:GetDescendants() do
if descendant:IsA("BasePart") then
descendant.CollisionGroup = CollisionGroupName
end
end
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
setCollisionGroup(character)
end)
-- プレイヤーがすでにキャラクターを持っている場合は、すぐに衝突グループを適用する
if player.Character then
setCollisionGroup(player.Character)
end
end)

モデルの衝突

Model オブジェクトは、BasePart から継承せず、パーツのコンテナであるため、BasePart.Touched または BasePart.TouchEnded イベントに直接接続できません。モデルが衝突イベントをトリガーするかどうかを判断するには、その子供をループして、カスタムの onTouched() および onTouchEnded() 機能をそれぞれの子供に接続し、BasePart に接続する必要があります。

次のコードサンプルは、マルチパーツモデルのすべての 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

メッシュとソリッドモデルの衝突

と (ソリッドモデリングで結合されたパーツ)は、 のサブクラスであり、メッシュとソリッドモデリングされたパーツは、通常のパーツと同じ衝突イベント と衝突フィルタリング オプションを継承します。しかし、メッシュやソリッドモデリングパーツは通常、より複雑な幾何学を持っているため、物理的な境界が衝突処理のためのビジュアル表現とどれほど正確に一致するかを決定する特別な CollisionFidelity プロパティがあります。

CollisionFidelity プロパティには、フィデリティとパフォーマンスの影響の順序に従って次のオプションがあります:

  • — 小さなオブジェクトや非対話オブジェクトに最適なバインディングコリジョンボックスを作成します。
  • 船体 — 陥没や空洞が少ないオブジェクトに適した凸状の船体を生成します。
  • デフォルト — 凹状をサポートする約似の衝突形状を生成し、半精密な対話ニーズを持つ複雑なオブジェクトに適しています。
  • 精密な凸分解 — 最も精密な忠実度を提供しますが、視覚の 1:1 の表現ではありません。このオプションは最も高価なパフォーマンスコストがかかり、エンジンの計算に時間がかかります。
Original mesh of castle tower

衝突フィデリティオプションのパフォーマンスへの影響と、それらを軽減する方法については、パフォーマンス最適化 を参照してください。