Unity Player - XmlSerialization failure that works in Editor

I’m running into a wall. I’m using System.Xml.Serialization to serialize and deserialize objects to and from XML.

The serialization logic works as expected in the Unity editor, but is failing in the Unity player.

I’ve attached the following example project.

The scene contains:

  • GameObject - attached script TAGTerrainScript and attached GUI Text components.

  • GUIText - Prints the result, deserialization okay, or deserialization failed.

  • Main Camera - the camera

The project contains:

  • NoiseGenerator - has a list of public properties to be deserialized

  • TerrainFragment - more public properties to deserialize, only has a NoiseGenerator

  • The Scene - just the scene file

  • Serialization Cache - since XmlSerialization objects leaks memory like crazy, a generic dictionary of serialization objects with a dictionary key on the typeof(object).

  • TagTerrainScript - a simple script that gets the XML from a URL and deserializes. The result is tested for null and a message is printed on the screen.

Now, I’ve done multiple tests. It doesn’t make any difference whether I use UnityEngine.WWW or HttpWebRequest. I can log the XML. The part that’s failing is the deserialization call.

Here is the error that I have recorded in the player log.

System.NotSupportedException: [url]http://tagenigma.com/qa/unity3d/wip/maps/tf_citymap.xml[/url]
  at System.Net.WebRequest.GetCreator (System.String prefix) [0x00000] 
  at System.Net.WebRequest.Create (System.Uri requestUri) [0x00000] 
  at System.Xml.XmlUrlResolver.GetEntity (System.Uri absoluteUri, System.String role, System.Type ofObjectToReturn) [0x00000] 
  at Mono.Xml2.XmlTextReader.GetStreamFromUrl (System.String url, System.String absoluteUriString) [0x00000] 
  at Mono.Xml2.XmlTextReader..ctor (Boolean dummy, System.Xml.XmlResolver resolver, System.String url, XmlNodeType fragType, System.Xml.XmlParserContext context) [0x00000] 
  at System.Xml.XmlTextReader..ctor (Boolean dummy, System.Xml.XmlResolver resolver, System.String url, XmlNodeType fragType, System.Xml.XmlParserContext context) [0x00000] 
  at System.Xml.XmlReader.Create (System.String url, System.Xml.XmlReaderSettings settings, System.Xml.XmlParserContext context) [0x00000] 
  at System.Xml.XmlReader.Create (System.String url, System.Xml.XmlReaderSettings settings) [0x00000] 
  at System.Xml.XmlReader.Create (System.String url) [0x00000] 
  at SerializeCache.DeserializeUrl2 (System.String url, System.Type type) [0x00000] 
UnityEngine.Debug:LogError(Object)
SerializeCache:smile:eserializeUrl2(String, Type)
TAGTerrainScript:Start()
 
(Filename: /Users/unity-build/Desktop/automatic-build-2/unity/Projects/../Runtime/Export/Generated/BaseClass.cpp Line: 1651)

Failed to deserialize
UnityEngine.Debug:Log(Object)
TAGTerrainScript:Start()

Again, this works as expected in the Unity Editor. This does not work as expected in the Unity Web Player on MacOS. This works as expected as an OSX standalone player.

111294–4266–$deserialization001_191.zip (493 KB)

The core issue here is that the Unity compiled assembly name changes (looks like a guid). And therefore, the assembly cannot be found for deserialization.

The painful workaround is to put the data structures into external DLL assets.