roblox-physics について
roblox-physicsは、アセンブリ、拘束、衝突、クエリ、ネットワーク所有権を扱うRoblox開発者向けスキルです。物理シミュレーション、キャラクター制御、ヒット判定、演出上の動きを区別して実装方法を選べます。
主な機能
- 01シミュレーションとクエリ方式の選択
- 02衝突とクエリ方針の設定
- 03アセンブリへの力と拘束の適用
- 04ネットワーク所有権の管理
- 05クエリ負荷とリソース寿命の制御
- 06マルチプレイヤーでの物理検証
活用シーン
- 01不安定な接触判定によるヒット検出の置き換え
- 02揺れたり停止したりする仕組みのデバッグ
- 03力や拘束を使った動きの構築
- 04クライアント所有物理のゲーム上の影響の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill roblox-physicsインストール後、Claude Code で/roblox-physicsを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yamlreferences/queries-and-ownership.md
詳細
Roblox の物理演算
シミュレーション、キャラクター制御、ヒット検出、見た目だけの動きのどれを使うか、意図的に選んでください。
これらはそれぞれ異なる用途です。Roblox の現行 API を対象としています。エンジンに依存しない安定性や操作感については、physics-tuning と組み合わせてください。
使用する場面
- BasePart のアセンブリ、制約、衝突/クエリのポリシー、レイ/オーバーラップクエリ、力、力積、物理的に動くオブジェクト、ネットワーク所有権、物理演算のクリーンアップに使用します。
Touchedが信頼できない、またはセキュリティ上の懸念がある場合、パーツがすり抜けたり揺れたりする場合、アンカーを設定すると機構が壊れる場合、古い BodyMover のパターンが見つかった場合に使用します。
使用しない場面: 通常の Humanoid のライフサイクル/制御には roblox-characters を使用します。リモートの検証には roblox-networking を使用します。装飾的な UI/ワールドの動きには、Tween だけで十分な場合があります。
まずシステムを選ぶ
| 目的 | 仕組み |
|---|---|
| 継続的な物理的相互作用 | アンカーされていないアセンブリ+最新の制約/力 |
| 瞬間的な物理変化 | ApplyImpulse / ApplyAngularImpulse |
| キネマティックなプラットフォーム/経路 | 乗客の扱いを明示した、制御されたピボット/トランスフォーム |
| キャラクターの移動 | Humanoid/カスタムキャラクターコントローラー(roblox-characters) |
| 権威あるヒット判定 | フィルターとゲームプレイ検証を用いたサーバー側のレイキャスト/オーバーラップクエリ |
| 装飾用の軌跡/反動 | ローカルの見た目上の動き。ゲームプレイの権限は持たせません |
ワークフロー
- 機構を調べます。 Studio でアセンブリ、アンカー、制約、衝突グループ、質量のないパーツ、ネットワーク所有者を可視化します。アセンブリのルートと、意図する権限の所在を特定します。
- 相互作用のポリシーを定義します。 衝突グループのマトリックスを作成し、
CanCollide、CanTouch、CanQueryを個別に決定します。これらのフラグは相互に置き換えられません。 - シミュレーションかクエリかを選びます。 あらゆるヒット検出に
.Touchedを使わないでください。経路/直線にはレイ、ボリュームにはオーバーラップクエリを使い、物理応答が実際に必要な場合にシミュレーション接触を使います。 - アセンブリ単位で動きを適用します。 パーツに加えた力は、そのアセンブリに作用します。適切に
LinearVelocity、AngularVelocity、VectorForce、AlignPosition、AlignOrientationの最新の制約を使います。システムを変更する際は、非推奨の BodyMover を移行します。 - 所有権を意図的に設定します。 必要に応じて、ゲームプレイ上重要な、固定されていないアセンブリの所有権をサーバーに持たせます。クライアント所有権は応答性を高められますが、ゲームプレイ結果の権限を与えるものではありません。
- コストと存続期間に上限を設けます。 クエリパラメーターを再利用し、クエリ頻度/結果数に上限を設け、一時的な制約/アタッチメントを削除し、イベントリスナーを切断します。
- 負荷時とマルチプレイヤーで検証します。 アンカーあり/なしの切り替え、質量の極端な値、衝突マトリックス、高速移動、複数のクライアント、所有権の変更、ストリーミング、クリーンアップをテストします。
パターン:フィルターを適用したサーバー側レイキャスト
local Workspace = game:GetService("Workspace")
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {shooterCharacter}
params.IgnoreWater = true
params.CollisionGroup = "WeaponQuery"
local direction = aimDirection.Unit * MAX_RANGE
local result = Workspace:Raycast(muzzlePosition, direction, params)
if result then
local model = result.Instance:FindFirstAncestorOfClass("Model")
local humanoid = model and model:FindFirstChildOfClass("Humanoid")
if humanoid and serverCanDamage(shooter, model, result.Position) then
humanoid:TakeDamage(serverWeaponDamage(shooter))
end
end
サーバーは、サーバーが把握しているキャラクター/武器の状態に基づいて、原点と方向を検証する必要があります。任意のクライアント側の原点を受け入れ、レイキャスト自体を検証として扱わないでください。
パターン:ポリシーを明示したオーバーラップボリューム
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {sourceCharacter}
params.CollisionGroup = "DamageQuery"
params.MaxParts = 64
local seen: {[Model]: boolean} = {}
for _, part in Workspace:GetPartBoundsInBox(hitboxCFrame, hitboxSize, params) do
local model = part:FindFirstAncestorOfClass("Model")
if model and not seen[model] then
seen[model] = true
validateAndApplyHit(model)
end
end
境界ボックスを使うクエリには、対象の複数のパーツが含まれることがあります。必要に応じて重複を排除し、正確な判定/ゲームプレイ上のチェックを行ってください。正確な形状を使う場合は、追加コストが妥当なときに限り WorldRoot:GetPartsInPart(part, overlapParams) を使用します。OverlapParams.RespectCanCollide は、クエリが CanCollide と CanQuery のどちらを尊重するかを決定する点に注意してください。意図的に設定しないと、下記のフラグポリシーが暗黙に上書きされます。OverlapParams.Tolerance は接触の許容幅を制御します。
アセンブリ、力、所有権
- 溶接されたパーツは1つの剛体アセンブリを形成し、力、インパルス、速度、質量、所有権はそのアセンブリに対して作用します。パーツを固定するとシミュレーションや所有権が変わり、アセンブリの質量が実質的に無限になることがあります。
- 一度限りの変化にはインパルスを適用し、継続的な制御には力または速度の拘束を使用します。
AssemblyLinearVelocityの設定は即時の状態変更であり、連続的な力のモデルではありません。 - メカニズムを作成または改訂する際は、
BodyPosition、BodyVelocity、BodyGyroやその他の非推奨の BodyMover よりも、アタッチメントと最新の拘束を優先してください。 - 自動所有権によって、近くにある固定されていないアセンブリの所有権がクライアントに移ることがあります。重要なオブジェクトには
SetNetworkOwner(nil)を慎重に使用し、応答性とサーバー負荷を測定してください。Studio でネットワーク所有者を可視化できます。 - クライアントが所有する物理演算の結果や
.Touchedによる検出は、クライアント側で操作される可能性があります。サーバーは重大な影響を伴うヒット、位置、タイミング、権限を独立して検証します。
よくある失敗
| 症状 | 考えられる原因 | 対処法 |
|---|---|---|
| 溶接されたメカニズムが動かない | パーツが1つ固定されている | アセンブリ全体を調べ、意図したワールドのルートだけを固定する |
| 力が強すぎる/弱すぎる | アセンブリの質量を考慮していない | AssemblyMass を調べ、意図する加速度に合わせて力/インパルスを調整する |
| 高速の飛翔体がヒットしない | 離散的な接触サンプリング/トンネリング | スイープクエリ — WorldRoot:Blockcast()、Spherecast()、または Shapecast() — と physics-tuning を使用し、.Touched だけに頼らない |
| レイが射手/エフェクトに当たる | フィルター/コリジョングループが設定されていない | 明示的なパラメーターとクエリグループを再利用する |
| 同じターゲットが何度もダメージを受ける | オーバーラップの結果に複数の身体パーツが含まれている | ターゲットモデルごとに重複を除外し、攻撃 ID/クールダウンを適用する |
| エクスプロイトがあり得ない接触を発生させる | 関連する物理演算をクライアントが所有している | サーバー側でクエリ/コンテキストを検証し、所有権を慎重に設定する |
| 見えないトリガーが妨げになる、またはクエリできない | 3つのフラグが混同されている | CanCollide、CanTouch、CanQuery を個別に設定する |
| メカニズムからアタッチメントが解放されず残る | 一時的な拘束のライフサイクルが未管理 | 拘束、アタッチメント、接続をまとめて管理し、破棄する |
リソース
- 衝突/クエリのマトリックス、アセンブリのデバッグ、所有権のセキュリティ、移行方法、物理演算の検証マトリックスについては、
references/queries-and-ownership.mdを読んでください。
関連スキル
physics-tuning— タイムステップ、ジッター、トンネリング、質量比、安定性の手法。roblox-characters— Humanoid/カスタム移動とリスポーンのライフサイクル。roblox-networking— クライアントが要求する物理アクションの権威ある検証。roblox-studio-workflow— 可視化、Output、マルチクライアントでの検証。
主なリファレンス
https://create.roblox.com/docs/physics/assemblieshttps://create.roblox.com/docs/physics/network-ownershiphttps://create.roblox.com/docs/workspace/raycasting