3Dオブジェクトをマウスでドラッグして移動する(フロアーベース)

2024年4月5日

オブジェクトの移動方法には様々な方法がありますが、今回は、マウスを使って移動させることを試してみましょう

実行結果

床の上に配置されたオブジェクトをマウスの左ボタンを押している間、マウスの動きに合わせて移動させます

シーン構成

Cube(移動させるオブジェクト)

移動させたいオブジェクトを作成します

Plane(オブジェクトを配置しているところ)

実際はマウスで床をクリックして、その場所にCubeを移動させています

スクリプト

Cubeにアタッチするコード

マネージャを作成してアタッチしてもいいですが、今回は単純化のためにCubeにアタッチします

using UnityEngine;

public class ClickMoveSample : MonoBehaviour
{
    RaycastHit[] hits = new RaycastHit[1];

    private void Update()
    {
        if (Input.GetMouseButton(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if (Physics.RaycastNonAlloc(ray, hits, Mathf.Infinity) == 0) return;

            Vector3 hitPoint = hits[0].point;

            transform.position = new Vector3(hitPoint.x, 0.5f, hitPoint.z);
        }
    }
}

解説

マウスが接触したオブジェクト(床)の情報を取得するために使います
配列になっているのは、マウスの先に複数のオブジェクトがあった場合に格納されるためです
具体的には、オブジェクトの奥にさらにオブジェクトがあった場合になります
RaycastHit型には、コライダーの情報やヒットした位置情報などが格納されます

RaycastHit[] hits = new RaycastHit[1];

マウスが押されている間中、実行されます
引数の0は左ボタンの状態の取得になります
押されていると、trueが返されます

if (Input.GetMouseButton(0))
{
    // 処理
}

ユーザー視点(カメラ視点)で、マウスの位置を基準にしたベクトルを作成します
少し難しいですが、オブジェクトがあるかどうかをチェックするために作成するものになります

 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

Physics.RaycastNonAllocメソッドは、難しい英単語ですが、メモリの使用をうまくしてくれるものになります
Physics.Raycastメソッドもありますが、Physics.RaycastNonAllocが推奨されます
戻り値は、ヒットしたオブジェクトの数になります
奥にオブジェクトが隠れていると、この数が増えます
もし、0ならば・・・なので、ヒットしなければと読みます
ヒットしなければ、returnなので、Updateメソッドから抜けます

if (Physics.RaycastNonAlloc(ray, hits, Mathf.Infinity) == 0) return;

ヒットすると、ヒットした3Dのワールド座標が欲しいので、pointプロパティを取得します

Vector3 hitPoint = hits[0].point;

Cubeの位置を移動させます
x軸とz軸の情報はマウスがクリックされた位置情報を採用してます
y軸は、0.5の位置を維持させます
これにより、床平面上を移動するようにさせています

transform.position = new Vector3(hitPoint.x, 0.5f, hitPoint.z);

参考

Rayについての解説をしています
また、Raycastメソッドの使い方にも触れています

Unity

Posted by hidepon