OnGUI
вызывается только тогда, когда мышь (перемещается / щелкает) над соответствующим окном -> она не берет almost 5 seconds
, но пока вы снова не наведете указатель мыши на окно.
В порядкечтобы решить, что вы можете реализовать EditorWindow.OnSelectionChange
и заставить EditorWindow.Repaint
, чтобы ваше окно обновлялось при каждом изменении Selection
.
private void OnSelectionChange()
{
Repaint();
}
Вторая проблема создается следующим образом:
GUILayout.TextField
вместе с GUILayout.FlexibleSpace
, если не определено иначе, автоматически использует ширину вставленного текста -> Поскольку у вас пустой текст в начале, ширина равна почти 0 ... вы на самом деле можете видеть, что ваше TextField очень тонкое, и оно увеличивается по мере заполнения:

ИспользованиеЯщики из EditorGUILayout
вместо этого решают это:
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.FlexibleSpace();
searchString = EditorGUILayout.TextField(searchString, EditorStyles.toolbarTextField);
EditorGUILayout.EndHorizontal();
var items = Selection.gameObjects;
// Do comparison here. For example
foreach (var selectedObject in selected)
{
if (selectedObject .name.Contains(searchString))
{
EditorGUILayout.LabelField(selectedObject.name);
}
}
Совет Если вы замените
EditorGUILayout.LabelField(items[i].name);
на
if (GUILayout.Button(selectedObject.name, EditorStyles.label))
{
EditorGUIUtility.PingObject(selectedObject);
}
, вы можетенажмите на имя и «пингуйте» соответствующий GameObject в иерархии!
Обновление с тех пор, как это было задано в комментариях
Если вы хотите включить всех дочерних элементов рекурсивного выбора, вы можете сделать что-то вроде (могут быть и более эффективные способыэто то, что я придумал в течение 10 минут)
private static IEnumerable<GameObject> GetChildrenRecursive(GameObject root)
{
var output = new List<GameObject>();
//add the root object itself
output.Add(root);
// iterate over direct children
foreach (Transform child in root.transform)
{
// add the child itslef
output.Add(child.gameObject);
// Recursion here: Get all subchilds of this child
var childsOfchild = GetChildrenRecursive(child.gameObject);
output.AddRange(childsOfchild);
}
return output;
}
private static IEnumerable<GameObject> GetChildrenRecursive(IEnumerable<GameObject> rootObjects)
{
var output = new List<GameObject>();
foreach (var root in rootObjects)
{
output.AddRange(GetChildrenRecursive(root));
}
// remove duplicates
return output.Distinct().ToList();
}
и использование
var selected = GetChildrenRecursive(Selection.gameObjects);
Другое обновление
Так как это может быть не оченьдля повышения эффективности вы, вероятно, должны переместить его на Searching
, а затем обновить значение selected
также в OnSelectionChange
, например
public class SearchableWindow : EditorWindow
{
private string searchString = "";
private List<GameObject> selected;
[MenuItem("Tools/Searching")]
private static void Searching()
{
const int width = 340;
const int height = 420;
var x = (Screen.currentResolution.width - width) / 2;
var y = (Screen.currentResolution.height - height) / 2;
var window = GetWindow<SearchableWindow>();
window.position = new Rect(x, y, width, height);
window.selected = GetChildrenRecursive(Selection.gameObjects).ToList();
}
private void OnSelectionChange()
{
selected = GetChildrenRecursive(Selection.gameObjects).ToList();
Repaint();
}
private void OnGUI()
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.FlexibleSpace();
searchString = EditorGUILayout.TextField(searchString, EditorStyles.toolbarTextField);
EditorGUILayout.EndHorizontal();
// only as fallback
if (selected == null)
{
selected = GetChildrenRecursive(Selection.gameObjects).ToList();
}
// Do comparison here. For example
foreach (var selectedObject in selected)
{
if (selectedObject.name.Contains(searchString))
{
if (GUILayout.Button(selectedObject.name, EditorStyles.label))
{
EditorGUIUtility.PingObject(selectedObject);
}
}
}
}
private static IEnumerable<GameObject> GetChildrenRecursive(GameObject root)
{
var output = new List<GameObject>();
//add the root object itself
output.Add(root);
// iterate over direct children
foreach (Transform child in root.transform)
{
// add the children themselves
output.Add(child.gameObject);
var childsOfchild = GetChildrenRecursive(child.gameObject);
output.AddRange(childsOfchild);
}
return output;
}
private static IEnumerable<GameObject> GetChildrenRecursive(IEnumerable<GameObject> rootObjects)
{
var output = new List<GameObject>();
foreach (var root in rootObjects)
{
output.AddRange(GetChildrenRecursive(root));
}
// remove any duplicates that would e.g. appear if you select a parent and its child
return output.Distinct();
}
}
