はじめに
みなさん、Editor拡張やっていますか?
今回はVisualElement上でキーボード入力を取得する方法を紹介します。
VisualElementにはRegisterCallback<T>()
というAPIが用意されており、特定のイベントに対してイベントを登録することができます。イベントにはKeyDownEvent
といったキーボードの入力を受け取るものがあります。
これを使用すればキーボード入力を取得できると思えますが、そううまくはいきません。
RegisterCallbackの例
rootVisualElement.RegisterCallback<KeyDownEvent>(登録したい関数)
なぜかこれだけではできないので、取得するための解決方法を紹介します。
解決方法
解決方法は実に簡単で、
focusable = true;
これを行っておくだけです。
ただしこの方法では、VisualElementをフォーカスしているときにしか入力を取得できないので注意してください。
実践
実際に実践していきます。
文字をタイピングできるVisualElementを作成してみます。
コードは以下です。
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class TypingWindow : EditorWindow
{
private string _text = "";
private VisualElement _typingElement;
public void CreateGUI()
{
_typingElement = new VisualElement
{
// キーボードイベントを受け取るためにフォーカス可能にする
focusable = true,
// 高さ幅を親の100%のサイズにする
style =
{
height = Length.Percent(100f),
width = Length.Percent(100f)
}
};
// KeyDownEventを登録する
_typingElement.RegisterCallback<KeyDownEvent>(OnKeyDown);
// 再描画される際にGenerateVisualContentを呼び出す
_typingElement.generateVisualContent += GenerateVisualContent;
rootVisualElement.Add(_typingElement);
}
[MenuItem("Window/TypingWindow")]
public static void ShowWindow()
{
GetWindow<TypingWindow>("TypingWindow");
}
private void GenerateVisualContent(MeshGenerationContext mgc)
{
// テキストを描画する
mgc.DrawText(_text, new Vector2(10, 10), 14f, Color.white);
}
private void OnKeyDown(KeyDownEvent evt)
{
// キーボードイベントのキーコードによって処理を分岐する
switch (evt.keyCode)
{
case KeyCode.None:
return;
case KeyCode.Backspace:
{
// テキストが空でない場合、最後の文字を削除する
if (_text.Length > 0) _text = _text[..^1];
break;
}
case >= (KeyCode)48 and < (KeyCode)90:
break;
default:
// それ以外のキーコードの場合、テキストにキーコードを追加する
_text += evt.keyCode.ToString();
break;
}
// 再描画する
_typingElement.MarkDirtyRepaint();
}
}
Window → TypingWindow
からウィンドウを開くことができます。
入力を取得できていますね!
以上です。
参考文献