回転するオブジェクトは、3D空間内で1つまたは複数の軸の周りを回転するオブジェクトです。Robloxのシミュレーションエンジンの組み込み機能を使用することで、オブジェクトを回転させ、重力、空気力学、摩擦など、プレイヤーにとって馴染みのある直感的な方法で環境と相互作用させることができます。
回転するオブジェクト .rbxlファイルを参照として、このチュートリアルでは、物理的な力がスタジオ内の角運動にどのように影響するかを説明し、さまざまな回転動作を持つオブジェクトをゲーム内で回転させるための技術を示します。これには以下のガイダンスが含まれます:
- AngularVelocityモーバー制約を使用して、全体のアセンブリを一定の角速度で回転させる。
- HingeConstraint機械的制約を使用して、アセンブリ内のパーツを一定の角速度で回転させるが、アセンブリの残りの部分は静止したままにする。
- ApplyAngularImpulseメソッドを使用して、初期の角力のインパルスでアセンブリを回転させ、アセンブリが時間とともにゆっくり減速するようにする。
角運動と物理的力
Roblox Studioは、リアルタイムで物理的な挙動をエミュレートする現実世界のシミュレーションエンジンであるため、ゲーム内の回転するオブジェクトの挙動を予測するには、現実世界でのオブジェクトの回転に関する高レベルの理解が重要です。
角運動、または回転運動は、固定された点または軸の周りの動きです。たとえば、プロペラが角運動を持つとき、それはプロペラの中央の回転軸の周りを回転します。

角運動は、オブジェクトを回転させるために外部の物理的力が押したり引いたりすることがなければ存在できません。ニュートンの運動の第一法則によれば、静止しているオブジェクトは静止し続け、動いているオブジェクトは外部の力が作用しない限り、一定の速度で動き続けます。たとえば、静止しているプロペラは、風のような物理的力がそれを回転させるまで静止したままです。
トルクは、オブジェクトを回転させる物理的力の測定値であり、オブジェクトが角加速度を得る原因となります。この概念は、スタジオ内でオブジェクトを回転させるために特に重要です。トルクをオブジェクトに適用すればするほど、より早く加速できます。
これは、トルクが重力や摩擦のようなオブジェクトに対して押し返す方向の物理的力よりも_大きい_必要があるからです。たとえば、プロペラを土の中に置くと、風の物理的力は、回転するプロペラを加速し続けるために土からの摩擦を克服する必要があります。風の力が土からの摩擦よりも大きくない場合、プロペラは加速しますが、前の例よりも遅くなります。

角速度は、オブジェクトの回転速度、またはオブジェクトが固定された点または軸の周りを回転する速さを時間の経過に伴って測定したものです。スタジオは、オブジェクトが1秒間に回転するラジアンの数に応じて角速度を測定します。1回転には2πラジアン(6.283)があるため、オブジェクトが1秒間に1回転するためには、約6ラジアン回転するのに十分なトルクが必要です。角速度を理解することは、ゲーム内でのゲームプレイを設計する上で重要です。なぜなら、回転するオブジェクトに特定の加速度を達成するために必要なトルクの量を決定するのに役立つからです。
以下のセクションでは、これらの概念をさらに深く掘り下げ、必要なトルクを持って環境内の反対の物理的力を克服しながら、一定または初期の角速度でオブジェクトを回転させる方法を学びます。これからの技術を通じてこれらの物理学の概念を見直すことで、スタジオ内で理想的な回転動作を達成するためにプロパティ値を調整する方法をより正確に予測できるようになります。
一定の角力を維持する
オブジェクトが一定の角速度に達し、それを維持するためには、オブジェクトの角速度を減速させるか、オブジェクトを静止させる反対の物理的力を克服するための角力が必要です。たとえば、スタジオでオブジェクトに角速度[0, 12, 0]を持たせたい場合、オブジェクトが環境内でY軸に沿って1秒間に12ラジアンに達し、維持するために十分なトルクが必要です。これは、約2回転に相当します。
オブジェクトに適用するトルクの量は、環境内の反対の物理的力(重力や摩擦など)だけでなく、オブジェクト自体にも依存します。たとえば、同じ軸で回転している同じ形状の2つのオブジェクトがある場合、より大きなオブジェクトは、同じ角加速度を達成するためにより多くの慣性モーメントが必要です。
以下のサブセクションでは、異なる形状とサイズのアセンブリを使用して、オブジェクト全体を回転させる方法や、オブジェクトの一部だけを回転させる方法を教えます。さまざまなプロパティ値を試すことで、自分のゲーム内のアセンブリに必要な最大トルクを見積もる方法を学びます。
AngularVelocity制約を使用する
AngularVelocityオブジェクトは、一定の角速度を維持するために全体のアセンブリにトルクを適用するモーバー制約の一種です。アセンブリを回転させるには、AngularVelocity制約が以下の情報を知る必要があります:
- 角力を適用する点と正または負の方向。
- アセンブリが1秒間に回転させたいラジアンの量。
- アセンブリが一定の角速度に達するためにエンジンが適用できる最大トルクの量。
このプロセスを示すために、ワークスペースにブロックを追加し、AngularVelocity制約が参照するアタッチメントを追加して、ブロックを世界のY軸に沿って一定の角速度で1秒間に6ラジアン回転させます。

アタッチメントを追加する
アセンブリを回転させるための固定点を指定するには、アセンブリにAttachmentオブジェクトを追加し、3D空間内でアタッチメントの位置を設定します。サンプルの回転するオブジェクトゲームでは、制約がパーツの中心で反時計回りに回転できるように、ブロックパーツの中心にアタッチメントを配置しています。
アタッチメントには、回転軸を視覚化するための視覚的な補助が含まれています。黄色の矢印はアタッチメントの主軸を示し、オレンジの矢印はアタッチメントの副軸を示します。この技術のステップでは、どちらの回転軸もブロックの回転に影響を与えませんが、将来的に異なるタイプの制約(次の技術でのHingeConstraintなど)の理想的な動作を決定するのに役立つため、これらの視覚的補助を理解することが重要です。

アタッチメントを追加するには:
Explorerウィンドウで、Workspaceにブロックパーツを挿入します。

新しいパーツにアタッチメントを挿入します。
- Explorerウィンドウで、パーツの上にカーソルを合わせて⊕ボタンをクリックします。コンテキストメニューが表示されます。
- メニューからAttachmentを挿入します。アタッチメントがパーツの中心に表示されます。
- アタッチメントの名前をSpinAttachmentに変更します。

制約を設定する
ブロックに回転させるための固定点ができたので、AngularVelocity制約のプロパティを設定して、回転方向、目標の一定の角速度を適用する軸、ブロックが1秒間に回転させたいラジアンの量、ブロックが一定の角速度に達するためにエンジンが適用できる最大トルクの量を指定できます。
サンプルの回転するオブジェクトゲームでは、ブロックを世界のY軸に沿って1秒間に6ラジアン回転させるために、最大1000 Rowtonスタッドの一定の角力を適用します。Rowtonスタッドは、トルクを測定するためのRobloxの主要な物理単位です。Robloxの物理単位とそれがメートル法単位に変換される方法については、Robloxの単位を参照してください。
AngularVelocity制約を設定するには:
制約の回転方向を参照できるように、ビューポートで制約を表示するために、スタジオのViewメニューからShow Constraint Detailsを有効にします。
パーツにAngularVelocity制約を挿入します。
- Explorerウィンドウで、パーツの上にカーソルを合わせて⊕アイコンをクリックします。コンテキストメニューが表示されます。
- コンテキストメニューからAngularVelocityを挿入します。制約の視覚的補助がパーツの中央に表示されます。
パーツのアタッチメントを新しい制約に割り当てます。
- Explorerウィンドウで、制約を選択します。
- Propertiesウィンドウで、
- Attachment0をSpinAttachmentに設定します。
- AngularVelocityを0, 6, 0に設定して、パーツをY軸に沿って1秒間に6ラジアン回転させます。このプロパティを0, -6, 0に設定すると、ブロックは時計回りに回転します。
- MaxTorqueを1000に設定して、目標の角速度を達成するために1秒間に最大1000 Rowtonスタッドの一定の角力を適用します。
- RelativeToをWorldのままにして、ブロックを世界の位置と向きに対して回転させます。

設定したトルクの量がブロックを世界のY軸に沿って1秒間に6ラジアン回転させることを確認します。
メザニンのドロップダウンメニューからRunシミュレーションモードを選択し、Playボタンをクリックして開始します。スタジオは、3D空間内でアバターなしで現在のカメラ位置でゲームをシミュレートします。

ブロックのスケールや環境内の反対の物理的力に応じてトルクを調整する必要があるかもしれません。たとえば、サンプルゲームのAngularVelocity制約のプロパティは、デフォルトサイズ4, 1, 2のブロックパーツがプラスチック素材の平坦なプラットフォーム上にある場合に機能しますが、クラシックプリセットの重力を持つ環境です。
ただし、ブロックが大きなサイズで草地にある場合、AngularVelocity.MaxTorqueプロパティを増やす必要があります。なぜなら、角力はブロックの質量と環境からの摩擦の両方を克服する必要があるからです。たとえば、サンプルのパーツの4倍のサイズの大きなブロックパーツは、設定された角速度を達成するために少なくとも300000 Rowtonスタッドの一定の角力が必要です!
HingeConstraint制約を使用する
HingeConstraintオブジェクトは、2つのアタッチメントが1つの軸の周りで回転できるようにする機械的制約の一種です。この制約は、アタッチメントを同じ位置に固定し、主軸を同じ方向に制約します。HingeConstraint.ActuatorTypeをMotorに設定すると、この制約は2つのアタッチメントにトルクを適用し、アタッチメントが一定の角速度に達し、維持することを目指します。
さらに、アセンブリ内に2つのオブジェクトを持つアタッチメントを配置すると、オブジェクトはロックされ、アタッチメントの固定された主軸に従って一緒に回転しようとします。これらのオブジェクトの1つを固定すると、角力は他のオブジェクトを一定の角速度で回転させ続け、アセンブリの残りの部分は静止したままになります。
たとえば、アセンブリ内の特定のオブジェクトを回転させるには、HingeConstraint制約が以下の情報を知る必要があります:
- アタッチメントが重なる位置。
- 角力を適用する点と正または負の方向。
- アタッチメントが1秒間に回転させたいラジアンの量。
- アタッチメントが一定の角速度に達するためにエンジンが適用できる最大トルクの量。
このプロセスを示すために、プロペラアセンブリをワークスペースに追加し、両方のオブジェクトにアタッチメントを追加して、HingeConstraint制約が参照するようにし、プロペラをY軸に沿って1秒間に3ラジアン(約半回転)回転させます。

プロペラアセットを取得する
Creator Storeは、プロジェクト内で使用するためにRobloxとRobloxコミュニティによって作成されたすべてのアセットを見つけるために使用できるToolboxのタブです。モデル、画像、メッシュ、オーディオ、プラグイン、ビデオ、フォントアセットを含みます。Creator Storeを使用して、個々のアセットやアセットライブラリを直接オープンゲームに追加できます。
このチュートリアルでは、HingeConstraint技術の各ステップを再現するために使用できるプロペラモデルを参照しています。このプロペラアセットをインベントリからゲームに取得するには:
プロペラをインベントリに追加します。
- アセットの詳細ページに移動します。
- 右上隅でGet Modelボタンをクリックします。プロペラアセットがインベントリに追加され、プラットフォーム上の任意のプロジェクトで再利用できます。
スタジオで、Homeタブに移動し、Toolboxボタンをクリックします。Toolboxウィンドウが開きます。

Toolboxウィンドウで、Inventoryタブをクリックします。My Modelsのソートが表示されます。

Propellerタイルをクリックします。モデルがビューポートに表示されます。

アタッチメントを設定する
アセンブリ内の特定のオブジェクトを回転させるために、アタッチメントが重なる位置と回転運動の方向を指定するには、2つのAttachmentオブジェクトをアセンブリに追加し、それらの整列と向きを3D空間内で設定します。
サンプルの回転するオブジェクトゲームでは、固定されていないプロペラが固定されたベースと重なる位置の近くに2つのアタッチメントを整列させ、主回転軸を上向きに向けて反時計回りに回転させます。この例では、ベースアタッチメントは固定されているため、回転できません。
ヒンジ制約のためにアタッチメントを設定するには:
HeadとBaseにAttachmentオブジェクトを挿入します。
- Explorerウィンドウで、Headの上にカーソルを合わせて⊕ボタンをクリックします。コンテキストメニューが表示されます。
- メニューからAttachmentを挿入します。
- Baseについても同様のプロセスを繰り返します。
- 両方のアタッチメントの名前をそれぞれHeadAttachmentとBaseAttachmentに変更します。

HeadAttachmentとBaseAttachmentを回転させて、各アタッチメントの主軸がY軸上で上向きになるようにします。これにより、スタジオはアタッチメントを反時計回りに回転させることができます。

BaseAttachmentをBaseの上部に、HeadAttachmentをPropellerの下端に移動させます。これにより、スタジオはヒンジ自体を接続する場所を指定し、ランタイム中に両方のアタッチメントが重なるようにします。

制約を設定する
アタッチメントが重なる位置と回転運動の方向を持つようになったので、HingeConstraint制約のプロパティを設定して、アタッチメントが1秒間に回転させたいラジアンの量と、アタッチメントが一定の角速度に達するためにエンジンが適用できる最大トルクの量を指定できます。
前の技術と同様に、サンプルの回転するオブジェクトゲームでは、アタッチメントをY軸に沿って1秒間に3ラジアン回転させるために、最大1000 Rowtonスタッドの一定の角力を適用します。ただし、ベースアタッチメントが固定されたオブジェクトにあるため、プロペラのアタッチメントのみが回転できます。
ヒンジ制約を設定するには:
HeadにHingeConstraintオブジェクトを挿入します。
- Explorerウィンドウで、Headの上にカーソルを合わせて⊕アイコンをクリックします。コンテキストメニューが表示されます。
- コンテキストメニューからHingeConstraintを挿入します。
プロペラのアタッチメントを新しい制約に割り当てて、プロペラが固定されたベースに関連して回転するようにします。
- Explorerウィンドウで、制約を選択します。
- Propertiesウィンドウで、
- Attachment0をBaseAttachmentに設定します。
- Attachment1をHeadAttachmentに設定します。ヒンジがビューポートに表示されます。

Explorerウィンドウで、制約を選択し、Propertiesウィンドウで、
- ActuatorTypeをMotorに設定します。新しいプロパティフィールドが表示されます。
- MotorMaxTorqueを1000に設定して、目標の角速度を達成するために最大1000 Rowtonスタッドの一定の角力を適用します。
- AngularVelocityを3に設定して、プロペラの頭部を1秒間に3ラジアン回転させます。

設定したトルクの量がプロペラをY軸に沿って1秒間に3ラジアン回転させることを確認します。
メザニンのドロップダウンメニューからRunシミュレーションモードを選択し、Playボタンをクリックして開始します。スタジオは、3D空間内でアバターなしで現在のカメラ位置でゲームをシミュレートします。

初期の角力を適用する
オブジェクトの角速度を変更する別の方法は、角力のインパルスを適用することです。角力のインパルスの後、オブジェクトは摩擦のような反対の力がある場合は減速して静止するか、反対の力がない場合は一定の速度で動き続けます。
この技術は、強風のような重要なゲームプレイや天候イベントの後にオブジェクトを回転させるのに便利です。なぜなら、プレイヤーに瞬時のフィードバックを提供するからです。次のサブセクションでは、初期のランダムな角力でアセンブリを回転させる方法を教えます。この値を新しい値に適応させて、自分のゲームプレイ要件に合わせることができます。
ApplyAngularImpulseを使用する
ApplyAngularImpulseメソッドは、アセンブリ全体にトルクを適用して初期の角速度を得るために使用され、停止するまで減速します。アセンブリを回転させるには、メソッドが以下の情報を知る必要があります:
- 回転させるアセンブリ。
- 初期の角速度に達するためにトルクを適用する軸。
- 各軸に適用するトルクの量。
これらの値はすべてスクリプト内で定義できます。たとえば、サンプルスクリプトでは、回転させるアセンブリをスクリプトの親として定義し、Y軸に沿って0から100 Rowtonスタッドの間のランダムな角力のインパルスを適用します。
ApplyAngularImpulseを使用してアセンブリを回転させるには:
Workspaceに球パーツを挿入します。サンプルでは、球の動きを明確に視覚化できるようにMaterialVariantを持つ球を使用します。

新しいパーツにスクリプトを挿入します。
- Explorerウィンドウで、パーツの上にカーソルを合わせて⊕ボタンをクリックします。コンテキストメニューが表示されます。
- メニューからScriptを挿入します。
デフォルトのコードを以下のコードに置き換えます:
local part = script.Parent
local impulse = Vector3.new(0, math.random(0, 100), 0)
part:ApplyAngularImpulse(impulse)