- Home /
Access game classes from within Editor extension?
Hello everyone,
I'm currently working on an Editor extension for Unity, and therefore the classes I'm working with reside in the "Editor" folder. I now need to access classes from the actual project DLL (in other words: the classes within the project outside the Editor folder). To make more clear what I mean, here's what VisualStudio displays:
Assembly-CSharp-Editor-vs this is where my classes are placed
Assembly-CSharp-vs this is the assembly I want to access
The question is: What is the best way to do this? I imagine that one could find out the project location on the OS file system, then navigate to
projectRoot/obj/Debug/Assembly-CSharp.dll
... and grab the assembly DLL file from there, but is there a more elegant way to solve this? By the way, since this editor extension should work for all projects, I need to do this via reflection of course.
Thanks,
Alan
EDIT: To be more precise about the problem, here's what I'm trying to achieve. I want to call "Type.GetType(name)" from within an editor class, where "name" contains the type name of a type that resides outside the editor folder (therefore, in the "normal" game DLL, not in the editor DLL). However, this call will always return null from within an editor class, whether the class in question exists outside the editor folder or not. I concluded that the editor therefore does not load the game assembly by default and now I want to do this myself.
Answer by Bunny83 · Feb 17, 2013 at 02:47 AM
All project assemblies are accessible by editor scripts since editor scripts are in the last compilation group. If you don't have a certain classname you want to access, just use reflection. The classes are all there.
Here's an extension method for the Type class which gives you a list of all derived classes:
public static List< Type > GetAllDerivedClasses(this Type aBaseClass, string[] aExcludeAssemblies)
{
List< Type > result = new List< Type >();
foreach (Assembly A in AppDomain.CurrentDomain.GetAssemblies())
{
bool exclude = false;
foreach (string S in aExcludeAssemblies)
{
if (A.GetName().FullName.StartsWith(S))
{
exclude = true;
break;
}
}
if (exclude)
continue;
if (aBaseClass.IsInterface)
{
foreach (Type C in A.GetExportedTypes())
foreach(Type I in C.GetInterfaces())
if (aBaseClass == I)
{
result.Add(C);
break;
}
}
else
{
foreach (Type C in A.GetExportedTypes())
if (C.IsSubclassOf(aBaseClass))
result.Add(C);
}
}
return result;
}
public static List< Type > GetAllDerivedClasses(this Type aBaseClass)
{
return GetAllDerivedClasses(aBaseClass, new string[0]);
}
Hi, thanks for the nice utility method! However, it does not quite solve my problem yet. To be more precise: if you call "Type.GetType(name)" from within an Editor class and "name" is the name of a class that resides outside the editor folder, this call will always return null, even though the class itself exists. Therefore my conclusion was that the editor does not class-load the game assembly by default.
No, it doesn't return always null, you just have to pass the correct value. You should read the docs on GetType. GetType will only search in the currently executing assembly and the mscorelib for a given type string except you pass a assembly qualified name of the type which includes the assembly name in which the class can be found
There's two cases when GetType will find a type which is not included in the current assembly: either if you specify the qualified assembly name, or if you load the assembly first in which the type is contained. I was trying to go for the latter option. Can you tell me the qualified name of the assembly where Unity stores the C# classes that reside outside the editor folder? I already tried "classname, Assembly-CSharp" which did not work. Since Unity does not support namespaces in C#, I assume that there is something happening "behind the scenes" I'm not aware of right now...
EDIT: Ah, "Assembly-CSharp" in fact does work. There was an error in my code. Thanks for your support!