マウスで操作する (入力システムパッケージ版)

ページ更新日 :
ページ作成日 :

検証環境

Windows
  • Windows 11
Unity エディター
  • 2020.3.25f1
入力システムパッケージ
  • 1.2.0

この Tips の前提設定

この Tips の説明の前提として以下の設定を事前に行っています。

マウスの位置を取得する

ゲーム画面上のマウスの位置は Mouse.position で取得可能です。 ここではその位置情報を表示させてみたいと思います。

Canvas にマウスの情報を表示するテキストオブジェクトを配置します。

マウスの情報はスクリプトで取得します。 ここではプロジェクトに MouseInfo というスクリプトファイルを作成します。

スクリプトは以下のように入力します。

using System.Text;              // 追加
using UnityEngine;
using UnityEngine.InputSystem;  // 追加
using UnityEngine.UI;           // 追加

public class MouseInfo : MonoBehaviour
{
  /// <summary>情報を表示するテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  private StringBuilder Builder = new StringBuilder();

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    if (TextObject == null)
    {
      Debug.Log($"{nameof(TextObject)} が null です。");
      TextObject.text = "";
      return;
    }

    var mouse = Mouse.current;
    if (mouse == null)
    {
      Debug.Log("マウスがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // マウスの位置を取得する
    Builder.AppendLine($"Mouse.position={mouse.position.ReadValue()}");

    TextObject.text = Builder.ToString();
  }
}

Mouse.current は現在アクティブなマウスの情報を取得することができます。 Mouse.position にはマウスの現在位置を Vector2Control で持っているので ReadValue メソッドを使うことにより Vector2 形式で値を取得することができます。

取得したマウスの位置はテキストオブジェクトにセットしています。 わざわざ StringBuilder を使っているのは後で追記するためのものですのであまり気にしないでください。

スクリプトを保存したら EventSystem オブジェクトにアタッチします。 Text Object には情報を表示するテキストオブジェクトをセットしておきます。

ゲームを実行してマウスを動かしてみてください。リアルタイムでマウスの位置が画面に表示されると思います。

ちなみにマウス位置の座標についてはゲーム画面上の左下が (0, 0) となります。 X軸(左右)は右にいくほどプラスになり左にいくほどマイナスになります。 Y軸(上下)は上にいくほどプラスになり下にいくほどマイナスになります。 なので各軸の最大値はゲーム画面の右上となります。

また、この座標についてはあくまでゲーム画面空間での話になりますのでゲーム内のピクセルサイズとデバイスのスクリーン座標のピクセルサイズは一致しない場合がありますので注意してください。

ホイールのスクロール量を取得する

マウスのホイールでのスクロールもスクリプトで取得することができます。 スクロール量は Mouse.scroll で取得することが可能です。 マウスの位置とは異なり瞬間的にスクロールした量しか取得できません。 これまでにどれぐらいスクロールしたかは取得できませんので注意してください。

スクロールの動作確認については先ほど作成した MouseInfo に追記してみます。

// 省略

public class MouseInfo : MonoBehaviour
{
  // 省略

  /// <summary>スクロールした量を保持する。</summary>
  private Vector2 ScrollValue = Vector2.zero;

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    // 省略

    // スクロール量を取得し保持する
    ScrollValue += mouse.scroll.ReadValue();

    Builder.Clear();

    // マウスの位置を取得する
    Builder.AppendLine($"Mouse.position={mouse.position.ReadValue()}");
    // スクロール量を表示
    Builder.AppendLine($"ScrollValue={ScrollValue}");

    TextObject.text = Builder.ToString();
  }
}

Mouse.current にはこれまでスクロールした量は保持されていませんので、 専用にスクロール量を保持するフィールド ScrollValue を定義しておきます。

Mouse.scroll ではその瞬間スクロールした量が取得できるのでその値を蓄積していきます。 例えばホイールを2回スクロールすれば ScrollValue には2回スクロールした量が保持されるというわけです。

後はこの値をテキストで表示させます。

ではゲームを実行してホイールを回してみてください。スクロール量が表示されると思います。

Mouse.scrollVector2 で値を持っていますが、縦スクロールのみのホイールであれば Y の値のみがセットされると思います。

ちなみにスクロールしてみると 120 単位で値が上下すると思います。 これは Windows で定義されている値なので他の環境であったりマウスの種類によっては数値は変わる場合があります。

マウスのボタンでクリックしたタイミングを判定する

ここではマウスの左ボタンをクリックした位置にテキストを表示させるサンプルを動かしてみたいと思います。 クリックしたタイミングはキーボードのキーと同じように wasPressedThisFrame プロパティで判定することが可能です。

まず移動用のテキストオブジェクトを配置しておきます。サイズや位置は適当でいいです。

クリック処理用のスクリプトを作成します。名前は MouseButtonClick としておきます。

スクリプトを以下のようにします。

using UnityEngine;
using UnityEngine.InputSystem;  // 追加
using UnityEngine.UI;           // 追加

public class MouseButtonClick : MonoBehaviour
{
  /// <summary>情報を表示するテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;
  [SerializeField] private Canvas CanvasObject;

  /// <summary>Canvas の RectTransform の参照です。</summary>
  private RectTransform CanvasRect;

  // 最初のフレーム更新の前に開始が呼び出されます
  void Start()
  {
    if (CanvasObject == null)
    {
      Debug.Log($"{nameof(CanvasObject)} が null です。");
      return;
    }

    // Canvas から RectTransform を取得しておきます。
    CanvasRect = CanvasObject.GetComponent<RectTransform>();
  }

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    if (TextObject == null)
    {
      Debug.Log($"{nameof(TextObject)} が null です。");
      return;
    }
    if (CanvasObject == null)
    {
      Debug.Log($"{nameof(CanvasObject)} が null です。");
      return;
    }

    var mouse = Mouse.current;
    if (mouse == null)
    {
      Debug.Log("マウスがありません。");
      return;
    }

    var transform = TextObject.transform;

    // マウスの位置を取得する
    var mousePosition = mouse.position.ReadValue();

    // マウスの位置を Canvas の座標に変換する
    var mouseOnCanvas = new Vector2(mousePosition.x - CanvasRect.sizeDelta.x / 2, mousePosition.y - CanvasRect.sizeDelta.y / 2);

    // 左ボタンがクリックしたタイミングか判定
    if (mouse.leftButton.wasPressedThisFrame)
    {
      transform.localPosition = mouseOnCanvas;
    }
  }
}

クリックした位置にテキストオブジェクトを移動するという処理を行うのですが、 UI オブジェクトのローカル位置は Canvas の座標になるためスクリーン座標であるマウスの位置とは異なります。

Canvas の原点 (0, 0) は中央であるため、RectTransform.sizeDelta を使用して Canvas サイズの半分を取得し、 マウス座標の原点の位置を中央にずらしています。

クリックしたタイミングかどうかは mouse.xxxxxxxx.wasPressedThisFrame で判定でき、クリックした瞬間のみ true を返します。 ボタンをクリックしたままにしても再度クリックするまでは false を返し続けます。

スクリプトを保存したら EventSystem にアタッチします。今回は Canvas も使うので Canvas とテキストオブジェクトをセットします。

ゲームを実行しクリックした場所にテキストオブジェクトが移動するか確認してみてください。 クリックした瞬間のみ処理するため、クリックしたままマウスを移動してもテキストオブジェクトは移動しません。

マウスのボタンを離したタイミングを判定する

サンプルとしては載せていませんが wasPressedThisFrame の代わりに wasReleasedThisFrame を使用することによって離したタイミングを判定することができます。

ボタンをクリックしている間判定する

mouse.xxxxxxxx.isPressed を使用することによりボタンをクリックしている間は true を返し続けます。 ここでは右ボタンを押している間はテキストが回転するようにしてみたいと思います。

スクリプトは左クリックのものを流用します。以下のように修正してください。

// 省略

public class MouseButtonClick : MonoBehaviour
{
  // 省略

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    // 省略

    // 右ボタンを押している間はオブジェクトを回転させる
    if (mouse.rightButton.isPressed)
    {
      transform.Rotate(0, 0, 1);
    }
  }
}

スクリプトを保存したら実行して確認してみてください。 右ボタンを押している間はオブジェクトがずっと回転し続けます。