見出し画像

【Unity初心者向け】オブジェクトの回転② | Transform.Rotateでオブジェクトを回転させる

前回は、Transform の Rotation について確認し、transform.eulerAngles を使ってオブジェクトの回転角度を変更する方法を紹介しました。
例えば、

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

とすると、オブジェクトのZ軸の回転角度を45度にできます。
この方法は「オブジェクトを指定した角度に向けたい」という場合に分かりやすい方法です。

一方、ゲームを作っていると、

  • コインをくるくる回したい

  • プロペラを回転させたい

  • 障害物を回し続けたい

  • 敵を少しずつ旋回させたい

といった、現在の向きから少しずつ回転させたい場面もあります。
このようなときに便利なのが、

transform.Rotate()

です。
今回は、Transform.Rotateを使ってオブジェクトを回転させる方法を確認していきましょう。



1.Transform.Rotateとは?

Rotateは、オブジェクトを回転させるための命令です。
まずは、次のように書いてみましょう。

transform.Rotate(0, 0, 1);

このコードでは、

  • X軸:0度

  • Y軸:0度

  • Z軸:1度

の回転を加えています。

つまり、現在の向きからZ軸を中心に1度回転する、という意味です。
ここが、前回紹介したeulerAnglesとの大きな違いです。


1-1.eulerAngles と Rotateの違い

例えば、

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

と書いた場合は「Z軸の回転角度を30度にする」という指定になります。
一方、

transform.Rotate(0, 0, 30);

と書いた場合は「現在の向きからZ軸を中心に30度回転する」という意味になります。

例えば、すでにZ軸方向へ20度回転しているオブジェクトがあったとします。そこへ、

transform.Rotate(0, 0, 30);

を実行すると、20度 + 30度 ⇒ 50度 となります。
Rotateでは、現在の回転に新しい回転量を追加しているわけです。


2.Rotateを使ってみよう

2-1.FixedUpdate関数で使ってみる

では、オブジェクトを実際に回し続けてみましょう。
次のスクリプトを作成します。

public class RotateSample : MonoBehaviour
{
    void FixedUpdate()
    {
        transform.Rotate(0, 0, 1);
    }
} 

FixedUpdate()は初期設定で、ゲーム中、1秒間に50フレーム実行されます。
そのため、

transform.Rotate(0, 0, 1);

は1秒間に50度回転します。
例えば、最初の回転角度が 0 度だった場合、
0度 → 1度 → 2度 → 3度 → 4度 → ……
というように、少しずつ回転量が追加されます。
その結果、オブジェクトがくるくると回り続けます。



2-2.Update関数で使ってみる

先ほどのコードでは、

transform.Rotate(0, 0, 1);

のように、回転する量を直接書いていました。
しかし、この数字を変更するたびにスクリプトを書き換えるのは少し不便です。

そこで、回転速度を変数にしてみましょう。
今度はUpdate関数の中に書いてみます。

public class RotateSample : MonoBehaviour
{
    public float rotationSpeed = 1f;

    void Update()
    {
        transform.Rotate(0, 0, rotationSpeed);
    }
}

これで、InspectorからRotation Speedを変更できるようになります。

例えば、

Rotation Speed = 0.5f

ならゆっくり、

Rotation Speed = 2f

なら速く回転します。

ただし、このコードにはまだ問題があります。


2-3.デバイスによって回転速度が変わる

Update()は、毎秒決まった回数だけ実行されるわけではありません。
例えば、1秒間に60回Update()が実行される環境もあれば、1秒間に120回実行される環境もあります。

もし、

transform.Rotate(0, 0, 1);

を毎フレーム実行すると、

  • 60FPSなら 1度 × 60回 = 60度

  • 120FPSなら 1度 × 120回 = 120度

となります。

つまり、フレームレートが高い環境ほど速く回ってしまいます。
これは、以前オブジェクトの移動を作ったときにも出てきた問題です。

そこで使うのが、

Time.deltaTime

です。


2-4.Time.deltaTimeを使って回転する

コードを次のように変更します。

public class RotateSample : MonoBehaviour
{
    public float rotationSpeed = 100f;

    void Update()
    {
        transform.Rotate(
            0,
            0,
            rotationSpeed * Time.deltaTime
        );
    }
}

ポイントは、

rotationSpeed * Time.deltaTime

です。
Time.deltaTimeは、前のフレームから現在のフレームまでにかかった時間を表します。
これを使うことで、フレームレートの違いを考慮した回転にできます。

例えば、

rotationSpeed = 100f;

とした場合は、おおよそ1秒間に100度回転する、と考えることができます。
つまり、

rotationSpeed

を、1秒間に何度回転するか?という値として扱いやすくなるわけです。
ゲーム中に少しずつ動かしたり、回転させたりするときは、

Time.deltaTime

を組み合わせることを覚えておきましょう。


3.回転軸

Rotateでは、X・Y・Zのどこに値を入れるかによって、回転する軸が変わります。

3-1.X軸を中心に回転

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

X軸を中心に回転します。


3-2.Y軸を中心に回転

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

Y軸を中心に回転します。


3-3.Z軸を中心に回転

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

Z軸を中心に回転します。

2Dゲームで、画面上のオブジェクトをくるくる回したい場合は、Z軸を使うことが多くなります。


3-4.Vector3を使って書くこともできる

ここまでは、

transform.Rotate(0, 0, 100);

のように書いてきました。
しかし、RotateではVector3を使って回転方向を指定することもできます。

例えば、

transform.Rotate(
    new Vector3(
        0,
        0,
        rotationSpeed * Time.deltaTime
    )
);

と書くことができます。
意味はこれまでのコードと同じです。

さらにUnityには、

Vector3.right
Vector3.up
Vector3.forward

という便利な値があります。それぞれ、

Vector3.right   → X方向
Vector3.up      → Y方向
Vector3.forward → Z方向

を表します。
そのため、Z軸を中心に回転させるなら、

transform.Rotate( Vector3.forward * rotationSpeed * Time.deltaTime);

と書くこともできます。
以前、オブジェクトを移動させたときにも、

Vector3.right

や、

Vector3.up

を使いました。

移動では「どちらへ動くか」を表していましたが、Rotateではどの軸を中心に回転するか を指定するために利用できます。


4.回転のSelfとWorld

ここから少し発展的な内容です。

Transform.Rotateでは、どの座標軸を基準に回転するかを指定することができます。
Unityには、大きく分けて、

Self
World

という2つの考え方があります。
これは、以前紹介したTransform.Translateにも登場した考え方です。


4-1.Space.Self ― 自分自身の軸を使う

例えば、次のように書きます。

transform.Rotate(
    Vector3.up * rotationSpeed * Time.deltaTime,
    Space.Self
);

Space.Selfでは、オブジェクト自身が持っている軸を基準に回転します。
オブジェクトにはそれぞれ、

X
Y
Z

の向きがあり、オブジェクトが傾くと、この軸も一緒に傾きます。

Space.Selfでは、その傾いた軸を使って回転します。


4-2.Space.World ― 世界全体の軸を使う

一方、

transform.Rotate(
    Vector3.up * rotationSpeed * Time.deltaTime,
    Space.World
);

とすると、Unityのワールド座標の軸を基準に回転します。
オブジェクト自身がどの方向へ傾いていても、ワールドのX・Y・Z軸は変わりません。
その固定された軸を基準に回転します。



4-3.SelfとWorldを比較してみよう

例えば、あらかじめCubeを少し傾けておきます。
そして、一方には、

transform.Rotate(
    Vector3.up * rotationSpeed * Time.deltaTime,
    Space.Self
);

もう一方には、

transform.Rotate(
    Vector3.up * rotationSpeed * Time.deltaTime,
    Space.World
);

を設定します。

すると、同じ、

Vector3.up

を使っていても、回り方が変わります。

  • Space.Selfは、自分自身の傾いたY軸を中心に回転します。

  • Space.Worldは、ワールド全体のまっすぐなY軸を中心に回転します。


4-4.Space.Selfは省略できる

transform.Rotate(
    Vector3.up * rotationSpeed * Time.deltaTime
);

のように、Space.Self や Space.World を書かなかった場合は、基本的にSpace.Self として扱われます。

そのため、通常は短い書き方を使い、
ワールド座標を基準に回転したい場合にSpace.Worldを指定する
と考えてもよいでしょう。


5.eulerAnglesとRotate、どっちを使う

ここまで確認すると、

transform.eulerAngles

と、

transform.Rotate()

の使い分けも分かりやすくなります。

指定した角度にしたい場合

例えば

  • ゲーム開始時に90度にする

  • キャラクターを決まった方向へ向ける

といった場合は、

transform.eulerAngles

が分かりやすいでしょう。


現在の向きから回したい場合

例えば

  • コインを回し続ける

  • プロペラを回す

  • 回転する障害物を作る

といった場合は、

transform.Rotate()

が使いやすくなります。



14.今回のまとめ

今回は、Transform.Rotateを使ってオブジェクトを回転させる方法を確認しました。

次回は、キーボードの入力に合わせてオブジェクトを回転させる方法を確認します。

Input.GetAxisRaw("Horizontal")を使って左右キーの入力を取得し、右キーなら右回転、左キーなら左回転する動きを作ります。

キャラクターの向き変更だけでなく、車のハンドル操作や砲台の回転などにも応用できる基本的な仕組みです。


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


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

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


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

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

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