【Unity】Quaternionでオブジェクトを回転させる方法


Unityでオブジェクトを回転させる時に使用するのがRotationQuaternionです。

ただ、このQuaternion、概念とか使い方がややこしく上手く使えないという方は多いと思います。

今回はQuaternionをすぐに使えるように、概要や使用例(スクリプト例)をご紹介します

難しい概念の理解は後でも大丈夫なので、「ひとまずなんとなく使えるように」ということを目的としています。

  • Quaternionとは?
  • Quaternionの使い方・サンプル

Quaternionとは? – 概要と特徴をご紹介!

Quaternionを簡潔に説明!

Quaternionクォータニオン)は四元数とも呼ばれ、Unityでオブジェクトを回転させる際に使用する数です。

Quaternion自体の理論は数学的な話になり難しいものですが、Unityでさくっと使用する分には特徴を掴むだけで十分です。

単純に回転の向き回転の大きさを表現する数だと捉えてもらうと良いかもしれません。

少し気を付けてほしい部分は、UnityのInspectorビューでRotation(物体の回転状態)を指定できるのですが、ここではオイラー角(度数法、1周を360度とした馴染み深い数)を使っています。

このように一見Unityでは回転をオイラー角で指定しているように思えますが、実は入力したオイラー角を内部で勝手にQuaternionとして計算し保持しているのです

つまり、Unityでの回転を上手く扱うためには、馴染み深いオイラー角ではなく、Quaternionを上手に扱えるようになる必要があるのです。

Quaternionの回転軸は任意軸である

回転と言われるとx軸、y軸、z軸の周りの三軸回転を想像することが多いと思いますが、Quaternionは任意軸回転が基本です。

要するにx,y,z軸に限定されず自分の好きな方向に軸を1つ取ることができ、その軸周りで回転を与えることができます

この任意軸回転のメリットは、三軸回転(オイラー角での回転)だと起こりうるジンバルロックにならないという点です。

ジンバルロックとは、簡単に言うとx,y,z軸の2軸で回転した際に、3軸あった回転軸の2軸が重なってしまい、見た目上2軸になってしまう現象のことです。

これにより自由な回転ができなくなります。

ジンバルロックについての詳細は以下の動画が分かりやすく説明しているので、お時間がある方はご覧ください(英語の動画です)

UnityでのQuaternionの特徴

Quaternionは数の名称であり、様々な3DCGエディタでも使われますが、UnityのQuaternionは少し変わった特徴があります。

それは一般的な右手系の座標系ではなく、左手系の座標系を使用しているということです。

具体的には

  • x 軸方向: 右
  • y 軸方向: 上
  • z 軸方向: 前

となっています。(下図が右手系と左手系の違いです。)

右手系と左手系_rev2.png

この違いによって何が起きるかと言うと

Quaternionの正の向きが反対になってしまいます。詳細は下記です。

  • 右手系では回転方向は反時計回りを正の向きとして測る
  • 左手系では回転方向は時計回りを正の向きとして測る

ただ、ややこしく考える必要はなく、シンプルに「Unity では角度(Quaternion)を時計回りで考える」と認識すれば問題ありません。

Quaternionの使い方・サンプル

これまではざっとQuaternionの概要や特徴を説明しました。

ここからはQuaternionの使い方について説明していきます。

Quaternionの生成方法

Quaternionを指定する方法はいくつかあります。

最もシンプルな方法はVector3(x,y,z)のように

と指定する方法です。

ただ、Quaternionのx,y,z,wが何を意味しており、どう設定すれば想像通りの回転になるかは難しい問題なので、基本的には使用しません。

では、よく使われる簡単に回転を表現する4つの関数を紹介します。

  • Quaternion.AngleAxis
  • Quaternion.Euler
  • Quaternion.FromToRotation
  • Quaternion.LookRotation

それぞれについて詳細に説明していきます。

Quaternion.AngleAxis

AngleAxisはaxis(軸)の周りをangle度回転するQuaternionを生成します。

最も基本的なQuaternionを作成する方法になります。

書き方はQuaternion.AngleAxis(angle,axis)のように、第1引数で角度(オイラー角)、第2引数で軸(例えば「Vector3(0, 1, 0)」 「,Vector3.forward」など)を指定します。

角度は数値で指定すればよく、軸については以下が代表的に使われます。

  • Vector3.right(x軸を指定したい場合)
  • Vector3.up(y軸を指定したい場合)
  • Vector3.forward(z軸を指定したい場合)

以下はAngleAxisを使った「x軸の周りを毎秒2度回転する」サンプルです。下の動画はCubeを回してみた動画です。

Quaternion.Euler

Eulerはオイラー角を使ってQuaternionを作成します。

「正直Quaternionでの指定がよく分からない」という方は、このEulerを使用すると良いかもしれません。

これは、オイラー角で回転を指定できる関数で、下のように表記します。

回転の仕組みは、Quaternion.Euler(x,y,z)としたとき、

  1. z軸周りにz度回転する
  2. x軸周りにx度回転する
  3. y軸周りにy度回転する

というように、z軸→x軸→y軸の順番で回転するようになります。

オイラー角で表した回転の三次元ベクトルを入れればよいので、感覚的に指定しやすいので、よく使われます。

ただ、先述のようにUnityではQuaternionで回転を決めているので、場合によっては上手くオイラー角がQuaternionに反映されず、自分が思ったような動きにならない時があります

また、先述のジンバルロックになる場合もあります。

なので、Eulerを使用する際は必ず確認の作業を忘れないようにしましょう

以下はEulerを使った「毎秒y軸周りに3度とx軸周りに3度回転する」サンプルです。無限に回転する回転体に適したサンプルになっています。

Quaternion.FromToRotation

FromToRotationはある方向からある方向へ回転させるQuaternionを作成します。

引数は開始方向と終了方向の順番です。

この回転は開始方向から終了方向までの最短の回転を描きます。

なので、最短で方向を切り替えたい時に使用することが多いです。

ただし、注意点として、スタートとゴールが決まっているだけで途中の過程は無限に存在するので、自分が思っている回転にならない可能性があります。

したがって、しっかりと確認をする必要があります。

Quaternion.LookRotation

LookRotationはある方向を向かせるためのQuaternionを作成します。

例えば、キャラクターを敵の方向に向かせたい場合は、Transform.LookAtを使えば簡単に敵の方向を向かせる事がありますが、これだと急に敵の方向を向く動きをしてしまいます。

これは不自然なので、徐々に敵の方向を向かせたい場合に敵の角度をLookRotationで算出して向かせる、という使用方法があります。

注意点として、回転させるオブジェクトがデフォルトでY軸方向に頭上、Z軸方向に正面を向けているという仮定のもとで動くため、この仮定が成り立たない状態では想定通りの回転はしません。

Quaternionの足し引き

Quaternionは足し引きすることができます。

その方法は非常に簡単です。上のサンプルの中でも使用しているのでその部分を使って紹介します。

この「*」が足し算になります。

要するに「Quaternion1 * Quaternion2 = 1+2」ということになるのです。

逆に引き算をしたい場合は

Quaternion.Inverseを使用します。

Inverseは逆Quaternionを示すものです。

Quaternionの無回転

また、identityプロパティにより無回転を表すQuaternionの取得もできます。

prefubを使ってオブジェクトを複製する時に使うことがあります。

下記の記事の中にでも使用している部分があるのでよろしければご一読ください!

【Unity】 Prefabを使ったオブジェクト生成・複製・削除等の方法

まとめ

今回はQuaternionについて解説しました。

Unityで回転を表現したい場合には確実に扱える必要があるので、この記事を利用して使えるようになっていただければ幸いです。

他にもゲーム開発に必要な基礎知識をまとめているので、ぜひ参考にしてみてください。

参考記事→)【Unity入門】ゲーム開発ができるようになる基礎知識まとめ


この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!

株式会社x garden CGO(Chief Growth Officer)
Unityエンジニアとして日々Unityと奮闘中
自他共に認めるゲーマー
Splatoon最高記録:世界6位(リグマペア)
ApexLegends最高記録:5連チャンピオン