マウスクリックを無効化したい
キー入力でボタンにフォーカスするようなシーンを作る場合、
ボタンのない場所をクリックしてフォーカスが外れてしまったり、変なボタンをクリックして移したくないボタンにフォーカスが移ってしまうことがあります。
これを防ぐ方法を色々と調べたのですが、全くわかりません。
最も有力なのは「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();
}
}
やっていることは単純で、毎フレーム「現在フォーカスされてるボタン」を保存し、クリックされたらその次のフレームで元々フォーカスされていたボタンにフォーカスを戻す、というものです。
なぜ「次のフレームで」なのかというと、同一フレーム内でフォーカスを移すとエラーになったからなのですが、ネット上で調べるとそんな事例がないので同一フレーム内で処理しても大丈夫かもしれません。