スクリーンショット_2018-10-22_20

Unity で物体を動かしたい

● やりたいこと
ある限定された範囲で,物体をマウスでDragして動かせるようにしたい。

● 条件
Screen Spaceで実装するのが一般的ですが,今回はWorld Spaceで実装します。あえてこのような形をとっているのは衝突判定などの物理演算が活用しやすくなると考えたからです。

● 方針
実装しようと思ってるときの頭の中はこんな感じでした。

1. まずCanvasの設定を見直そう
・細かい設定が面倒だけど頑張る
2. マウスの位置と物体の位置を同じにする関数を作ろう
・マウスの位置を取得したい
・スクリーン座標からワールド座標に変換
・変換後の座標を物体に与える
3. 物体をDragしている間だけ関数を呼び出したい
・EventSystemのEventTriggerがつかえそう

● コード ( MoveBox.cs )
いつものようにシンプルなコードです

using UnityEngine;
using System;

public class MoveBox : MonoBehaviour {

    Vector3 pos; // マウスの位置情報を受け取る
    RectTransform rect; // Canvasの情報を受け取る

    void Start () {
        rect = transform.parent.transform as RectTransform; // 親(=Canvas)のtransformをRectTransformに返還
    }

    public void Move(){
        pos = Camera.main.ScreenToWorldPoint(Input.mousePosition); // マウス位置をスクリーン座標からワールド座標に返還
        // canvasの位置に収める
        if(Math.Abs(pos.x) < rect.rect.width / 2 && Math.Abs(pos.y) < rect.rect.height / 2)
            //canvasのwidthとhighはこんな感じでとってこれます
        {
            transform.localPosition = pos; // 物体の座標をマウス座標に更新
            // position ではなく localPosition だといい感じ
            // Canvasの座標情報とかとも関係しているのでここらへんは説明が難しい
        }
    }
}

雑な解説

● Canvasの設定
UI部品を並べるときCanvasなるものがいきなりでてきて戸惑いますよね。
いじったことない人もいると思うのですが便利な設定がいろいろあります。

今回は単純にScreen SpaceからWorld Space上にCanvasをもってきたいという話です。

これは簡単で,CanvasコンポーネントのRender Modeなるものを変更するとできます。

この項目をWorld Spaceに変更します。

その後postionがいい感じなっていないと思うので

今回はこんな感じにPos Xを0 Pos Yも0 に設定しています。
Pos Zが1なのはこの後追加していくオブジェクトがきちんと描画されるようにするためです。ここらへんややこしいので,詳しく知りたい人はTwitterで訊いてください。
WidthとHeightを設定することでCanvasの子オブジェクトのPivotの設定に役立つのでよいです。ちなみに今回はこのCanvasの範囲から物体が飛び出ないようにしていきたいと思っています。

● Boxの設定

Canvasの子どもとして UI ▶ Image を作成します。今回はその名前をBoxに変更しました。Imageはデフォルトだと真っ白の四角形が表示されます。

そしてこのBoxにMoveBox.csをアタッチします。
コードに関して説明すべきことはあんまりありませんね。

● EventTriggerを使う
クリックやドラッグなどの基本的なイベント時に関数を呼び出したい。そういうときはEventTriggerがつかえます。なのでBoxのコンポーネントに追加していい感じに設定します。

このEventTriggerなどについても詳しく紹介できるといいですね。

Hierarchyはこんな感じです

おしまい

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