Unity EditorWindow:修改查询结果文字颜色+修复过时API警告
修复ScriptFinder EditorWindow的两个问题
问题1:GameObject名称黑色改为白色
原代码使用GUIStyle.none导致文本在深色Editor主题下显示为黑色,解决方式是自定义适配的按钮样式,确保文字显示为白色:
- 新增全局样式变量并初始化:
static GUIStyle whiteButtonStyle; // 在OpenScriptFinder方法中初始化样式 whiteButtonStyle = new GUIStyle(GUI.skin.button); whiteButtonStyle.normal.textColor = Color.white; whiteButtonStyle.hover.textColor = Color.white; whiteButtonStyle.active.textColor = Color.white;
- 在OnGUI的按钮渲染处使用该样式:
if (GUILayout.Button(_obj.name, whiteButtonStyle)) { Selection.activeObject = _obj; EditorGUIUtility.PingObject(_obj); }
如果希望自动适配Editor深浅主题,也可以直接使用EditorStyles.label替代GUIStyle.none,它会根据主题自动调整文字颜色。
问题2:替换过时的FindSceneObjectsOfType API
GameObject.FindSceneObjectsOfType已被标记为过时,需替换为Object.FindObjectsByType,同时修正原代码中通过名称查找GameObject的同名冲突风险:
将原SelectScript方法中的循环逻辑替换为:
sceneObjects = new List<GameObject>(); // 替换过时API,指定参数确保只获取场景内对象(包含非激活) var foundComponents = Object.FindObjectsByType(_type, FindObjectsOptions.IncludeInactive | FindObjectsOptions.ExcludePrefab); foreach (Component comp in foundComponents) { Debug.Log(comp.gameObject.name); // 直接从组件获取所属GameObject,避免同名查找错误 sceneObjects.Add(comp.gameObject); }
关键说明:
FindObjectsByType需Unity 2021.3及以上版本支持;FindObjectsOptions.IncludeInactive保持和原API一致,包含非激活对象;FindObjectsOptions.ExcludePrefab确保只获取场景内的对象,排除资源中的预制体;- 直接通过
Component.gameObject获取对象,彻底避免GameObject.Find带来的同名冲突问题。
完整修改后的代码
using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.Reflection; using System; public class ScriptFinder : EditorWindow { static ScriptFinder window; static List<Type> components; static List<string> componentNames; static List<GameObject> sceneObjects; static int selectedIndex = 0; static int prevIndex = 0; static Vector2 scrollValue = Vector2.zero; static GUIStyle whiteButtonStyle; [MenuItem("EditorUtility/Script Finder")] static void OpenScriptFinder() { window = (ScriptFinder)EditorWindow.GetWindow(typeof(ScriptFinder)); Assembly _assembly = Assembly.Load("Assembly-CSharp"); components = new List<Type>(); componentNames = new List<string>(); foreach (Type type in _assembly.GetTypes()) { if (type.IsClass) { if (type.BaseType?.FullName.Contains("MonoBehaviour") ?? false) { components.Add(type); componentNames.Add(type.Name); } else { if (!type.BaseType?.FullName.Contains("System") ?? false) { Type _type = type.BaseType; components.Add(_type); componentNames.Add(type.Name); } } } } // 初始化白色按钮样式 whiteButtonStyle = new GUIStyle(GUI.skin.button); whiteButtonStyle.normal.textColor = Color.white; whiteButtonStyle.hover.textColor = Color.white; whiteButtonStyle.active.textColor = Color.white; prevIndex = selectedIndex; if (components.Count > 0) { SelectScript(components[selectedIndex]); } } static void SelectScript(Type _type) { Debug.Log("Selected Type: " + _type); sceneObjects = new List<GameObject>(); // 替换过时API并修正GameObject获取逻辑 var foundComponents = Object.FindObjectsByType(_type, FindObjectsOptions.IncludeInactive | FindObjectsOptions.ExcludePrefab); foreach (Component comp in foundComponents) { Debug.Log(comp.gameObject.name); sceneObjects.Add(comp.gameObject); } Selection.objects = sceneObjects.ToArray(); } void OnGUI() { if (components == null || components.Count == 0) { EditorGUILayout.LabelField("No MonoBehaviour scripts found in Assembly-CSharp"); return; } selectedIndex = EditorGUILayout.Popup(selectedIndex, componentNames.ToArray()); if (selectedIndex != prevIndex) { SelectScript(components[selectedIndex]); } scrollValue = EditorGUILayout.BeginScrollView(scrollValue); foreach (GameObject _obj in sceneObjects) { if (GUILayout.Button(_obj.name, whiteButtonStyle)) { Selection.activeObject = _obj; EditorGUIUtility.PingObject(_obj); } } EditorGUILayout.EndScrollView(); prevIndex = selectedIndex; } }
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

