UnityでEditor拡張書いていてちょっと問題にあたって解決したのでメモ
出くわした問題
次のUIを持つEditor拡張を書いていた。
- TextFieldがある
- TextFieldの中身をクリアするボタンをつける
このときにTextFieldに文字を打ったあとにボタンを押してもTextFieldの中身がクリアされていない表示になった。
実際の現象
次のコードで再現できる。
using UnityEngine;
using UnityEditor;
public class MyEditorWindow : EditorWindow
{
string myString = "";
[MenuItem("Window/My Editor Window")]
static void Init()
{
MyEditorWindow window = (MyEditorWindow) EditorWindow.GetWindow(typeof(MyEditorWindow));
window.Show();
}
void OnGUI()
{
myString = EditorGUILayout.TextField("Text Field", myString);
if (GUILayout.Button("Clear"))
{
myString = string.Empty;
}
}
}
動かしてみたのが次のgif。TextFieldはClearボタンが押されたタイミングでなく、その後のフォーカスが変更されたタイミングで空になった。
対応
フォーカスをはずさせるコードを入れることで対応できた。
if (GUILayout.Button("Clear"))
{
myString = string.Empty;
GUI.FocusControl(""); // 追加
}
フォーカスされているときは一時的に専用にデータを持っているとかなのだろうか。
余談
正しい対応方法なのだろうかヒントを得るため UnityCsReference で似たようなことやってるコードがないかを調べたら、多分同じ目的で GUI.FocuControl("") や GUI.FocusControl(null) を行っている箇所がいくつか見つかったりした。
ついでに PlayerSettingsEditor.cs では次のコードとコメントを見つけた。
// Reset focus when changing between platforms.
// If we don't do this, the resolution width/height value will not update correctly when they have the focus
GUI.FocusControl("");
やはりフォーカスがあるままだと更新がうまくいかないのかな。とりあえず公式でも同じ対応の仕方しているので大丈夫そう。