[UNITY]2DRPG開発日誌 #30 マウスクリックを無効化する方法

マウスクリックを無効化したい

キー入力でボタンにフォーカスするようなシーンを作る場合、

ボタンのない場所をクリックしてフォーカスが外れてしまったり、変なボタンをクリックして移したくないボタンにフォーカスが移ってしまうことがあります。

 

これを防ぐ方法を色々と調べたのですが、全くわかりません。

最も有力なのは「EventSystemのStandaloneInputModule.csを改造する」という方法でしたが、なぜかうまくいきませんでした(自作するとEventSystemにアタッチできなかった)。

解決方法

なにをやってもダメだったので「無効化する」ことは諦めて、「クリックしたらクリック前の状態に戻る」ようにしました。

 

まずは適当にMouseDisableみたいな名前のGameObjectをつくり、そこに同じ名前のスクリプトを新規作成してアタッチします。

using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using System;
public class MouseDisable : MonoBehaviour
{
   [SerializeField] EventSystem eventSystem;
   GameObject selectedObject;

   void Update()
   {
      CheckMouseButton();
   }

   void CheckMouseButton()
   {
      if (Input.GetMouseButton(0) || Input.GetMouseButton(1) || Input.GetMouseButton(2))
      {
         //マウスクリックを検出したら、1フレーム後にフォーカスを戻す
         StartCoroutine(DelayCoroutine(1, () =>
         {
            EventSystem.current.SetSelectedGameObject(selectedObject);
         }));
      }
      else if(eventSystem.currentSelectedGameObject != null)
      {
         //マウスクリックしていないフレームでは、いまフォーカスされてるボタンを取得し続ける
         selectedObject = eventSystem.currentSelectedGameObject.gameObject;
      }
   }

   //指定フレーム後に処理を呼び出すコルーチン
   private IEnumerator DelayCoroutine(int delayFrameCount, Action action)
   {
      for (var i = 0; i < delayFrameCount; i++)
      {
         yield return null;
      }
      action?.Invoke();
   }
}

やっていることは単純で、毎フレーム「現在フォーカスされてるボタン」を保存し、クリックされたらその次のフレームで元々フォーカスされていたボタンにフォーカスを戻す、というものです。

なぜ「次のフレームで」なのかというと、同一フレーム内でフォーカスを移すとエラーになったからなのですが、ネット上で調べるとそんな事例がないので同一フレーム内で処理しても大丈夫かもしれません。