見出し画像

Unity : マウスで物体を回転させる

● やりたいこと
PowerPointなどで写真や図形を回転させる機能がありますよね。

こういうやつです。
こういうやつを作りたいという話をします。

● 方針

1. まずはハンドルを作ろう
・ハンドルをドラッグして回転させたいなあ
2. 回転角を求めよう
・ベクトルのことを思い出す
3. 回転方向を決めよう
・外積が使えるらしい
4. Boxを回転させよう
・Unityの回転は少し面倒

雑な解説

1. まずはハンドルを作ろう
四角い箱の角をドラッグする形で回転できるようにしたい。
ということで,前回の記事で作ったBoxにハンドルを付けます。
具体的にはBoxの子オブジェクトにImageを追加して丸い画像を追加してみました。

追加したオブジェクトの名前をHandleとしておきます。

このハンドルにいつものシンプルなコードをアタッチします。

using UnityEngine;

public class RotateObj : MonoBehaviour {

    Vector2 pos; // 最初にクリックしたときの位置
    Quaternion rotation; // 最初にクリックしたときのBoxの角度

    Vector2 vecA; // Boxの中心からposへのベクトル
    Vector2 vecB; // Boxの中心から現在のマウス位置へのベクトル

    float angle; // vecAとvecBが成す角度
    Vector3 AxB; // vecAとvecBの外積

    // PointerDownで呼び出す
    // クリック時にパラメータの初期値を求める
    public void SetPos(){
        pos = Camera.main.ScreenToWorldPoint(Input.mousePosition); // マウス位置をワールド座標で取得
        rotation = transform.parent.rotation; // Boxの現在の角度を取得
    }

    // ハンドルをドラッグしている間に呼び出す
    public void Rotate(){
        vecA = pos - (Vector2)transform.parent.position; //ある地点からのベクトルを求めるときはこう書くんだった
        vecB = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.parent.position; // 上に同じく
        // Vector2にしているのはz座標が悪さをしないようにするためです

        angle = Vector2.Angle(vecA, vecB); // vecAとvecBが成す角度を求める
        AxB = Vector3.Cross(vecA, vecB); // vecAとvecBの外積を求める

        // 外積の z 成分の正負で回転方向を決める
        if (AxB.z > 0)
        {
            transform.parent.localRotation = rotation * Quaternion.Euler(0,0, angle); // 初期値との掛け算で相対的に回転させる
        }
        else{
            transform.parent.localRotation = rotation * Quaternion.Euler(0, 0, -angle); // 初期値との掛け算で相対的に回転させる
        }
    }
}

HandleのEventTriggerをこのように設定するととりあえず動くはずです。

2. 回転角を求めよう

この図で伝わって欲しい。
ハンドルをクリックしたときの座標をAとする。ドラッグ先の座標をBとする。Boxの中心座標を基準とすると,ベクトルAとベクトルBができる。このvecAとvecBが成す角度を求めてその分だけBoxを回転させるとうまくいきそうな気がする。

3. 回転方向を決めよう
vecAとvecBの成す角度は Unityだと Vector2.Angle(vecA, vecB) で求めることができます。けどこの角度は正の値しかとりません。
つまり,右回りなのか左回りなのかの区別がつかないのです。
こまった。

こまったのでググります。

いい記事を発見しました。
外積を使えば回転方向を判別できるというヒントを得ました。

高校数学の知識も怪しいので外積もわからない。
直感的な理解ならこの記事の図がよいと思います。

ようは外積の z 成分の正負で回転方向を判断しようというわけです。

4. Boxを回転させよう
Unityの回転は少しややこしいです。
次のような記事が役立つので紹介しておきます。

できあがったもの

おしまい

最後まで読んでもらえて嬉しいです。よければフォローもお待ちしています。サポートは記事を書くときのコーヒーになります。