Unityのゲームオブジェクトを相対的に回転させる

今回はUnityでゲームオブジェクトの回転について見ていきます。

UnityのインスペクタではTransformのRotationでゲームオブジェクトの角度を見る事が出来ますが、これはオイラー角を表しています。

しかしUnityの内部ではQuaternion型で角度の処理をしています。

Quaternion型の数値は人が見てすぐにわかる数値ではないのでインスペクタではオイラー角で表示されています。

内部でオイラー角を使わない理由はジンバルロックが発生するからだそうですが、わたくしには何のことやら・・・・(^_^;)

その辺りは

Unity のマニュアルは、Unityの使い方を学ぶ手助けとなります。Unityを使って 2D や 3D ゲームを作成したり、ゲーム以外のアプリを作成したりして多くの経験を積みましょう。

Unityのスクリプトリファレンスを見てください。

Unityのスクリプトでもオイラー角をQuaternion型へと変換しそれをキャラクターの角度に設定したりと必ず変換をして角度を変更しています。

よく使用するのがQuaternion.Eulerで指定したオイラー角をQuaternion型に変換します。

Quaternion.Euler(0, 90, 0)

ではX軸を0、Y軸を90、Z軸を0のオイラー角をQuaternion型に変換し利用しています。

スポンサーリンク

ゲームオブジェクトを回転させる

ゲームを本格的に制作していくとゲームオブジェクトの角度を扱う場面によく遭遇する事になります。

主人公キャラを敵キャラの方に向かせたい、主人公キャラと敵キャラの位置の角度の計算をしたいといった場面です。

これらの処理はtransform.LookAtやVector3.Angleを用いて機能を作成する事が出来ます。

Unityで武器を構えた時にターゲットである敵の方向に滑らかに回転し、敵の方向に体を傾ける方法を簡単にしてみました。

他には、あるゲームオブジェクトを他のゲームオブジェクトからの角度で相対的に変更したい場面があります。

つまり現在の角度の状態から新しい角度回転させるという場合です。

文章を見ても解り辛いですね・・・・(^_^;)

ゲームオブジェクトを回転させるサンプル

試しにサンプルを作成し実行してみましょう。

ゲームオブジェクトの回転サンプル

↑のように2つのCubeを作成し、回転するゲームオブジェクトをBase、回転角度用のゲームオブジェクトをRotateとします。

回転させるゲームオブジェクト

Baseは↑のような角度に設定しました。

回転角度用ゲームオブジェクト

Rotateの角度は↑のようにしました。

ゲームオブジェクトを回転するサンプルの図

左がRotateで右がBaseになります。

次にスクリプトを作成し、マウスの左ボタンが押されるたびにBaseの角度をRotateの角度分変更していきます。

スクリプトはBaseゲームオブジェクトに設定します。

元の角度から新しい角度の影響を与えるには元の角度に新しい角度をかけます。

オイラー角で表した場合(実際はQuaternion型)、元の角度が(0, 0, 0)でこれを(0, 90, 0)度変更するには

(0, 0, 0) × (0, 90, 0)

とします。

すると(0, 90, 0)という角度が得られます。

もう一回同じ事をすると

(0, 90, 0) × (0, 90, 0)

なので(0, 180, 0)が得られます。

前の角度から90度回転させているのでこうなります。

↑のスクリプトの例ではBaseゲームオブジェクトの角度をインスペクタで設定したobjの角度分回転させています。

Quaternionの角度は×とその分の回転結果が得られますが、オイラー角の場合は

Transform.Rotate

を使用します。

別のゲームオブジェクトotherBaseをobjの角度分回転させる場合は

otherBase.Rotate (obj.eulerAngles, Space.Self);

でotherBaseの角度をobjのオイラー角分回転させます。

第2引数がローカル(Space.Self)かワールド(Space.World)の角度で回転させるかの指定です。

ローカルとワールドの部分で少し混乱しますが、ゲームオブジェクトを選択した時にUnityのツールバーでローカルとワールド座標を切り替えられますが、

その状態で回転するかどうかです。

ローカルだとそのゲームオブジェクトが向いている向きを軸として回転させますが、ワールドだとX、Y、Z軸は常に同じ方向を向いていてその向きで回転させます。

今回の例で言うとotherBaseの角度をローカルで回転させています。

ローカルとワールドどちらで回転させるかわからなくなった時はツールバーでローカル、ワールドの座標を切り替えて確認してみるとわかりやすいです。

ワールド座標軸

↑がワールド座標軸で表示した時で常に同じ方向を示しています。

Space.Worldを選択した場合はこの軸で回転させます。

ローカル座標軸

↑がローカル座標軸で表示した時でそのゲームオブジェクトのローカルの方向軸を示しています。

Space.Selfまたは何も設定しない時はこの方向軸で回転させます。

それでは実行してみましょう。

次々にゲームオブジェクトを回転させたサンプル

↑のように元のゲームオブジェクトが自身の角度からRotateゲームオブジェクトの角度分回転していきます。

結局このサンプルのような事は何に使えるんだ!?

という声も聴こえてきそうですが・・・。

例えばキャラクターの向いている角度に合わせてそのゲームオブジェクトの角度を回転させたい時などです。

Unityのゲームでキャラクターの両足が別の高さの地面の上にある時にそれぞれの足をそれぞれの地面につけるようにする機能を作成します
Unityのアクションゲームでゾンビに足を捕まれ、そこから脱出する機能の作成と敵であるゾンビを地面に合わせて傾きを変更して移動させる機能を作成します

の当たりでこの角度の掛け算を利用しています。

角度にベクトルをかけた場合は何が得られる?

Quaternion型とQuaternion型をかけると最初の角度を次の角度分回転させた角度が得られますが、

Quaternion型にVector3型の値をかけると何が得られるんでしょうか?

Quaternion型にVector3の値をかけるとその角度方向のベクトル値(Vector3)が得られます。

試しにメインカメラにスクリプトを取り付け検証してみます。

Startメソッドでメインカメラの角度にVector3の(0f, 0f, 2f)をかけて出力しています。

出力した値だけでは解り辛いのでUpdateメソッドでメインカメラから角度にベクトルをかけた方向に線を引いてわかりやすく表示します。

角度にベクトルをかけた値

↑のように角度にベクトルをかけるとその角度のベクトルが得られる事がわかります。

Vector3の(0f, 0f, 2f)と言う事はメインカメラの前方を表す(0f, 0f, 1f)の長さの2倍のベクトルです。

つまりメインカメラの角度に(0f, 0f, 2f)の方向ベクトルをかけるとメインカメラの前方のベクトルが得られます。

先ほどのメインカメラはRotationのX軸を20にしているので20度の方向のVector3(0f, 0f, 2f)のベクトルが求められます。

カメラの角度方向のベクトルが求められる

↑のような感じですね。

Debug.DrawRayでレイを視覚化しているのは長さが1mなので実際にはあと1m先が計算で求められる位置です。

Debug.DrawRayの長さも2にすればよかったかも・・・・(-_-)

終わりに

今回角度について取り上げたのは自分がいまいちわかっていなかったからです。

結局の所いまいちわかっていない状態は変わっていないですが・・・・(^_^;)

元の角度から回転させたい時も出てくると思うのでそんな時にこの記事が役立つかもしれません(謎)

わたくしは以前からオイラー角を足して計算した結果をそのままオイラー角に入れたり、Quaternion型に変換して角度を変更していますが、

オブジェクトを回転させる時はTransform.Rotateを使った方が良さそうですね。

オイラー角の場合計算結果が360を越えると角度がうまく計算されなくなるみたいなので、以前の記事も見直さないといけないかも・・・( ノД`)シクシク…

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます