Unity’s source code for the type I need can be viewed here: DockArea.cs
I’m actually trying to use the “addTab” method metionned in DockArea.cs (Note: I cannot use GetWindow, it doesn’t allow creating multiple windows of the same type and is the only way to specify a tab placement
My code so far (for add tab):
public static void DockTab(this EditorWindow anchor, EditorWindow docked) {
var addTab = anchor.GetType().GetMethod("AddTab", BindingFlags.Instance | BindingFlags.Public);
object[] param = {docked};
addTab.Invoke(docked, param);
}
And it gives the following error:
NullReferenceException: Object reference not set to an instance of an object
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
I think the problem may be that I’m trying to use add tab the wrong way, in EditorWindow.cs there is an example of how it’s used. Been trying for days to make it work but I have no clue what I’m doing when it comes to reflection. Tried some tutorials but I still dont get it.
Please help.
UPDATE:
Here is another piece of code I tried (based on EditorWindow.cs) but I get stuck at accessing w.rootView.allChildren and will still need the DockArea type and it still not the proper usage as it would have to run this from withing the editor window being docked… I think.
public static System.Type[] GetAllDerivedTypes(this System.AppDomain aAppDomain, System.Type aType) {
var result = new List<System.Type>();
var assemblies = aAppDomain.GetAssemblies();
foreach (var assembly in assemblies) {
var types = assembly.GetTypes();
foreach (var type in types) {
if (type.IsSubclassOf(aType))
result.Add(type);
}
}
return result.ToArray();
}
public static void DockTab(Type desired) {
var containerWinType = System.AppDomain.CurrentDomain.GetAllDerivedTypes(typeof(ScriptableObject)).Where(t => t.Name == "ContainerWindow").FirstOrDefault();
if (containerWinType == null)
throw new System.MissingMemberException("Can't find internal type 'ContainerWindow'.");
var windows = Resources.FindObjectsOfTypeAll(containerWinType);
foreach (var w in windows) {
var rootviewProperty = containerWinType.GetProperty("rootView", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
// var allChildren = rootviewProperty.get
foreach (var view in w.rootView.allChildren)s
{
var dockArea = view as DockArea;
if (dockArea == null) continue;
if (dockArea.m_Panes.Any(pane => pane.GetType() == desired))
{
dockArea.AddTab(win);
}
}
}
}
Maybe its possible to override GetWindow (anothing thing I dont know how to use) to somehow prevent GetWindow from checking if a window of the requested type allready exist. If I can force it to open a new window everytime that would also work.