Unity compiles your scripts into several Assemblies. One first-pass, one “second pass” (normal) and one editor assembly for each language! That means in the worst case you have 9 assemblies (when you use all 3 languages, each one has scripts in the Asset folder, Standard Assets folder and editor folder).
This little script gives you all loaded assemblies:
// C#
System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
foreach (var A in assemblies)
{
Debug.Log(A.FullName);
}
In my test project it returns those:
System.Runtime.Serialization
System.Xml
Boo.Lang
UnityScript.Lang
I18N.West
I18N
StrumpyShaderEditor
PluginBase
Ionic.Zip
ClassLibrary1
ICSharpCode.SharpZipLib
99aa27bda4361f14daa122d8422328a8 // those are my script assemblies
6dac0c9e57c785f48af23cab4b6a9065 //
e5fb0309aa8d3f343b2426d5b5cbb406 // I have used C# and UnityScript
89151c5adb8fb004db23eed2920f5f0b // so there are 6 assemblies ;)
0ffeb8055303a1e42bd4fe4f136bb35d //
1998a47c8bf283646903c1fefb57955f //
System.Core
Mono.Cecil
System
UnityEditor
UnityEngine
mscorlib
Unity have to do this so other languages can use an assembly from another language. However to use an assembly it has to be compiled first. That’s why we have a first pass and a second pass assembly. The first-pass assemblies can’t use each other. They are compiled at the same time so they can’t reference each other.
The second-pass assemblies are compiled next so they can use all first-pass assemblies, but not other second-pass assemblies. That’s why you have to put scripts that should be accessible from another language in a first-pass folder (Standard Assets, plugins).
Editor assemblies, which are only build and used in the editor, are compiled last so they can use all previous assemblies.
To get a complete list of certain classes you have to crawl through all assemblies.
Here’s a helper function that returns all types derived from a certain baseclass:
public static System.Type[] GetAllSubTypes(System.Type aBaseClass)
{
var result = new System.Collections.Generic.List<System.Type>();
System.Reflection.Assembly[] AS = System.AppDomain.CurrentDomain.GetAssemblies();
foreach (var A in AS)
{
System.Type[] types = A.GetTypes();
foreach (var T in types)
{
if (T.IsSubclassOf(aBaseClass))
result.Add(T);
}
}
return result.ToArray();
}
void Start ()
{
foreach (var T in GetAllSubTypes(typeof(MonoBehaviour)))
{
Debug.Log(T.Name);
}
}
Final note: You can put your classes into namespaces without any problems. However Unity “extracts” classes that are derived from MonoBehaviour into the global namespace. That’s why namespaces for MonoBehaviours become irrelevant. You can’t have two MonoBehaviours (or Editor, EditorWindows, …) with the same name, even when they are in different namespaces.