マウスドラッグでボールをはじく

投稿者: | 2019-12-21


マウスドラッグでボールをはじくスクリプトを作ります。

まず無限に大きな平面を置きます。これはCubeなどと同じような3DゲームオブジェクトのPlaneとは違います。
参考:https://docs.unity3d.com/jp/460/ScriptReference/Plane.html

マウスカーソルの位置から、カメラの向いている方向へレイという光線を発射し、このPlaneとレイのぶつかったところの座標を取得できます。
そこで、マウス左クリックを押した時と離した時にレイを飛ばしてPlaneとの交点の座標を得て、前者の座標から後者の座標への向き・大きさの力をボールに加えます。

ボールと、ボールが飛び出ないように枠を付けたボードとをシーンに配置します。

ボールのスピードが早いときにボールが枠を通り抜けないように、ボールのRigidbodyのCollision Detectionを「Continuous Dynamic」にします。

Emptyオブジェクトを新規作成して、スクリプトを付けます。

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

public class SnapScript2 : MonoBehaviour
{
    Plane groundPlane;
    Vector3 downPosition3D;
    Vector3 upPosition3D;

    public GameObject sphere;
    public float thrust = 3f;

    float rayDistance;
    Ray ray;

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

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0)) // 左クリックを押した時
        {
            downPosition3D = GetCursorPosition3D();
        }
        else if (Input.GetMouseButtonUp(0)) // 左クリックを離した時
        {
            upPosition3D = GetCursorPosition3D();

            if (downPosition3D != ray.origin && upPosition3D != ray.origin)
            {
                sphere.GetComponent<Rigidbody>().AddForce((downPosition3D - upPosition3D) * thrust, ForceMode.Impulse); // ボールをはじく
            }
        }

    }

    Vector3 GetCursorPosition3D()
    {
        ray = Camera.main.ScreenPointToRay(Input.mousePosition); // マウスカーソルから、カメラが向く方へのレイ
        groundPlane.Raycast(ray, out rayDistance); // レイを飛ばす

        return ray.GetPoint(rayDistance); // Planeとレイがぶつかった点の座標を返す
            
    }

}

まずワールドの原点を通って、まっすぐ上を向いた平面を作っています。

groundPlane = new Plane(Vector3.up,0f) 

マウスカーソルの位置からカメラの向いている方へ飛ばすためのレイを作る関数も用意されています。

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

Camera.main は、MainCameraタグの付いた有効な一番目のカメラです。

レイを飛ばすと、レイの原点から、Planeとぶつかった点までの距離が得られます。

groundPlane.Raycast(ray, out rayDistance);

距離は変数rayDistanceに入ります。

RayのGetPointメソッドでPlaneとレイとの交点の座標を得ます。

ray.GetPoint(rayDistance);

レイの出発点から交点までの距離を引数にします。レイを飛ばすのに失敗したときは、距離が0になるので、GetPointメソッドで得られる座標は、レイの原点の座標と同じになります。

なので、取得した座標がレイの原点と同じでないときだけボールに力を加えるようにしています。

if (downPosition3D != ray.origin && upPosition3D != ray.origin)
{
    sphere.GetComponent<Rigidbody>().AddForce((downPosition3D - upPosition3D) * thrust, ForceMode.Impulse); // ボールをはじく
}



コメントを残す

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