Plugins. Am I doing it wrong?

So, I have been struggling with finding a good workflow when creating plugins for Unity.

My dev platform is Windows, and I use Visual Studio to compile the DLLs, which are copied to the Unity project library. All works well, BUT, my main headache is every time I test the Unity program, the DLL is LOCKED. And I am not allowed to overwrite it with a new DLL without quitting the project first.

So, my workflow is like this:

  1. Edit CPP code in a separate Visual Studio project, compile and build the plugin DLL, into the Unity project
  2. Run the scene in Unity, test if the DLL is working properly
  3. Edit the CPP code in Visual Studio again, rebuild, FAIL because the DLL is now in use after running in 2
  4. Close the Unity project
  5. Open the Unity project
  6. Rebuild the DLL from Visual Stutio, it now works as the DLL is no longer marked as in use

Everyone here knows how crazy slow Unity is at everything these days, espectially when using Plastic SCM, and closing and opening the project is a huge overhead where I can do nothing but look at damn progress bars 90% of my time, so this ridiculously slow circle absolutely kills productivity!

The perfect workflow would to simply have the CPP/H files directly in the Unity project foilders, and have it built automatically to a DLL from when changed, as is the case when C# code is changed. I suppose this is just an impossible dream, but there must be a better way than the slow circle above?

Am I doing it wrong?

By default, the editor will load native DLLs which have “editor” marked in the DLL supported platforms. It even has a warning about it.

To be able to update the DLL without restarting the editor, you need to disable editor loading, load it manually using kernel32.dll functions, then grab the library’s function addresses and wrap them in dynamic delegates, which you use instead of the dllimport functions. All this only works in the Editor, so if you plan to use the library in builds you need to #if UNITY_EDITOR the whole thing.

Here’s an example: http://runningdimensions.com/blog/?p=5

2 Likes

My KurtMaster2D game is all 100+ of my old C/C++ shareware games compiled into a DLL, then “run” one frame at a time from Unity. The Unity portion of the project rarely changes, so my main workflow is to make C/C++ changes and recompile the library, then re-run it.

Because of the above mount-and-lock hassle, rather than #ifdef a workaround, I just build the Unity project as an app once, and then “inject” the updated .bundle into the built app hierarchy, overwriting the previous DLL, and run the same Unity project. My entire API to the game package is only 4 methods and they never change.

Workflow:

  • edit C / C++ code
  • press Build in XCode to produce a .bundle file
  • run my “runmac” shell script to inject the new bundle and launch the Mac app of KurtMaster2D:
cp -R ./plbm1/Assets/Plugins/bundletest1.bundle dist_osx/KurtMaster2D/KurtMaster2D.app/Contents/Plugins
open dist_osx/KurtMaster2D/KurtMaster2D.app```

Obviously this would be less useful in a context where frequent Unity side changes are required, but in my case, I use Unity as basically a "shell" around the native binary games.

KurtMaster2D:

Apple iTunes: https://itunes.apple.com/us/app/kurtmaster2d/id1015692678
Google Play (including TV): https://play.google.com/store/apps/details?id=com.plbm.plbm1
1 Like

Brilliant, this will solve the issue. Thanks! :slight_smile: