いぬおさんのおもしろ数学実験室

おいしい紅茶でも飲みながら数学、物理、工学、プログラミング、そして読書を楽しみましょう

Unityでキャラクタを決まった軸の周りに回す

 編隊を全滅させたとき「300」が現れ、クルクルッと回って加点、とやりたかったので試しました。板(3DオブジェクトのQuad)に「300」の絵を貼り付けます。その板を上下方向の軸の周りに回します。
f:id:Inuosann:20210419222158p:plain:w250
↑こんな感じです。動画でお見せしたいですが、ブログに動画をアップする方法が分からないので、この絵で想像してください……。

 今回は板を回しましたが、同じ方法で他の立体でも回せます。ここでは回し方のみ説明します。その前にいくつか注意。「300」の絵を貼り付けるのですが、ぼくは数字以外の部分(例えば「0」の穴の部分など)は透過させています。これはいくつか手順を踏まないと実現できません。その方法は別の機会に書きます。また、板の場合、通常の方法では板を回して裏を向いたときに完全に透過してしまい、「300」が見えなくなってしまいます。ぼくは同じ板を2枚用意し、裏同士をくっつけて、どちらから見ても大丈夫なようにしました。ネットで調べるとシェーダを書き換えるなどすればできるのだそう。でも大変そうだと思ったので2枚でやっています。

 さて、回転の方法です。コードは次の通り。板なり立体なりを生成しておき、そのゲームオブジェクトを go としています。1行目でオブジェクトの上下方向の周りに10°回すためのクオータニオン rot を作っています。2行目でオブジェクトの rotation を取得し、それに左からさっき作ったクオータニオンをかけ算しています。そしてその結果をもとの rotation に書き戻します。

    var rot = Quaternion.AngleAxis(10f, go.transform.up);
    go.transform.rotation = rot * go.transform.rotation;

これで、このコードが実行されるたびに10°ずつ回転します。余談ですが、Unity って扱う角の単位がラジアンではないんですね。度の方が楽だからいいですが。

 transform.up は、オブジェクトの上方向を向く、長さ1の空間ベクトルです。ベクトルの成分はワールド座標系での値が入ります(もちろんオブジェクトの状態によって成分はいろいろに変化します)。今回は「自分自身の上下方向を回転の軸に」ということなのでこれを使いましたが、別の軸を使いたいこともあるでしょう。例えば空間内の(3, 4, 5)というベクトルを軸にしたければ transform.up の代わりにそれを使うだけです。なお、「オブジェクトの上方向」とは、そのオブジェクトをUnityのエディタで見たとき(Sceneタブをクリックして)、オブジェクトをクリックして現れるy軸の向きのことです。オブジェクトにはローカルの座標軸が固定されています。この軸のうちのy軸です。

 気をつけましょう。Unity では左からかけたクオータニオンの効果が後から出ます。例えば rot = rot1 * rot2 * rot3 などとクオータニオンを3つかけ算すると、まずオブジェクトに rot3 が表す回転をさせ、次に rot2 、最後に rot1 、ということになります。rot を使えばこの3回の回転を1回で済ますことができますが、そういう注意が必要です。

 もうひとつ、もともとクオータニオンは前に書いたようにNRN’ を計算してベクトルを回転させることになっています。ここでNは回転のためのクオータニオン、N’はその共役。Rは 0+ なのでした。
www.omoshiro-suugaku.com
しかしどういう加減なのか知りませんが、Unity では最初に載せたコードのように1回、左からかけるだけで回転させることができます。内部では共役クオータニオンもかけているのかな、などと想像していますが、まあいいでしょう。