見出し画像

【Unity初心者向け】オブジェクトの回転⑥ | AddTorqueで力を加えて回転させる

これまでの記事では、Transform や Rigidbody2D を使って、オブジェクトを回転させる方法を確認してきました。

前回は、

rb.angularVelocity = 100f;

のように、angularVelocityを使って回転速度を変更する方法や、

rb.MoveRotation(angle);

を使って、Rigidbody2Dから回転させる方法を確認しました。

今回は、Rigidbody2Dを使ったもう1つの回転方法、

AddTorque()

について確認します。
AddTorque()は、オブジェクトへ回転させる力を加える命令です。
Rigidbodyを使った移動編で登場した、

AddForce()

の回転版と考えると分かりやすいでしょう。

今回の記事では、

  • AddTorqueとは

  • Torqueとは

  • angularVelocityとの違い

  • Angular Damping

  • ForceMode2D

  • MassとInertia

などについて確認していきます。


1.AddForceとAddTorque

1-1.AddForceとAddTorqueの違い

まずは、移動と回転の関係から整理してみましょう。
Rigidbody2Dを使ってオブジェクトを移動させるときには、

rb.AddForce(Vector2.right * power);

のようにAddForce()を使うことができます。
AddForce()は、オブジェクトへ力を加える命令です。
力を加えた結果として、オブジェクトの速度が変化します。

一方、今回使用する、

rb.AddTorque(torquePower);

は、オブジェクトへ回転させる力を加えます。

移動編でAddForce()を理解していれば、今回のAddTorque()も同じような考え方で理解できます。


1-2.Torqueとは?

ここで、Torque(トルク)って何?と思うかもしれません。
Torqueは簡単に言えば「物体を回転させようとする力」です。

例えば、ドアをイメージしてみましょう。
ドアノブを押すと、ドアが回転して開きます。
このとき、ドアを回転させようとする力がトルクです。

Unityでは、

rb.AddForce(...)

が、オブジェクトを押す力 だとすれば、

rb.AddTorque(...)

は、オブジェクトを回す力と考えると分かりやすいでしょう。


2.AddTorqueを使ってみよう

まずは実際にオブジェクトを回転させてみましょう。

2-1.Rigidbo2Dとスクリプトの追加

回転させたいオブジェクトに Rigidbody2D を追加します。

そして、次のスクリプトを作成します。

Rigidbody2D rb;          // Rigidbody2Dへの参照
public float torquePower = 10f; // 回転の強さ

void Start()
{
    // Rigidbody2Dコンポーネントを取得
    rb = GetComponent<Rigidbody2D>();
}

void FixedUpdate()
{
    // 水平方向の入力を取得
    rb.AddTorque(torquePower);
}

作成したスクリプトをオブジェクトに追加します。

ゲームを実行すると、オブジェクトが回転します。

今回重要なのは、

rb.AddTorque(torquePower);

の部分です。

AddTorque()は、Rigidbody2Dの重心にトルクを加え、その結果としてangularVelocity、つまり回転速度を変化させます。




2-2.angularVelocityとの違い

前回の記事では、

rb.angularVelocity = 100f;

という処理を使いました。

では、

rb.angularVelocity = 100f;

と、

rb.AddTorque(10f);

では何が違うのでしょうか。
この違いは非常に重要です。


angularVelocityの場合

rb.angularVelocity = 100f;

これは、回転速度を100にするという命令です。
つまり、回転速度を直接変更しています。


AddTorqueの場合

一方、

rb.AddTorque(10f);

は、回転させる力を加えるという命令です。
回転速度そのものを指定しているわけではありません。

AddTorque
    ↓
回転する力を加える
    ↓
angularVelocityが変化する
    ↓
オブジェクトが回転する

という流れになります。

Unity公式ドキュメントでも、AddTorque()によって変化するのはRigidbody2D の angularVelocity であり、その変化量には回転慣性が影響すると説明されています。


2-3.徐々に回転速度が変化する

次の処理では、

void FixedUpdate()
{
    rb.AddTorque(torquePower);
}

FixedUpdate()が実行されるたびにトルクを加えています。
そのため、

最初
  ↻

少し後
 ↻ ↻

さらに後
↻ ↻ ↻ ↻

というように、回転速度が徐々に変化していきます。
これは移動編でAddForce()を使ったときとよく似ています。

AddForce()の場合は、

力を加える
↓
移動速度が変化する

でした。
AddTorque()では、

回転する力を加える
↓
回転速度が変化する

となります。

この違いを覚えておきましょう。


3.Angular Dampingとは?

AddTorque()を使ってオブジェクトを回転させると、一度回り始めたオブジェクトはどうやって減速するの?という疑問が出てきます。

ここで関係してくるのが、Angular Damping です。

Rigidbody2DのInspectorを見ると、Angular Dampingという項目があります。

Angular Dampingは、回転速度を徐々に減らすための抵抗 と考えると分かりやすいでしょう。


Angular Dampingが小さい場合

Angular Dampingが小さい場合は、回転速度が落ちにくくなります。

例えば、

Angular Damping = 0

のようにすると、回転に対する減衰がほとんどありません。


Angular Dampingが大きい場合

Angular Dampingを大きくすると、回転速度が早く減少します。

つまり、値が大きいほど回転が止まりやすくなる、と考えることができます。

Unity 6のRigidbody2Dでは、回転速度の減衰をAngular Dampingとして扱います。
古いUnityでは、この項目がAngular Dragという名前で表示されていたバージョンもあります。


4.ForceMode2Dを使ってみよう

AddTorque()には、トルクの加え方を指定することもできます。

例えば、

rb.AddTorque(
    torquePower,
    ForceMode2D.Force
);

のように書きます。
ForceMode2D には、以下の2つの指定方法があります。

  • ForceMode2D.Force

  • ForceMode2D.Impulse

があります。


ForceMode2D.Force

rb.AddTorque(
    torquePower,
    ForceMode2D.Force
);

Force は、継続的に力を加えるときに使います。
例えば、

  • モーターで回転させる

  • タイヤを回し続ける

  • プロペラを回転させる

といった動きを考えると分かりやすいでしょう。

なお、

rb.AddTorque(torquePower);

のように ForceMode2D を省略した場合も、デフォルトではForceMode2D.Force が使用されます。


ForceMode2D.Impulse


rb.AddTorque(
    torquePower,
    ForceMode2D.Impulse
);

Impulseは、一瞬だけ強い力を加えたいときに使います。
例えば、

  • 爆発に巻き込まれて回転する

  • 敵に攻撃されて吹き飛ぶ

  • ボールに回転を与える

  • 物体へ衝撃を与えて回転させる

移動編のAddForce()で使ったForceMode2Dと同じ考え方ですね。


5.Massを大きくすると回転しにくくなる?

ここで、もう1つ確認しておきたいのがMassです。

移動編では、Massが大きいオブジェクトほど、同じAddForceでは加速しにくいことを確認しました。
実際、UnityのAddForce()ではMassが大きいほど、同じ速度変化を得るためにより大きな力が必要になります。

では、回転ではどうでしょうか。
回転の場合は、もう1つ重要な値があります。
それが、Inertia(慣性モーメント)です。


5-1.Inertiaとは?

Inertiaは、回転速度の変化に対する抵抗 を表します。
簡単に言えば、どれくらい回転しにくいか、を表す値です。

例えば、Inertiaが小さい
→  少しのTorqueでも クルッと回りやすい

一方、Inertiaが大きい
→ 同じTorque で回転速度が変化しにくい

となります。

Unityでは、Inertia が大きいほど AddTorque() による angularVelocity の変化が小さくなり、Inertia が小さいほど変化が大きくなります。

Inertia は Rigidbody2D の Inspector では通常、Info欄に計算結果として表示されます。
値を直接変更したい場合は、Rigidbody2D.inertia をスクリプトから設定できます。

例えば、

rb.inertia = 0.5f;

なら回転速度が変化しやすく、

rb.inertia = 10f;

なら同じ AddTorque() でも回転速度が変化しにくくなります。


5-2.MassとInertiaの関係

Inertiaは、Mass とも関係しています。
Unityでは、Rigidbody2D の Mass などをもとに回転慣性が計算されます。

そのため、Massを変更すると回転のしやすさにも影響する 場合があります。
ただし、回転について考える場合は、

  • 移動 → Massが重要

  • 回転 → Inertiaが重要

と考えておくと分かりやすいでしょう。
最初のうちは、

Inertia = 回転するときの重さのようなもの

くらいのイメージでも十分です。


6.左右キーで回転させてみよう

ここまでの内容を使って、左右キーでオブジェクトを回転させてみましょう。

6-1.スクリプトの作成

次のように書きます。

Rigidbody2D rb;          // Rigidbody2Dへの参照
public float torquePower = 10f; // 回転の強さ

void Start()
{
    // Rigidbody2Dコンポーネントを取得
    rb = GetComponent<Rigidbody2D>();
}

void FixedUpdate()
{
    // 水平方向の入力を取得
    float x = Input.GetAxisRaw("Horizontal");
    // Rigidbody2Dの角速度を設定して回転させる
    rb.AddTorque(-x * torquePower); 
}

まず、

float x = Input.GetAxisRaw("Horizontal");

で左右入力を取得しています。
左右入力では、

左キー  → -1
入力なし → 0
右キー  → 1

という値を取得できます。
その値を、

rb.AddTorque(-x * torquePower);

へ使用します。
これによって、左右キーに合わせて反対方向のトルクを加えられます。

今回のサンプルの戦車の動きであれば、Angular Damping を 5 程度に設定すると、ちょうどよいと思います。


6-2.なぜFixedUpdateを使うの?

今回の処理では、

void FixedUpdate()
{
    rb.AddTorque(torquePower);
}

のように、FixedUpdate()を使っています。
Rigidbody2DはUnityの物理演算によって動いています。
そのため、

  • AddForce

  • AddTorque

  • MoveRotation

など、Rigidbody2Dへ継続的に物理的な操作を行う処理では、FixedUpdate()を使うことが多くあります。

移動編や前回の記事でも登場した考え方ですね。


7.angularVelocity と AddTorqueの使い分け

ここまで確認すると、

angularVelocityとAddTorque、結局どちらを使えばいいの?

と思うかもしれません。
これは、どのような回転を作りたいかによって変わります。


一定の回転速度にしたい

例えば、

  • 常に一定速度で回るトラップ

  • 回転する床

  • 一定速度で回り続けるオブジェクト

なら、

rb.angularVelocity = 100f;

のようにangularVelocityを使うと分かりやすいでしょう。


徐々に加速する回転を作りたい

例えば、

  • タイヤ

  • モーター

  • プロペラ

  • 回転する物体

  • 衝撃による回転

など、物理的な回転を表現したい場合は、

rb.AddTorque(torquePower);

が向いています。


回転方法を整理しよう

今回のシリーズでは、いくつかの回転方法を確認してきました。

最後に、それぞれの違いを整理してみましょう。


Transformで回転角度を指定する

transform.eulerAngles = new Vector3(0, 0, angle);

指定した角度へ直接変更したいときに使えます。


Transform.Rotateで回転量を追加する

transform.Rotate(0, 0, rotateSpeed * Time.deltaTime);

現在の向きから、さらに回転させたいときに使えます。
単純にオブジェクトを回し続けたい場合にも便利です。


LookAtやAtan2で方向を向かせる

プレイヤーやマウスなど、指定した対象の方向を向かせたい場合に使用できます。


MoveRotationで回転する

rb.MoveRotation(angle);

Rigidbody2Dを使いながら、指定した角度へ回転させたい場合に使用できます。


angularVelocityで回転する

rb.angularVelocity = 100f;

回転速度を直接指定したい場合に使用できます。


AddTorqueで回転する

rb.AddTorque(torquePower);

回転する力を加えたい場合に使用します。

力を加えた結果として回転速度が変化するため、物理演算を利用した回転を作ることができます。


こちらはUnity初心者向けの記事をテーマ別にまとめています。
▼ Unity初心者向け記事まとめはこちら


こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!