衝突

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

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

衝突イベント

衝突イベントは、2つのBasePartsが3D空間で接触または接触を停止したときに発生します。これらの衝突は、どちらかのパーツのCanCollideプロパティ値にかかわらず、TouchedおよびTouchEndedイベントを介して検出できます。パーツの衝突処理を考慮する際は、以下に注意してください。

  • パーツのCanTouchプロパティは、衝突イベントをトリガーするかどうかを決定します。falseに設定されている場合、TouchedおよびTouchEndedは発火しません。
  • パーツのCanCollideプロパティは、他のパーツと物理的に衝突して力を及ぼすかどうかに影響します。たとえCanCollideが無効になっていても、TouchedおよびTouchEndedイベントを介して接触や非接触を検出できます。
  • TouchedおよびTouchEndedイベントは、物理的な移動の結果としてのみ発生し、パーツのPositionまたはCFrameの変更によって他のパーツと交差または交差しない状態になることによって発火することはありません。
  • トップレベルのTerrainクラスはBasePartから継承されているため、Terrain衝突グループを割り当てて、他のBasePartsTerrainボクセルと衝突するかどうかを決定できます。

Touched

Touchedイベントは、BasePartが別のオブジェクトまたはTerrainボクセルに接触したときに発火します。これは、物理シミュレーションの結果としてのみ発火し、パーツのPositionまたはCFrameが明示的に設定されて他のパーツやボクセルと交差する場合には発火しません。

以下のコードパターンは、TouchedイベントをカスタムonTouched()関数に接続する方法を示しています。このイベントは、衝突に関与する他のパーツを示すotherPart引数を関数に送信します。

パーツの衝突

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. " は " .. otherPart.Name .. " と衝突しました")
end
part.Touched:Connect(onTouched)

Touchedイベントは、移動するオブジェクトが「安定」した位置に落ち着くときや、マルチパートモデルを含む衝突の場合など、繊細な物理的衝突に基づいて短時間に複数回発火する可能性があります。必要以上に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 .. " は " .. otherPart.Name .. " と衝突しました")
part:SetAttribute("Touched", true) -- 属性を true に設定
task.wait(COOLDOWN_TIME) -- クールダウンの間待機
part:SetAttribute("Touched", false) -- 属性をリセット
end
end
part.Touched:Connect(onTouched)

TouchEnded

TouchEndedイベントは、BasePart全体の衝突境界が他のBasePartまたは充填されたTerrainボクセルの境界を出たときに発火します。これは、物理シミュレーションの結果としてのみ発火し、パーツのPositionまたはCFrameが明示的に設定されて別のパーツやボクセルと交差しなくなるときには発火しません。

以下のコードパターンは、TouchEndedイベントをカスタムonTouchEnded()関数に接続する方法を示しています。Touchedと同様に、このイベントは、関与する他のパーツを示すotherPart引数を関数に送信します。

非衝突検出

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " はもう " .. otherPart.Name .. " に接触していません")
end
part.TouchEnded:Connect(onTouchEnded)

衝突フィルタリング

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

衝突グループ

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

上記の動画では、回転する物体が異なる衝突グループにあり、異なる色の物体とは衝突しますが、自分の色の物体とは衝突しません。

Studioの衝突グループエディタを使用して、衝突グループを簡単に設定できます。これはStudioのウィンドウ ⟩ 3Dメニューからアクセスできます。

エディタは、Studioの左側または右側にドッキングすることを好むリスト ビューまたは、上部または下部にドッキングすることを好む広いテーブル ビューのいずれかで機能します。

衝突グループエディタのリストビューの例

グループを登録する

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

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

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

    リストビューに新しいグループが追加された衝突グループエディタ
  2. 必要に応じてプロセスを繰り返し、それぞれのグループにユニークで説明的な名前を選択します。開発中にグループ名を変更することもでき、フィールドをクリックするか、選択して名前変更ボタンをクリックします。

    衝突グループエディタでグループの名前を変更するためのボタンとフィールド

グループの衝突を構成する

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

次の例では、CubesグループのオブジェクトはDoorsグループのオブジェクトと衝突しません

リストビューで構成されたグループ

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

登録したグループにオブジェクトを割り当てるには、スタジオエディタを使用します。

  1. 衝突グループの一部となるBasePartsを1つ以上選択します。

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

    選択したパーツをグループに追加するためのプラスボタン

割り当てられると、新しいグループはオブジェクトのCollisionGroupプロパティに反映されます。

選択した衝突グループがパーツのCollisionGroupプロパティとして表示されています

StudioSelectable衝突グループ

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

たとえば、レーシング体験のチェックポイントが大きな透明なパーツで定義される場合、このグループをCheckpoints衝突グループに割り当て、その後StudioSelectableでは衝突しないように設定して、マップのジオメトリを編集するときに邪魔にならないようにできます。

チェックポイントグループがStudioSelectableグループと衝突しないように構成されています

プラグインコードでは、カーソルの下にあるパーツを見つけるときに、RaycastParamsの衝突グループフィルタとして"StudioSelectable"を割り当てることをお勧めします。これにより、作成者が組み込みのStudioツールから期待する選択メカニズムと一致させることができます。

推奨プラグイン選択レイキャスト

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- 規約に従うため
raycastParams.BruteForceAllSlow = true -- CanQueryが"false"のパーツを選択できるようにする
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)

パーツ間フィルタリング

2つの特定のパーツ間の衝突を防ぐには、衝突グループを設定せずに、たとえば車両の車輪とシャーシの間のようにする場合は、No Collision制約を検討してください。利点には以下が含まれます。

  • 衝突グループや設定スクリプトは不要なため、カスタマイズされた衝突フィルタリングを持つモデルを簡単に作成して共有できます。
  • 接続されたパーツは互いに衝突しませんが、他のオブジェクトとは衝突できます。

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

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またはBasePart.TouchEndedイベントに直接接続することはできません。モデルが衝突イベントをトリガーするかどうかを判断するには、その子をループして各子のBasePartにカスタムonTouched()およびonTouchEnded()関数を接続する必要があります。

次のコードサンプルは、マルチパートモデルのすべてのBasePartsを衝突イベントに接続し、他のパーツとの衝突の合計数を追跡します。

モデルの衝突

local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- モデルが自己交差する場合は無視
if otherPart:IsDescendantOf(model) then return end
-- モデルパーツが接触している数を増加
numTouchingParts += 1
print(model.Name, "は", otherPart.Name, "と交差しました | モデルパーツが接触:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- モデルが自己交差から外れる場合は無視
if otherPart:IsDescendantOf(model) then return end
-- モデルパーツが接触している数を減少
numTouchingParts -= 1
print(model.Name, "は", otherPart.Name, "から除去されました | モデルパーツが接触:", 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固体モデリングによって結合されたパーツ)はBasePartのサブクラスであるため、メッシュおよび固体モデリングパーツは通常のパーツと同じ衝突イベントおよび衝突フィルタリングオプションを継承します。ただし、メッシュおよび固体モデリングパーツは通常、より複雑なジオメトリを持つため、物理的境界が視覚的表現とどれだけ正確に一致するかを決定する特有のCollisionFidelityプロパティがあります。

CollisionFidelityプロパティには、忠実度とパフォーマンスへの影響の低い順から高い順に以下のオプションがあります。

  • ボックス — 小さなオブジェクトや非対話型オブジェクトに理想的なバウンディング衝突ボックスを作成します。
  • ハル — 明確な凹みや空洞の少ないオブジェクトに適した凸包を生成します。
  • デフォルト — 凹面をサポートし、複雑なオブジェクトで半詳細なインタラクションニーズに適したおおよその衝突形状を生成します。
  • 正確な凸分解 — 最も正確な忠実度を提供しますが、視覚的表現の1:1の表現ではありません。このオプションは最もコストが高く、エンジンの計算に時間がかかります。
城の塔の元のメッシュ

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

©2026 Roblox Corporation。Roblox(ロブロックス)、RobloxロゴおよびPowering Imaginationは、米国並びにその他の国における登録商標および非登録商標です。