ゲーム中に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との交点まで瞬時に動きます。