I decided to split my code into two seperate projects, a client and a server project. In order for the projects tp share similar code I decided to wrap the shared code into a .dll. However, some of the code that resides in the .dll are Networkbehaviours that makes use of SyncVar, Command and ClientRPC.
In an ordinary project when compiling, Unity identifies these special markers and generates boilerplate code, but this all happens behind the scenes. Because my code resides in a .dll Unity is not capable of generating the necessary code and thus state syncronisation does not work.
How would you guys go about this? Is it even possible to use .dll at all in this case? Can I reuse Unity’s code generation and apply it to the .dll I build?
After posting this, I found topics with a similar question:
By investigating the source code of UNet it appears that the code generation magic is done by UNetWeaver. I assume I could invoke UNetWeaver myself, but I am not certain what arguments I should pass.
For @ and whoever it may interest, I figured out you can invoke UNetWeaver yourself to apply the code generation to your own custom .dll
I ended up creating a new console project in visual studio. I added UNetWeaver.dll and Mono.Cecil.dll as references to that project.
I ended up writing the following:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
Unity.UNetWeaver.Program.Process
(
@"D:\Unity\Editor\Data\Managed\UnityEngine.dll",
@"D:\Unity\Editor\Data\UnityExtensions\Unity\Networking\UnityEngine.Networking.dll",
@"D:\MyUNetWeavingSolution\WeaverOutput\", //Output directory for the new .dll file
new string[]
{
@"D:\MyDLLProject\bin\Release\Assembly-MyDLL.dll" //Your custom dll file. Remember to add "Assembly-" in front of the name
},
new string[]
{
},
null,
(str) => Console.WriteLine("Warning: " + str),
(str) => Console.WriteLine("Error: " + str)
);
}
}
Remember, it is important that you add the prefix “Assembly-” to your custom build .dll, so its name becomes something like “Assembly-MyDLL.dll”
You build or run the executable and a new code-generated DLL should be found in the output folder.
I could attempt at writing a more general solution, but I believe people are better off doing it themselves at this point.
Hi @Freaking-Pingo
I managed to use UNetWeaver to inject the code needed for synchronization, RPCs and Commands to work thanks to your assistance. The thing is whenever I run the console project it removes the pdb file generated with my custom dll, thus I’m not able to debug my code whenever I use the dll in another project. Any clue what to do ?
I don’t exactly get what you mean, I just use the UnityEngine.Networking.dll in my custom dll which handles a lot of behaviors beside the network behaviors.
What I do:
1- Build the dll. At this point, I can attach the debugger to the project that has the dll if I copy it to the project but UNet synchronization doesn’t work.
2- Run UNetWeaver console project on my custom dll, which injects code for UNet attributes and rpc calls. Hence, the lines offset is changed only inside the output dll, that’s why I believe it deletes the old pdb cuz it won’t work anyways.
3- I finally get a dll that has UNet synchronization working but I don’t have a pdb to debug it.
I tried using dotpeek to decompile the dll, copy the injected code to my original project and rebuild the dll, thus I won’t need to use UNetWeaver, and I can attach my debugger, but that’s a really messy solution. I’ll have to do this whole process each time I change anything in my NetworkBehaviours.
I haven’t stumbled upon any debug symbol generation when using UNet weaver and I am a little bit too hung up on work to actually investigate it at the moment. Try reach out to Unity Technologies and see if they can provide some information on this. I believe there must be a solution to this we are not aware of.