将棋アプリの制作

2023年6月21日

マウスをクリックした時に選んだ駒の情報や座標を取得する

シーケンス図

クラス図

マウスがクリックされたら、その位置のゲームオブジェクトと座標(符号)が取得できるようにします

マウスクリックで情報を得るオブジェクト

クリックされた時にどのイベントハンドラ(メソッド)を実行したいのかを登録できます
複数の登録も可能です

アタッチされているスクリプト

using UnityEngine;
using UnityEngine.Events;

public class ClickMouseObject : MonoBehaviour
{
    /// <summary>
    /// マウスオブジェクトがクリックされたときに呼び出されるイベント
    /// </summary>
    /// <param name="clickedObject">クリックされたGameObject</param>
    /// <param name="mousePos">ワールド座標でのマウスの位置(符号)</param>
    public UnityEvent<GameObject, Vector2Int> OnClickedMouseObject;

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out RaycastHit hit))
            {
                GameObject clickedObject = hit.collider.gameObject;
                Vector2Int mousePos = Fugo.FromWorldPos(hit.point);
                OnClickedMouseObject?.Invoke(clickedObject, mousePos);
            }
        }
    }
}

上記のコードは、Unityのスクリプトである「ClickMouseObject」クラスです。

このスクリプトは、マウスでオブジェクトをクリックしたときにイベントを発生させる機能を提供します。

以下は、クラス内の主な要素です。

  1. public UnityEvent<GameObject, Vector2Int> OnClickedMouseObject;
    • クリックされたマウスオブジェクトを通知するためのイベントです。このイベントは、GameObjectVector2Intの2つのパラメータを持ちます。
  2. private void Update()
    • Unityのフレームごとに呼び出されるメソッドです。
    • Input.GetMouseButtonDown(0)は、マウスの左ボタンが押された瞬間を検出します。
    • Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);は、マウスの位置を元にレイを作成します。
    • Physics.Raycast(ray, out RaycastHit hit)は、作成したレイを使ってオブジェクトの衝突判定を行います。
    • オブジェクトが衝突した場合、そのオブジェクトとマウスの位置をOnClickedMouseObjectイベントに通知します。

このスクリプトを使うと、マウスでオブジェクトをクリックしたときに、他のスクリプトでイベントを受け取ることができます。例えば、ゲームオブジェクトがクリックされたときに別のスクリプトで特定の処理を実行するなどの使い方ができます。

マウスクリックした時に取得する情報を確認するテスト

テスト用のオブジェクト

アタッチされているスクリプト

using UnityEngine;

public class GetPieceTest : MonoBehaviour
{
    /// <summary>
    /// マウスポイントオブジェクトを取得するためのイベントハンドラです
    /// クリックされたオブジェクトの名前とマウス位置(行位置を漢字に変換した符号)をコンソールに出力します
    /// </summary>
    /// <param name="obj">クリックされたオブジェクト</param>
    /// <param name="pos">マウスの位置(符号)</param>
    public void OnGetMousePointObject(GameObject obj, Vector2Int pos)
    {
        // クリックしたオブジェクトとマウスの位置(符号)をコンソールに出力する
        Debug.Log($"{pos.x},{Fugo.ConvertNumToKanji(pos.y)} {obj.name}");
    }
}

このコードは、Unityのゲームオブジェクト上でマウスの位置を取得し、その位置に存在するオブジェクトとその座標をコンソールに表示するためのものです。

コードの内容を詳しく見ていきましょう。

1行目では、UnityEngineネームスペースを使用するためにusingディレクティブが宣言されています。

3行目では、GetPieceTestというクラスが定義されています。このクラスはMonoBehaviourクラスを継承しているため、Unityのゲームオブジェクトにアタッチすることができます。

5行目では、OnGetMousePointObjectというパブリックなメソッドが定義されています。このメソッドは、GameObject型のobjVector2Int型のposという2つの引数を受け取ります。

7行目では、Debug.Logを使用してコンソールに文字列を表示しています。表示する文字列は、$を使った文字列補完を利用しています。pos.xはマウスのX座標を表し、Fugo.ConvertNumToKanji(pos.y)はマウスのY座標を漢数字に変換した結果を表しています。また、obj.nameはクリックしたオブジェクトの名前を表しています。

このコードは、ゲームオブジェクト上でマウスをクリックした時にOnGetMousePointObjectメソッドが呼び出され、クリックしたオブジェクトの情報とマウスの座標がコンソールに表示される仕組みです。

実行結果

ライブラリ

using UnityEngine;

public static class Fugo
{
    /// <summary>
    /// ワールドポジションを対応する座標(符号)に変換します
    /// </summary>
    /// <param name="pos">変換するワールド空間座標</param>
    /// <returns>対応する座標(符号)</returns>
    public static Vector2Int FromWorldPos(Vector3 pos)
    {
        Vector3Int intPos = Vector3Int.RoundToInt(pos);
        return new Vector2Int(-intPos.x, -(intPos.z + 1));
    }

    /// <summary>
    /// 数字を対応する漢字に変換します
    /// </summary>
    /// <param name="number">変換する数値</param>
    /// <returns>変換された漢字</returns>
    public static string ConvertNumToKanji(int number)
    {
        string kanjiDigits = "一二三四五六七八九";
        return kanjiDigits[number].ToString();
    }
}

このコードは、Unityゲームで使用するためのユーティリティクラス Fugo を定義しています。


コードの内容を詳しく見ていきましょう。
3行目では、Fugo という名前の静的クラスが定義されています。静的クラスは、インスタンスを作成せずに直接クラス名を使用してメソッドやフィールドにアクセスできる特殊なクラスです。


6行目から13行目では、FromWorldPos という静的メソッドが定義されています。このメソッドは、ワールド座標を受け取り、その座標を基にした Vector2Int オブジェクトを返します。
pos を Vector3Int.RoundToInt(pos) を使って整数座標に変換し、intPos という変数に代入しています。
次に、intPos.x の符号を反転したものを x とし、intPos.z に1を加えたものを符号反転して y とします。
最後に、new Vector2Int(-intPos.x, -(intPos.z + 1)) を使って x と y の値を持つ新しい Vector2Int オブジェクトを作成し、それを返します。


15行目から20行目では、ConvertNumToKanji という静的メソッドが定義されています。このメソッドは、整数の数字を受け取り、それを漢数字に変換して返します。
kanjiDigits という文字列には、"一二三四五六七八九" という漢数字の一桁の文字列が格納されています。
メソッド内で、number をインデックスとして使い、kanjiDigits[number] を取得して文字列に変換し、それを返しています。


このように、Fugo クラスは、ワールド座標と漢数字の変換といった機能を提供するユーティリティメソッドを含んでいます。静的クラスのため、他の部分から直接アクセスして利用することができます。

C#,Unity,設計

Posted by hidepon