Serialization from WinForms to Unity

To make a long story short, I’m using the WinForms technology as my game editor. What I’m hoping to accomplish is to send my serialized game objects from Winforms to Unity.

I’ll use a fake example to be less complex as possible.

Step one, I create a class/structure in my WinForms project. I’ll also copy that one in my Unity folders. The class looks like this:

using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable()]
class My_Data_Structure : ISerializable
{
	public int x;
	public int y;
	public string name;
	
	public My_Data_Structure()
	{
		x = 0;
		y = 0;
		name = "This is a Unity Test, Ta-Da!";
	}
	
	public My_Data_Structure(SerializationInfo info, StreamingContext ctxt)
	{
		x = (int)info.GetValue("x", typeof(int));
		y = (int)info.GetValue("y", typeof(int));
		name = (String)info.GetValue("name", typeof(string));
	}
		
	public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
	{
		info.AddValue("x", x);
		info.AddValue("y", y);
		info.AddValue("name", name);
	}
	
	
}

Step Two, a bit later inside my Winforms project, I instantiate an object and serialize it:

My_Data_Structure my_unity_test = new My_Data_Structure();
my_unity_test.x = 100;
my_unity_test.y = 200;
			
string full_filename = "Unity_Test" + ".csdata";
Stream stream = File.Open(full_filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, my_unity_test);

From this point, I have no problem to deserialize it from within my WinForms project.

Step Four, Now I try to deserialize it from Unity. First, I copy/paste the Unity_Test.csdata inside my Unity local folder > Assets\Resources\Game_Csdata\Unity_Test.Csdata

I also make sure to import My_Data_Structure class inside my Unity project.

Then I try to get my serialized object from this script inside Unity:

Stream stream = File.Open("Assets\\Resources\\Game_Csdata\\Unity_Test.Csdata", FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
My_Data_Structure my_unity_test = new My_Data_Structure();
my_unity_test = (My_Data_Structure)bFormatter.Deserialize(stream);

Sadly I get FileNotFoundException: Could not load file or assembly ‘NGINE, Version=1.0.4944.4274, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. The system cannot find the file specified." [the error pursue many more lines]

Anyone have an idea what to do? I’m a bit lost. I’ve spent a bunch of hours trying to figure out the best way I should serialize between WinForms and Unity without success.

Thank you in advance for your help!

1 Answer

1

I’ve done something like this before, except that I serialized objects over local TCP between the two applications instead of using a file to store the data in the meantime. So I know the approach works. I don’t think there’s anything wrong with your serialization code necessarily. I just think it’s because File.Open can’t find the file, like the error says. Thankfully, that should be easy to fix.

According to File.Open on MSDN, the path can be both relative and absolute. If relative, it assumes the root is the program’s working directory, which is whatever path is returned by Directory.GetCurrentDirectory. Have you tested that this is indeed where you’re storing Assets?

Just for the heck of it, try to give it the absolute path and see if it eats that. If it does, we know it’s a path thing. You could also try to explicitly build the absolute path yourself, i.e. try with:

    File.Open(System.IO.Directory.GetCurrentDirectory() + "\\Assets\\Resources\\...etc");

Very interesting reply! It definitely give a clue on the issue, I'll make a few tests. Thanks!

–

UPDATE: I made a mistake in my last example. string curFile = System.IO.Directory.GetCurrentDirectory() + "Unity_Test.Csdata"; should be string curFile = System.IO.Directory.GetCurrentDirectory() + "\\Unity_Test.Csdata"; Now File.Exists(curFile) actually find the file, it exists on that path, and I'm dealing with the same error than before. Grr... :(

–

Oooh, I understand. You're right, it is the BinaryFormatter throwing the exception, but not for the reason I initially thought. I guess I should've read the error text a little more carefully - it's not failing to find a file, it's failing to find an ASSEMBLY. There's some assembly the BinaryFormatter needs to complete the deserialization and it can't find it. I tried running your code and got the same error. I'll get back to you if I stumble on a solution.

–

I did exactly what you asked me to do (I hope I did it right) and still the same results. I'm starting to wonder if it's not a compatibility issue with Unity...

–

As I posted in the forum discussion, using BinaryFormatter for cross-platform serialization is frowned upon and fraught with issues. Namely, BinaryFormatter includes a whole host of metadata that is going to be specific to .Net and will throw up issues when trying to deserialize the object in Mono.

–