Unityで簡単な2D脱出ゲームを作ってウェブサイトで公開してみよう 〜オブジェクトの回転〜

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
オブジェクトの回転

この記事を三行にまとめると

明石家さんまさんのMCばりにガンガン回しても大丈夫でしょう
三角関数も三角州も三角錐の体積の求め方も忘れてしまった
今の僕には三角関数よりも三角筋を鍛える方が確実に必要です
今日はオブジェクトを回転させてみたいと思います。回転と言ってもぐるぐる〜というアニメーションをつけるわけではなく、オブジェクトの角度を変える処理を行うという内容です。

動画はこちらです。





オブジェクトのRotationについて

オブジェクトの角度を変えるにはインスペクターのRotationの数字をいじることになるわけですが、一瞬混乱しちゃうかもしれないのは、Rotation XはX方向に回転するという意味ではなくX軸を中心に回転するという意味になります。Rotation YもRotation Zも同じ。

ゲーム画面の中でXは横軸、Yは縦軸、Zは奥行きの軸となっているので、X軸を中心に回転するということは画面の奥に向かって回転することになります。画面と平行にくるくる回したい場合は奥行きの軸、つまりZ軸を中心に回転させなければなりません。2D画面でゲームを作る場合、奥に向かって回転させることはあまりないと思うので、基本的にはRotation Zをいじることになるのかなと思います。

実際にオブジェクトがそれぞれの軸に対してどう回転するのかは動画の中で紹介しているので、言葉だけじゃ分からんって方は動画も見てみてください(1:00あたり)

それから回転の方向は反時計回りが正、時計回りが負となります。数学のグラフと同じですね。第一象限とか第二象限とか……なつかしいっす。

Rotationには負の数字を入れることもできますので、それでどっち方向に回したいか変えられます。



現在の角度に加算する

Rotationを変える方法は大きく分けて二つあります。一つは現在の角度に数字を加算する方法。

public class CabinetLow : MonoBehaviour {
  public RectTransform parent;

  public void ChangeDegree() {
    parent.Rotate(new Vector3(0, 0, 90));
  }
}

現在の角度に加算するためには「Rotate」という関数を使います。今回はZの値を変えたいのでVector2ではなく Vector3で値を入力しています。

これだとChangeDegreeが呼び出されるたびにparentにセットしたオブジェクトが現在の角度から90度回転します。つまり何度もクリックすればそのたびに90度ずつ回転する動きになります。



角度を直接入力する

もう一つは角度を直接入力するやり方です。こっちの場合はRotationの値が指定した数字になるという処理なので、何度クリックしても同じ角度にしかなりません。

public class CabinetLow : MonoBehaviour {
  public RectTransform parent;

  public void ChangeDegree() {
    parent.rotation = Quaternion.Euler(0, 0, 90);
    parent.localRotation = Quaternion.Euler(0, 0, 90);
  }
}

この場合は何度クリックしてもparentオブジェクトのRotation Zは90のままです。つまり回転するのは最初の一回だけってことですね。

直接入力する場合、設定方法は2パターンあります。オブジェクトの位置を変える場合にもpositionとlocalPositionという二つのパターンがありますが、あれと同じで角度にもrotationとlocalRotationがあります。

rotationは絶対角度です。つまり画面から見た角度。一方のlocalRotationは親を基準とした相対角度です。

親オブジェクトのRotation Zが90の時は子供も90度傾いた状態に見えますが、この時、rotationで子オブジェクトに90度を入れても画面上では変化がありません。すでに画面に対して90度傾いているからです。親が90度傾いている状態でさらに子供も90度回したい場合はlocalRotationに値を入れる必要があります。Positionと同じでRotationもインスペクターの値はlocalRotationの値なので、親と子を両方ぐるぐる回す場合は混乱しないように注意が必要かもしれません。個人的にはなるべく親は0度から回転させないような作りにするのが良いと思うのですが……あるいは親を回す場合は子を回転させないような作りにするとか。まあ、別に混乱なんてしないぞって方は明石家さんまさんのMCばりにガンガン回しても大丈夫でしょう。

それからrotationやlocalRotationはVector3で値を入れることができません。代わりに「Quaternion.Euler」という関数を使います。使い方はVector3と同じでx、y、zの値をそれぞれ入れればOK。



角度を取得する

位置の場合はpositionやlocalPositionで簡単に値が取れるのですが、角度の場合はrotationやlocalRotationで値を取ろうとするとちょっとめんどうなことになります。

例えばこんな感じでRotation Zの値を取ろうとした場合。

public class CabinetLow : MonoBehaviour {
  public RectTransform parent;

  public void ChangeDegree() {
    parent.rotation = Quaternion.Euler(0, 0, 90);
    float z = parent.rotation.z;
    Debug.Log(z);
  }
}

コンソール画面に90と出てきてくれれば良いのですが、これだと「0.7071068」とかいうよく分からない値が出てきます。これを90に直すには三角関数が必要なので、もはや三角関数も三角州も三角錐の体積の求め方も忘れてしまった上に三角関係も三角木馬も経験がない僕にはこの数値は使いこなせません。

まあ「俺は三角関数も得意だし三角筋も毎日鍛えてるから全然よゆーだぜ」って人は、たぶんこんな式で変換すれば角度が取れると思うんで、良かったら。

public class CabinetLow : MonoBehaviour {
  public RectTransform parent;

  public void ChangeDegree() {
    parent.rotation = Quaternion.Euler(0, 0, 90);
    float z = parent.rotation.z;
    float theta = 2 * Mathf.Asin(z) * 180 / Mathf.PI;
    Debug.Log(theta);
  }
}

自分で試した限りでは正しい数値が取れたから合ってはいると思うんだけど……わざわざこんなことをしなくても「eulerAngles」や「localEulerAngles」を使えばRotationの値をそのまま取れます。

public class CabinetLow : MonoBehaviour {
  public RectTransform parent;

  public void ChangeDegree() {
    parent.rotation = Quaternion.Euler(0, 0, 90);
    float z = parent.localEulerAngles.z;
    Debug.Log(z);
  }
}

eulerAnglesとlocalEulerAnglesもrotationやlocalRotationと考え方は同じです。eulerAnglesは絶対角度、localEulerAnglesは相対角度を取得します。インスペクターに表示されている数値と同じ値を取りたい場合はlocalEulerAnglesを使ってください。

X、Y、Zの単体の値を取りたい場合はfloat型の変数に値を入れれば良いですが、3つの角度をまとめて取得したい場合はVector3型の変数が必要です。

public class CabinetLow : MonoBehaviour {
  public RectTransform parent;

  public void ChangeDegree() {
    parent.rotation = Quaternion.Euler(0, 0, 90);
    Vector3 angles = parent.localEulerAngles;
    Debug.Log(angles);
  }
}

ちなみにマイナスの数字を入れた場合でもlocalEulerAnglesで取れる数字はプラスに置き換わるみたいです。だから-90度にした時はlocalEulerAnglesは270度になります。あとインスペクターでは「-90.00001」みたいに小数点以下の誤差が出てしまうことがあるんですが、この値をスクリプトで取得した時は誤差は無視されます。「270.00001」みたいにはならない。まあ、もし誤差が出たとしてもこの程度だったら画面上での違いはほぼ分からないですけどね。






よく学生の時に「微分積分とか絶対将来使わねーだろ」とか「三角関数なんて覚えてどーすんだよ」みたいなことを誰でも一度は思ったことがあると思うんですけど、僕も何度となくそう思ったもんだけど、こうやって使う日が来ることもあるんだね。まさか趣味でゲームを作る時に使うなんてな……人生いつ何が必要になるか分からないもんです。いや、別に使う必要は全くないんだけどね。

少なくとも今の僕には三角関数よりも三角筋を鍛える方が確実に必要です。肩こりにも効果があるらしいし。僕もそうですけど、普段からPCばっかりいじってる人はマジで肩こりには気をつけた方が良いです。もう十年以上前になるけど整骨院の先生から「肩こりがひどくて肩甲骨が炎症起こしてるよ」って言われたことあって、あの時は誇大な表現とかではなく本当に起きてる間はずっと肩が痛かったです。みなさんはそうならないように。

ともあれこれでオブジェクトの角度を変える方法は分かったということで、次回はこれを使って角度と色を判定するパスワードを作ります。

それじゃあ次回もよろしくお願いしんぼりるどるふ。



本シリーズの記事の一覧はこちら
Unityで簡単な2D脱出ゲームを作ってウェブサイトで公開してみよう 〜エピローグ〜
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください