- Home /
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!
Answer by CHPedersen · Jul 15, 2013 at 09:03 AM
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!
Sadly no results so far. The mistake isn't on that line:
Stream stream = File.Open("Assets\\Resources\\Game_Csdata\\Unity_Test.Csdata", File$$anonymous$$ode.Open);
It seems to find the file perfectly without signaling an error, the path is correct. Besides, when I comment the remaining part of the code, the code runs without errors.
The error comes from that line:
my_unity_test = ($$anonymous$$y_Unity_Test)bFormatter.Deserialize(stream);
I'm totally clueless what might cause this error.
If any of you have some time to kill, maybe would you like to use WinForms to serialize a class object, and then try to deserialize it in Unity to see if you have more success than me? Sounds like a worthy challenge? :D
I hate to say this and sound like a mean skeptic, but I really don't think the error comes from that line. You see, your error is a FileNotFoundException, and BinaryFormatter.Deserialize does not throw FileNotFoundExceptions. See http://msdn.microsoft.com/en-us/library/b85344hz(v=vs.110).aspx. It may throw ArgumentNullException, SerializationException and SecurityException, but not FileNotFoundException.
It really smells like File.Open, as FileNotFoundException is among its list of thrown exceptions. Please run your path by File.Exists and see if it returns true or false.
It seems you might be completely right, even if the code didn't report the error on the Open.File line when the path seems correct. I tried with a wrong path and it report me an error in such case, example:
Stream stream = File.Open("Wrong\\Unity_Test.Csdata", File$$anonymous$$ode.Open); // report an error
However, as you suggested I tried the Exists() method and apparently it's the 'else' part of the code that is run which mean the file doesn't exist (or can't be found:
string curFile = System.IO.Directory.GetCurrentDirectory() + "Unity_Test.Csdata";
if(File.Exists(curFile))
{
Stream stream = File.Open("Unity_Test.Csdata", File$$anonymous$$ode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
$$anonymous$$y_Data_Structure my_unity_test = new $$anonymous$$y_Data_Structure();
my_unity_test = ($$anonymous$$y_Data_Structure)bFormatter.Deserialize(stream);
}
else
{
// file doesn't exists, nothing happens.
}
Here's the Unity Test Project if you're interested to investigate with the same data as me: https://dl.dropboxusercontent.com/u/59740378/Deserialization_Test.rar
It includes the serialized object, I've put it at the root folder this time.
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... :(
Your answer
Follow this Question
Related Questions
Why is scene object serialized multiple times when entering play mode? 1 Answer
Serialization creates file while returning nothing 2 Answers
How do I remove a serialized field correctly? 0 Answers
Json deserialisation of server results? 1 Answer
Help with Binary serialization/de-serialization of List items and the WEBPLAYER 1 Answer