Monday, 4 January 2016

Serializing and Saving/Loading Data in Unity3D for UWP 10

My reason for this post has come from me wanting to both port existing game projects and create new projects to be released on the Windows 10 Store. To do this is pretty simple and the wonderful Shahed has already done a great blog post on the basics of getting your Unity3D projects ported to UWP 10

This is a great place to start, but, if like me, you like to serialize your game data and write it to a file, then you will probably come across the issues I had.

My issues were namely around the restrictions on the namespaces that can be used in the UWP 10 build. To my knowledge, we can’t use binary serializers for UWP and I think the use of DataContractSerializerDataContractSerializers are recommended (I like using them anyway)

So, I decided, after having all sorts of issues porting an existing project to start from the beginning and create a game project for UWP 10 from the get go.

I created a class called Dude, this was going to store my player data, position, name score, etc.. I made this class a DataContract and the properties I wanted to save DataMemebers, all good so far…

I then created a simple Serializer class that I can use to serialize any class that is a DataContract.

As you can see it’s pretty simple.

Within my Dude class I created simple load and save methods that would use  the serializer

Again, pretty simple stuff right?

So, running this as a regular PC game all works fine, it builds, my game runs,  I can save and re load player data perfectly.

Switch to a Universal 10 build and it all went a bit wrong lol

In the serializer class I got one compile error reported by the Unity editor

Assets\Scripts\Utilities\Serializer.cs(40,23): error CS1061: 'MemoryStream' does not contain a definition for 'Close' and no extension method 'Close' accepting a first argument of type 'MemoryStream' could be found (are you missing a using directive or an assembly reference?)

It seemed that under UWP 10, the Close method on the MemoryStream is no longer there, this was simply fixed by wrapping the Close method in a #if for the appropriate build type. It may well be better to just host the MemoryStream in a using (){} as I am not sure if doing it like this could result in memory issues on UWP 10 due to the stream not getting closed.

Now, my dude class had more issues… All the issues in my save and load methods were due to the System.IO.Stream and System.Text.Encoding, this took me a little longer to sort out, but after some Google/Bing searches I discovered that Unity3D provides a UnityEngine.Windows namespace that holds a new Dictionary and File objects that can be used for saving the data, once I found that out, fixing the code was as simple as it was in the serializer class.

I hope this will help if you come across these issues, as I pulled out a fair bit of my hair solving this, and I have to tell you, I have little hair to start with :P