Hey,
I have read the relevant (two short) pages in the Unity 6 documentation. The bottom line here is the sentence “call into UnityPlayer.dll, which any Win32 application can load directly” and the description of the entry point’s signature. The documentation also says “The Unity Runtime Library exposes ways to manage loading, activating, and unloading within the native application.” I obviously know how to load a DLL at runtime, use exported functions, and unload it again, but I probably don’t fully understand the limits of the interface provided in the UnityPlayer.dll. I assume this entry point is the “activating”? So I can load the DLL, activate the Unity Player, and then unload the DLL again at the end, and that’s it?
Do I understand correctly that I have to let all communication (e.g. with a GameObject) between the host application and the Unity DLL take place in a different way? In the past, for example, I have created native plugins with C# wrappers for Unity that can communicate with servers etc. Does it come down to something like this?
I can’t find much information on this topic. This could of course be because it is too obvious and I am thinking in completely the wrong direction. For example, I read about functions in native iOS/Android plugins such as “UnitySendMessage” etc., but I don’t see whether this is relevant here in any way.
I would be very grateful for any pointers in the right direction.
Cheers!
Yes, you pretty much call “UnityMain” and let it boot up. Not sure about a shutdown but I think there’s got to be some example or template project on github showing the minimal steps. Or so I hope.
There is no interface. Communication happens in any way two processes can communicate, be it networking or inter-process communication (C# / .NET has something built in but not sure if supported by Mono). This may need some experimentation.
Shutdown, I’m not sure. I assume unloading the DLL will just trigger the shutdown process. Again a minimal test project to see if you can get it working would help. If anything, you may find yourself asking a specific question and when you search for that, chances are someone else also had that question but it doesn’t come up unless you specifically search for that particular issue.
Also good advice would be to inspect the player DLL with an IL viewer. That may help you discover public C# methods next to UnityMain.
Thanks for your reply.
I checked the headers in UnityPlayer.dll before posting here, it is not a .NET assemby (“0 [ 0] RVA [size] of COM Descriptor Directory”), so there is no IL to check. And UnityMain() is the only visible function. So I think, as you said, you load it, activate it and that’s pretty much it.
I will look into compatible ways of process communication. Thanks again!
Just adding to everything else that’s been said:
- Calling UnityMain will take over that thread (the function will not return). So don’t do it from your main thread.
- If you’re running in the same process (as opposed to multi processes), you can communicate with C# scripts via COM. That is the most efficient solution as it allows you to define COM interfaces and call them as if they were normal C# methods.
- You can pass the “-parentHWND” command line parameter in order to make Unity create the main window as a child window of your passed in handle. That allows you to “embed” the Unity player inside your app;
- Unloading at this time is not functional on Windows. Trying to do that will terminate the process so if you need this functionality, you will have to start Unity up in a separate process.
1 Like
Thanks to your hints, my observations in my test scenario now really make sense. I have a simple, working example with which I can test IPC methods.
Thanks!