今回はUnity初心者の方向けの話題で、
という内容です。Unityでゲームを作っていると移動とかは割と簡単に理解できるのですが、回転について調べると「Quaternion(クォータ二オン)」などワケの分からない用語が出てきて思わず難しいなぁ…とため息が出てしまった初心者の方は多いのではないでしょうか。実際、私自身も初心者のころは回転のやり方がイマイチよくわからなくて毎回悪戦苦闘したものです。
そこでここではUnityでゲームオブジェクトを回転させる方法について、初心者の方を対象に
- アセットを使わず、Unityの標準機能だけでゲームオブジェクトを回転させる方法
- アセットを使って楽にゲームオブジェクトを回転させる方法
の2通りのやり方を解説していきますね。
アセットを使わずにゲームオブジェクトを回転させる方法まとめ
では、まずはアセットを使わずにUnityの標準機能だけでゲームオブジェクトを回転させる方法を説明していきます。標準機能だけでも細かいやり方が色々あるのですが、大まかに分けると
- オイラー角を使って直感的に回転させる方法
- Quaternion型を使って回転を作成する方法
- 指定した方向を向かせる方法
の3種類があるので、それぞれ詳しく見ていきましょう。
オイラー角を使って直感的に回転させる方法
まずは直感的に理解しやすい「オイラー角」を使って簡単に回転させる方法です。こちらの方法はゲームオブジェクトの移動処理を理解できた方ならすぐに使えるようになると思います。
前提:オイラー角とは?
オイラー角は簡単に言うと
です。つまりUnityでお馴染みのVector3で表現できる回転方法であり、人間が直感的に理解できるのが大きなメリットです。
C#スクリプトからオイラー角を使った回転を行う方法
オイラー角を使ってC#スクリプトからゲームオブジェクトを回転させる方法は主に次の2通りがあります。
- Transform.eulerAnglesを直接書き換える方法
- Transform.Rotate関数を使う方法
Transform.eulerAnglesを直接書き換える方法
using UnityEngine; public class EulerAnglesSample : MonoBehaviour { [SerializeField] float angularSpeed = 360f; void Update() { transform.eulerAngles += angularSpeed * Time.deltaTime * Vector3.forward; } }
一つ目は、ゲームオブジェクトのTransformに「eulerAngles」というオイラー角での回転角度を記録する変数があるのでそれを直接書き換える方法です。上のサンプルスクリプトのようにUpdate関数内で毎フレーム実行するとゲームオブジェクトがクルクルと回転するようになります(下のGIF参照)。
なお、このようにUpdate内で毎フレーム呼び出すときは角度に「Time.deltaTime」を掛けて「1フレームあたりの回転角度」に変換するようにしましょう。こうしないと凄まじい速さで回転するようになってしまいます。
あと余談ですが、eulerAnglesはワールド空間での回転量を示す変数なので、ローカル空間で回転させたい場合は「localEulerAngles」を使いましょう。
Transform.Rotate関数を使う方法
using UnityEngine; public class EulerAnglesSample : MonoBehaviour { [SerializeField] float angularSpeed = 360f; void Update() { transform.Rotate(angularSpeed * Time.deltaTime * Vector3.forward, Space.World); } }
二つ目はtransformに用意されている「Rotate」関数を使う方法です。この関数の引数は
- 第一引数:オイラー角のVector3
- 第二引数:回転の基準がワールド空間かローカル空間かを指定
となっています。
Quaternion型を使って自由自在に回転を作成する方法
次は理解するのが少し難しい「Quaternion(クォータニオン)」を使った回転のやり方です。
先ほど説明したオイラー角のやり方でもゲームオブジェクトを回転できるので「わざわざ難しいのを使うのは嫌だなぁ」と思う方もいらっしゃるかもしれませんが、Quaternionを使うと自由自在に回転を操れるようになるので、余裕のある方はぜひもう少し頑張ってみてください。
前提:Quaternionとは?
Quaternionは別名で四元数とも呼ばれ、その名の通り4つの成分(x,y,z,w)から構成されます。ただ、こちらはオイラー角とは違って直感的に理解するのは難しいですし、私もQuaternionの仕組みを熟知しているわけではないので難しい説明はここでは省略させて頂きます。もし詳しく知りたい場合は以下の記事が秀逸なのでそちらをご参照ください。
なぜそんな難しいものをわざわざ使うのかというと、Quaternionには「あらゆる回転を正確に表現できる」というメリットがあるからです。実はオイラー角は場合によっては回転に制限がかかってしまうことがあります(※ジンバルロックという現象が発生します)。一方でQuaternionであればどんな回転でも問題なく表現できるので難しい分Quaternionのほうが便利なのです。
C#スクリプトからQuaternion型を使った回転を行う方法
Quaternionを使った回転方法は色々あるのですが、ここでは最も簡単な「Quaternion.AngleAxis」をサンプルとしてご紹介します(※でもゲームを作る際はあまり使わないかも…)。
using UnityEngine; public class QuaternionSample : MonoBehaviour { [SerializeField] float angularSpeed = 360f; void Update() { transform.rotation *= Quaternion.AngleAxis(angularSpeed * Time.deltaTime, Vector3.forward); } }
Quaternion.AngleAxis関数は「ある回転軸の周りの、指定した角度の回転」を作成します。引数は
- 第一引数:回転角度
- 第二引数:回転軸
となっています。
ちなみにQuaternionを扱う際のポイントなのですが、Quaternion同士なら足し算(というか合成)を行うことが可能です。ただし足すときは「+」ではなく「*」(=掛け算記号)を使うので注意しましょう。上のサンプルでは元々の回転(transform.rotation)に新しく作ったQuaternionの回転を合成することでゲームオブジェクトをクルクルと回転させる動きを実現しています。
指定した方向を向かせる方法
さてゲームを作っていると、直接回転を指定するというよりは例えば「他のゲームオブジェクトの方向を向かせたい」といった状況のほうが多いと思います。そのような場合の回転のやり方は主に次の2つが挙げられます。
- Transform.LookAt関数を使う方法
- Quaternion.LookRotation関数を使う方法
Transform.LookAt
using UnityEngine; public class LookAtSample : MonoBehaviour { [SerializeField] Transform target; void Update() { transform.LookAt(target); } }
ゲームオブジェクトを指定したTransformまたは座標を向くように回転させます。簡単に使うことができますが、そのままだと一瞬でターゲットの方向を向くような動作になるので使いどころが少し難しいかもしれません(※例えばキャラクターを振り向かせたいときは不自然になってしまいます)。
Quaternion.LookRotation
using UnityEngine; public class LookAtSample : MonoBehaviour { [SerializeField] Transform target; void Update() { transform.rotation = Quaternion.LookRotation(target.position - transform.position); } }
第一引数に方向を渡すとそちらに向く回転を得ることができる関数です(※引数に渡すのは座標ではないので注意)。こちらは他の関数と組み合わせることで滑らかに回転させたり、ゆっくり回転させたりすることができるといったメリットがあります。
ちなみに、あるゲームオブジェクトAから他のゲームオブジェクトBへの方向が欲しい場合は
を計算すればOKです。
アセットを使って簡単にゲームオブジェクトを回転させる方法
さて、ここまではUnityの標準機能を使ってゲームオブジェクトを回転させる方法を長々と説明してきました。しかし実際にゲームを作るときに回転でいちいち頭を悩ませるのは嫌ですよね。できることならもっと手軽に回転を扱いたいものです。
そこで私は「DOTween」という便利アセットを必ずと言っていいほど使っています。
詳しい説明は以下の記事に書いたので省略しますが、このアセットを使えばゲームオブジェクトを滑らかに移動・回転・拡大縮小できます。
例えば、ゲームオブジェクトを「2秒間でZ軸方向に180度回転させる」場合のサンプルコードは次の通り。
using UnityEngine; using DG.Tweening; public class TweenSample : MonoBehaviour { [SerializeField] Vector3 angle = new Vector3(0, 0, 180); [SerializeField] float duration = 2f; void Start() { transform.DORotate(angle, duration); } }
たった一行で指定した回転を・指定した時間で完了するように設定できるので非常に役に立ちます。興味のある方は是非チェックしてみてください。
おわりに
以上、Unityの回転について一通り説明してきました。結論を言うと
という話なのですが、Unityの標準機能の使い方も理解しておくと役に立つのでぜひ上記の内容を覚えておいて頂ければと思います。
この記事がUnityでのゲーム開発のお役に立てば幸いです。