マウスクリックでゲームオブジェクトを取得するために必要な処理

過去にトランプゲームを制作した際に悩んだ事です。トランプゲーム制作時には、カードにボタンコンポーネントを追加して解消しました。ですが、今回はもっと実用的な方法をタワーディフェンスゲーム制作時に見つけたので、そちらを参考に […]

過去にトランプゲームを制作した際に悩んだ事です。トランプゲーム制作時には、カードにボタンコンポーネントを追加して解消しました。ですが、今回はもっと実用的な方法をタワーディフェンスゲーム制作時に見つけたので、そちらを参考にしつつメモを残します。

レイヤー分けとコライダーの付与

最初にレイヤー分けを行う必要があります。レイヤーを分けることで、そのレイヤーのオブジェクトのみと判定を行う事が可能になります。今回の場合は “Block” レイヤーを作って、そのレイヤーにブロックを設置しています。
次に、クリックを受け付けるオブジェクトにコライダーを付与します。クリックされた判定は、コライダーを使って行います。

クリックされたオブジェクトを取得

オブジェクトを設置したら、早速スクリプトを記述します。スクリプトで行う事は、マウスのワールド座標を取得して、その座標に点のコライダーを生成し、判定を行います。行うことは単純ですが、マウスのワールド座標を取得するには、少し手順が必要となります。
最初にクリックされたら処理が走るように、if文を記述しましょう。左クリックの取得は Input.GetMouseButtonDown(0) で行います。

if (Input.GetMouseButtonDown(0))
{
}

マウスの座標はスクリーン座標

マウスの座標は Input.mousePosition で取得できますが、実はマウスが返す座標はスクリーン座標であり、ワールド座標ではありません。イメージとしては、空間を指さしている感じです。カメラレンズの中にポインターがあるので、ワールドには座標を持ってません。
そのため、スクリーン座標をワールド座標に変換する必要があります。そのためには下記の様に記述します。

var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

これで mousePos にマウスのワールド座標を格納することができます。
ScreenToWorldPoint() がスクリーン座標をワールド座標に変換する処理です。このメソッドはカメラについている機能のため、 Camera.main でメインカメラを指定しています。
日本語にすると「メインカメラから見たマウスのワールド座標を取得する」という意味です。
カメラが複数ある場合は、今見ているカメラから座標を取得する必要があります。

点のコライダーを生成して判定

座標を取得したら、コライダーを生成して判定を行います。下記の様に記述します。

var col = Physics2D.OverlapPoint(mousePos, LayerMask.GetMask("Block"));

Physics2D.OverlapPoint() が点のコライダーを生成して判定を行います。その際、レイヤーマスクを生成して “Block” レイヤーのみで判定を行っています。これで、もし衝突するオブジェクトがあった場合はそのコライダーを取得する事が可能となります。

まとめ

必要なのはクリックされた判定、マウスのワールド座標取得、その座標にコライダーがあるかの判定と、3行ほどです。ボタンコンポーネントを使用すると、フィールドにあるカードや相手の手札も選択できてしまったりと、考える事が多くありましたが、今回のような処理であれば、プログラム上で制御が容易なため、自由度が高く、スクリプトも作りやすくなりそうです。
忘れないように、クリックしたオブジェクトを返すメソッドを下記に記述しておきます。

public GameObject GetClickObject(string layerName)
{
    var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    var col = Physics2D.OverlapPoint(mousePos, LayerMask.GetMask(layerName));
    return col.gameObject;
}