マウスカーソルが重なったことを検知する処理の作り方

前回、カメラを回転させてプレイヤーの視点移動を行う処理を作ることができました。そこで次は脱出ゲームに必須の「マウスカーソルでクリックしたオブジェクトを調べる」という処理を作っていこうと思います。

ただしその前に、そもそもそのオブジェクトが調べられるのかどうかをプレイヤーが知ることができた方が親切なので、ここではまず「マウスが重なった(=マウスオーバーした)ときにカーソル画像を変える」処理を作ってみましょう。

なおここからは少し長めのC#スクリプトを書くことになるので、初心者の方はわからない部分があったら適宜調べるなどして丁寧に読んでいってくださいね。

スポンサーリンク

「マウスが重なった」ことを検知する方法

では、まずスクリプトを書く前に「どうやってマウスオーバーを検知するか?」を考えておく必要があります。いったいどうすればマウスが重なったことを検知できるでしょうか?

先に結論を言ってしまうと、今回はマウスの位置から「レイ」を飛ばし、それに何らかのゲームオブジェクトが当たったかどうかでマウスオーバーを検知することにします。

空間上のオブジェクトを検知したいときは「レイ」を飛ばすのが基本

ところで、そもそも「レイ」って何?と思う方もいるかもしれないので一応説明しておきます。

Unityで言うところのレイとは透明なレーザー光線のようなもので、ヒットしたゲームオブジェクトを検出することができる便利な機能です(ただしレイに当たるのはコライダーを持つゲームオブジェクトだけなので注意)。これを使うと例えば

  • 進行方向に障害物があるか調べる
  • 障害物までの距離を測る
  • レイが当たった位置を取得して利用する

といった色々なことができます。特にアクションゲームで頻繁に使う機能なのでついでに覚えておいてください。

「ScreenPointToRay」でスクリーン上からレイを飛ばす

さてレイの飛ばし方はいくつかあるのですが、今回はカーソルの位置からレイを飛ばしたいので「ScreenPointToRay」というメソッドを使います。

ScreenPointToRayについてはUnityの公式リファレンスをご覧ください。

Camera-ScreenPointToRay - Unity スクリプトリファレンス
スクリーンの点を通してカメラからカメラからレイを通します。

マウスオーバー判定&カーソル変更を行うC#スクリプト

これでマウスオーバーを検知する方法が分かったので、次はそれをC#スクリプトに落とし込んでいきます。適当なフォルダに新しいC#スクリプトを作り、名前を「CursorManager」に変更して次のコードを書いてください。

using UnityEngine;

public class CursorManager : MonoBehaviour
{

  [SerializeField]
  Texture2D defaultCursor = null;
  [SerializeField]
  Texture2D interactCursor = null;

  Camera mainCamera;
  RaycastHit hit;
  GameObject targetObject;

  void Start()
  {
    mainCamera = Camera.main;

    SetCursor(true);
  }

  void Update()
  {
    // マウスの左ボタンが押下されたら、対象オブジェクトを調べる処理
    if (Input.GetMouseButtonDown(0))
    {
      LookUpTargetObject();
      return;
    }

    CastRay();
  }

 void OnDisable()
 {
   SetCursor(true);
 }

  // マウスカーソルの位置から「レイ」を飛ばして、何かのコライダーに当たるかどうかをチェック
  void CastRay()
  {
    Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);

    if (Physics.Raycast(ray.origin, ray.direction, out hit, Mathf.Infinity))
    {
      targetObject = hit.collider.gameObject;

      SetCursor(false);
    }
    else
    {
      targetObject = null;

      SetCursor(true);
    }
  }

  // 対象のオブジェクトを調べる処理
  void LookUpTargetObject()
  {
    if(targetObject == null)
    {
      return;
    }

    SetCursor(true);

    targetObject.GetComponent<InteractableObject>().LookUp();

    // このコンポーネントを無効にする(そうしないと調べている最中に別のオブジェクトを調べることができてしまう)
    enabled = false;
  }

  public void SetCursor(bool isDefault)
  {
    if (isDefault)
    {
      Cursor.SetCursor(defaultCursor, Vector2.zero, CursorMode.Auto);
    }
    else
    {
      Cursor.SetCursor(interactCursor, Vector2.zero, CursorMode.Auto);
    }
  }

}

難しいことはやっていないのでコメントを参考にしつつ処理内容を理解してください。

なお現時点ではエラーが出ると思いますが、この後の作業「脱出ゲームのオブジェクトを調べる処理の作り方」を行うと消えるので今はそのままで構いません。

スクリプトをアタッチし、カーソル画像を登録する

スクリプトを書いたら、あとはそれを適当なゲームオブジェクトにアタッチしてカーソル画像を登録しましょう。ここではとりあえずメインカメラにスクリプトをアタッチすることにします。

そうするとCursorManagerコンポーネントに

  • Default Cursor
  • Interact Cursor

という2つの欄が出るので、それぞれ次のイラスト素材を設定してください。

カーソル画像(デフォルト) カーソル画像(調べるとき用)

※素材をダウンロードしたら、Assetsフォルダ内の適当な場所にコピペして「テクスチャタイプ」を「カーソル」にするのをお忘れなく。


次のページ→シンプルなアイテム管理システムの作り方