【Unity】ドラッグアンドドロップで3Dオブジェクトを動かす

投稿者: | 2020-10-30

ゲーム中にCubeをドラッグアンドドロップして同じ平面上を移動させてみます。

シーンには原点を通るPlaneオブジェクトとCubeを配置しています。

Cubeに他のオブジェクトとは違うタグを設定します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameScript : MonoBehaviour
{

    Plane plane;   
    bool isGrabbing;
    Transform cube;

    // Start is called before the first frame update
    void Start()
    {
        plane = new Plane(Vector3.up, Vector3.up);
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;
            if(Physics.Raycast(ray,out hit, Mathf.Infinity))
            {
                if (hit.collider.tag == "Player")
                {
                    isGrabbing = true;
                    cube = hit.transform;
                }
            }
        }


        if (isGrabbing)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float rayDistance;
            plane.Raycast(ray, out rayDistance);

            cube.position = ray.GetPoint(rayDistance);

            if (Input.GetMouseButtonUp(0))
            {
                isGrabbing = false;
            }
        }

    }

}

スクリプトではStart()で、真上を向いて、原点の1メートル上(0, 1, 0)にPlaneを作ります。これは3DオブジェクトのPlaneとは違って見えません。

plane = new Plane(Vector3.up, Vector3.up);

マウス左クリックで、カーソルからカメラの向いている方向へレイを飛ばします。タグを使ってCubeかどうかを調べて、Cubeなら掴みます。

if(Input.GetMouseButtonDown(0))
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // カーソルからのレイ

    RaycastHit hit;
    if(Physics.Raycast(ray,out hit, Mathf.Infinity)) // レイを飛ばす
    {
        if (hit.collider.tag == "Player") // タグで見分ける
        {
            isGrabbing = true; // 掴む
            cube = hit.transform; // Cubeを保存
        }
    }
}

そして、Cubeを掴んでいる間は、同じ様にレイを飛ばして、Start()で作ったPlaneとレイとの交点にCubeを移動し続けます。

if (isGrabbing)
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // レイ
    float rayDistance;
    plane.Raycast(ray, out rayDistance); // Planeにレイを飛ばす

    cube.position = ray.GetPoint(rayDistance); // レイが当たった位置

    if (Input.GetMouseButtonUp(0))
    {
        isGrabbing = false;
    }
}

このときはPhysics.RaycastでなくPlane.Raycastを使います。Plane.Raycastでは交点までのレイの距離だけがわかります。レイのGetPoint()メソッドを使うと、引数に渡した長さだけレイが進んだ場所の座標がわかるので、Cubeの位置にこれを代入します。

左クリックを離すと掴むのをやめます。

この方法だと、Cubeをクリックした時にPlaneとの交点まで瞬時に動きます。

コメントを残す

メールアドレスが公開されることはありません。