Unityでオブジェクトを回転するときに、transform.rotationに値を代入すると、ちゃんと回転しませんでした。回転はするんですが、指定した角度で回転してくれず、誤差が発生したんですよね。
で、解決したので、その解決方法を記載しておきます。キーワードはクォータニオンです。
Unityのバージョン:2020.3.47f
【Unity】オブジェクトが指定の角度で回転しない時はクォータニオンを使え!
不具合の現象と対策後の動きについて解説します。
オブジェクトが正常に回転しなかった時の現象とスクリプト
今回実装したのは、時計の針をボタンを押した時に30度ずつ回転させる機能です。ボタンを押したら、回転はするんですが、ピッタリ30度ずつは回転してくれませんでした。
オブジェクトがうまく回転してくれなかった時のスクリプトは下記です。
hari.transform.Rotate(new Vector3(0, 0, hari.transform.rotation.z - 30.0f));
hariは回転させたいオブジェクトです。Rotateメソッドでz軸を30度回転させてやればいいだろうと実装しました。
しかしこれを9回実行した場合、下図のようになっています。本当は270度回転して9時の方向を向いておいて欲しいのですが、若干ずれていますね。ヒエラルキー上でもZ角度が84.703度になっています・・・。
オブジェクトが正常に回転するようになった時のスクリプト
ここで登場するのがクォータニオンです。詳しくはUnity公式ページを見てもらえたらと思いますが、ざっくり言うと先ほど示したベクトルで角度を指定する方法だと、Unityの制限に引っかかることがあるということです。
外部サイト:Unity の回転と向き
メリット・デメリットの説明にもありますが、直感的に「ベクトル指定しておけば回るっしょ」ぐらいで実装したのですが、そうは簡単にはいかなかったってことですね・・・。
というわけで、クォータニオンで回転させました。と言っても超簡単で、下のように修正しました。
hari.transform.rotation *= Quaternion.AngleAxis(-30, Vector3.forward);
Quaternion.AngleAxisメソッドでZ軸方向に30度回転させるスクリプトです。
Vector3.forwardはZ軸方向のことでVector3(0,0,1)と同様のものです。また「*」オペレーションはQuaternionクラスに実装されているオペレーションで角度を加算することができます。
これにより実行した結果が下記のようになっています。
9時方向にピッタリ向いていますね!そしてZ軸の角度も90度ピッタリになっています。
このようにクォータニオンを使えば、正確にオブジェクトを回転させることができるわけですね!
最後に
Unityでオブジェクトを回転させるときにはクォータニオンを使いましょうということですね。今回は2Dのゲームなので回転軸は1軸しか使わないのですが、それだけでも苦労しますねw