我正在尝试为 Unity 制作一个自定义编辑器脚本,但我陷入了我认为是一个简单的步骤。 使用 UnityEditor.GetWindow() 时,窗口不会在主选项卡中打开,而是作为单独的窗口打开。 The scene view is not attached to the main Unity window.
我尝试了一些解决方法,但似乎都不起作用:
首先,我尝试使用 API 中的desiredDockNextTo 参数。 ,但我不断收到无法修复的错误。
Type inspWndType = typeof(Editor).Assembly.GetType("UnityEditor.SceneView"); EditorWindow[] allWindows = Resources.FindObjectsOfTypeAll<EditorWindow>(); Type[] insWindTypeList = new Type[allWindows.Length]; for(int i = 0; i < allWindows.Length; i++) { insWindTypeList[i] = allWindows[i].GetType(); } var window = EditorWindow.GetWindow<typeof(inspWndType)>(insWindTypeList);
我一直在
- 还尝试使用 Jayatubi's Docker但也没有成功。
TLDR:我希望能够使用 EditorWindow.GetWindow() 创建一个窗口并将其从脚本中停靠。
感谢任何可以帮助我的人。
最佳答案
首先,typeof
需要编译时常量类型而不是动态变量。
所以如果有什么应该是例如
var inspWndType = typeof(UnityEditor.SceneView);
但是,第二个问题:您不能将其作为泛型类型参数。
您想要做的是假设您的编辑器窗口看起来像例如
public class YOURWINDOW : EditorWindow
{
...
}
那么应该是
var inspWndType = typeof(UnityEditor.SceneView);
var window = EditorWindow.GetWindow<YOURWINDOW>(inspWndType);
这里不需要反射,因为您不想处理任何运行时类型,并且 UnityEditor.SceneView
无论如何都是公共(public)的。
示例:
using System;
using UnityEditor;
public class ExampleWindow : EditorWindow
{
[MenuItem("Examples/ExampleWindow")]
private static void Init()
{
var inspWndType = typeof(SceneView);
var window = GetWindow<ExampleWindow>(inspWndType);
}
private void OnGUI()
{
EditorGUILayout.LabelField("Tadaaaa!", EditorStyles.boldLabel);
}
}
现在如果您确实希望无论打开哪个选项卡都将其停靠,您可以使用反射来查找EditorWindow
的每个继承者并执行
using Linq;
...
var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes()).Where(type =>type.IsClass && !type.IsAbstract && type.IsSubclassOf(typeof(EditorWindow))).ToArray();
// This kind of equals doing something like
//var typesList = new List<Type>();
//var assemblies = AppDomain.CurrentDomain.GetAssemblies();
//foreach(var assembly in assemblies)
//{
// var allTypes = assembly.GetTypes();
// foreach(var type in allTypes)
// {
// if(type.IsClass && !type.IsAbstract && type.IsSubclassOf(typeof(EditorWindow)))
// {
// typesList.Add(type);
// }
// }
//}
//var types = typesList.ToArray();
var window = GetWindow<YOURWINDOW>(types);
请注意,由于顺序,ConsoleWindow
几乎是第一个条目,因此如果打开了一个控制台选项卡,它总是首先附加到该选项卡 ^^
您仍然可以添加您喜欢的内容,例如
var types = new List<Type>()
{
// first add your preferences
typeof(SceneView),
typeof(Editor).Assembly.GetType("UnityEditor.GameView"),
typeof(Editor).Assembly.GetType("UnityEditor.SceneHierarchyWindow"),
typeof(Editor).Assembly.GetType("UnityEditor.ConsoleWindow"),
typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser"),
typeof(Editor).Assembly.GetType("UnityEditor.InspectorWindow")
};
// and then add all others as fallback (who cares about duplicates at this point ? ;) )
types.AddRange(AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes()).Where(type =>type.IsClass && !type.IsAbstract && type.IsSubclassOf(typeof(EditorWindow))));
var window = GetWindow<YOURWINDOW>(types.ToArray());
因为它实际上从头到尾遍历该数组并使用第一个匹配的打开的窗口类型。
关于c# - 如何从脚本在 Unity 中创建窗口并将其附加到现有选项卡?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71322699/