- Home /
Subclassed MonoBehavior in External DLLs Not Recognized
This may be a bug, or it could be I'm doing something wrong.
I am having trouble getting the editor to recognize the existence of a C# class in an external DLL under certain conditions. Specifically, when this class derives from an intermediate class that resides in a different external DLL, which in turn derives from MonoBehavior. ie:
Assembly A contains this class: class A : MonoBehavior
Assembly B contains this class: class B : A
The class A is recognized and shows up in the editor, but class B does not. When I move class B into the same assembly as class A, both of them ARE recognized and it all works fine.
There seems to be something about them living in separate assemblies combined with the use of inheritance that is causing the editor not to recognize class B as a valid class deriving from MonoBehavior.
Can anyone offer a solution/workaround? Is this a real bug?
Thanks, Jeremy
Never tried such a setup, but it should work. Where have you placed your dlls? They should be just somewhere in the Assets folder.
I'll have to try this myself before i can say something concrete...
(As of Unity 3.5.6) Similar bug when I have a generic base compoennt class $$anonymous$$yBaseComponent<T> : $$anonymous$$onoBehaviour and a derived component $$anonymous$$yDerivedComponent : $$anonymous$$yBaseComponent<string>. This works in scripts, but not with a DLL (even if both classes are in the same DLL).
Answer by GeraldOBBI · Jul 07, 2014 at 11:26 PM
Hello there! We managed to get Unity to patch this in 4.5.x. I verified it myself (see http://answers.unity3d.com/questions/594712/monobehaviours-editors-with-inheritance-across-dll.html). Enjoy!
I am still experiencing this issue with Unity 4.5.3f3. Do you know if this patch has regressed?
Oh nm, I just read your fine print in the other QA... the DLL must live alongside one another. That kinda sucks, how strange! Thanks :)
Answer by Bunny83 · Apr 16, 2012 at 11:24 PM
Ok i've double checked it and it seems Unity doesn't recognise MonoBehaviour classes in this special case. I'm not sure why since with reflection you can see the class, so it is there but Unity doesn't include it in it's AssetDatabase so you can't use AddComponent.
Well you can use AddComponent but it just prints a funny debug message:
when using AddComponent<MyClass>();
""
"UnityEngine.GameObject:AddComponent()"
when using AddComponent(typeof(MyClass));
""
"UnityEngine.GameObject:AddComponent(Type)"
when using AddComponent("MyClass");
"Can't add component because class 'MyClass' doesn't exist!"
"UnityEngine.GameObject:AddComponent(String)"
This happens because the class itself is there, but it's not registrated in the AssetDatabase. So i would say it's a bug (or limitation if you want)
I got some news:
I've done some tests with dynamically loaded assemblies (i think i've recompiled my dll 40+ times). It does work! The big problem: namespaces!
We all know the docs states that namespaces aren't supported. Yes that's true, but when you compile an Assembly created in Visual studio it usually creates a namespace. Unity ignores the namespace when it imports the dll.
Here is the flaw: It seems that the namespace is ignored, but infact it isn't. When you put the dll into the asset folder Unity "sees" the classes and can use it, but they are still in another namespace. When you create your two assemblies put all your classes in the global namespace, then it works ;)
The same applies for Assemblies that are dynamically loaded (via WWW + reflection). The classes are there, but you can't use them unless they are in the global namespace.
It does work! The big problem: namespaces!
I cannot get this working. Could you post a simple example of how you set up the classes? I had done a bunch of testing on this problem recently and I found several problems: I was never able to see the $$anonymous$$onoBehaviour derrived classes in the project view (normally a DLL with $$anonymous$$onoBehaviours has an arrow drop down that allows you to drag and drop them onto objects). However, I WAS able to add the components using scripting (AddComponent), BUT the monobehaviour it added to the object was completely broken. It showed up in the inspector as "Script" ins$$anonymous$$d of a named class, and if you saved the scene/prefab and reloaded, it would lose the data and the link to the class completely because it did not store both a fileID and GUID in the .meta file for the object. I was even able to get the editor to crash every time when I went through certain steps involving prefabs. (See my post at http://forum.unity3d.com/threads/148617-Problems-compiling-DLLs-from-$$anonymous$$onoDevelop?p=1022960&viewfull=1#post1022960) I reported this to Unity as a bug. I did also come up with a workaround that involves merging DLLs into one using $$anonymous$$icrosoft IL$$anonymous$$erge. (See http://forum.unity3d.com/threads/148617-Problems-compiling-DLLs-from-$$anonymous$$onoDevelop?p=1023568&viewfull=1#post1023568 for the workaround).
Well, unfortunately I can't make it work in the editor ;) So it's an editor bug since i can use the components at runtime without any problem. The class type is there and can be used even from "normal" scripts. I was searching for a way to create the $$anonymous$$onoScript sub assets manually, but that's not possible since all members of the $$anonymous$$onoScript class map to native code. Also an imported assembly has no type (just UnityEngine.Object) in the editor. This makes it almost impossible to create a custom inspector for dll assemblies.
So when you put both assemblies in the assetfolder you can just use AddComponent from another script. $$anonymous$$y test class is just called Class1 so i do this:
gameObject.AddComponent<Class1>();
And i get this:
Note that the component doesn't have the correct name and no asset reference since there's no $$anonymous$$onoScript asset for this class. It does work anyways but it's clearly an editor / importer bug.
Yes, this is exactly what I got adding it to a scene object with an editor script. Your serialized data will get trashed if you try to save/load it and the editor will crash if you put it on a prefab. Oh well. I already reported this as a bug to Unity so we'll see if they fix it. Thanks!