Create ScriptableObject in External Assembly

This could be considered a Unity bug or feature.

I have a script that implements ScriptableObject. I moved it to an external assembly so that I could use it in some unit tests.

The Unit tests run without any issues.

Unfortunately, Unity has a problem finding the class because it’s in an external assembly. It looks like Unity builds a hash of script names and needs to also look in external assemblies.

Instance of GroundLayerRenderer couldn't be created because there is no script with that name.
UnityEngine.ScriptableObject:.ctor()
GroundLayerRenderer:.ctor()
TerrainData:CreateGroundLayerRenderer()
TerrainManager:Start() (at Assets/2-Scripts/Terrain/TerrainManager.cs:68)

[/Users/unity-build/Desktop/automatic-build-2/unity/Projects/../Runtime/Mono/MonoExportUtility.cpp line 685]

Here’s an example project of the issue.

ExternalScriptableObject is defined in ExternalAssembly and the ScriptableObject constructor can’t find it.

123744–4634–$externalscriptableobject001_148.zip (602 KB)

You better submit this with the bug report tool (in the Unity Help menu). That way it goes faster into the right hands than when you post it here in the forum.

My Help->report a problem is broken. Nothing happens anymore when I click that button. I think I did too many…

That menu item basically just opens the “Report Bug.app” you can find in the Unity folder.
You can try to open it directly and if it’s gone, then you need to reinstall Unity.

I know what happened. I copied my Unity.app into the Applications folder, and it just can’t find the bug reporting tool now. That makes sense. I’ll move it back.

I just invoked the report tool manually. That works.

I created another example project and submitted a bug for MonoBehaviour has the same issue.

124050–4647–$externalmonobehaviour001_106.zip (603 KB)

Unfortunately you cannot do this right now.
All your monobehaviours and scriptableobjects need to be scripts in your assets folder. They can use types defined in an external assembly, but they themselves need to be in seperate scriptfiles.

Which indeed makes unit testing quite difficult, especially when you want to test stuff that’s closer to the unity api.

What you could do is call gmcs manually on those scriptfiles, and create an external assembly that you will only use to unit test, and that you do not place back into unity.

I try to keep all my code as loosely coupled as possiblle, especially from the unity api. I unit test untill I hit the api, and the parts that really have to interact with the api, I have no unit tests for.

hth,

Bye, Lucas

I want as much as I can in my external assembly so that I can debug algorithms when I need to.

I put my data structures into an external assembly so they can be deserialized.

This restriction enforces that my data and my graphical representation of the data are decoupled.

I want the sun to shine also in the winter, and would like fresh croissants for breakfast.

Untill Unity starts playing nice with external dll’s, there’s not much you can do here. You can still move as much stuff as you possible can in your external assembly, just not the part of the scriptableobjects or monobehaviours.

Bye, Lucas

I’ve been screaming about this one for a while as well. What I do is have very thin shell classes in my assets folder script files which implement an interface for my assembly to hook up to.

Its quite tedious work to do every time you need to add a new MonoBehaviour / ScriptableObject to your project, but so far I have found no other solution.