Search Unity

Private field serialization problems in Windows App Store DLL

Discussion in 'Unity 5 Pre-order Beta' started by guavaman, Feb 28, 2015.

  1. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,835
    When building to Windows App Store in Unity 5, the build fails with the error

    Rewired.InputManager_Base exists in Rewired_Core.dll in both the Metro version and the version used in the editor. The serialized fields on the two classes are completely identical.

    Nothing has changed in this project from Unity 4.3 - 4.6.3 which all build flawlessly.

    The Metro DLL was linked to WinRTLegacy.dll from Unity 4.5.3, and I have tried recompiling everything linked to Unity 5 RC3 and get the same error.

    Does anyone have any ideas?
     
  2. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    1,991
    Try opening both dll's with http://ilspy.net/, if serialized fields really matches, and you're sure it's a bug, please submit a bug with repro project attached.

    Thank you
     
  3. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,835
    Hi,

    Just checked them in ILSpy and the serialized fields are identical as expected. I've submitted it: Case 676167.

    It's very unfortunate, but this bug will break Windows App Store support in Unity 5 for my product.
     
  4. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    6,565
    Hi,

    just had a really quick look at it. Problem is that in both DLLs field _userData (and other fields in that matter) have custom attributes order swapped out.

    On Windows Store DLL, their order is:

    [UnityEngine.SerializeField]
    [Rewired.CustomObfuscation]

    On Editor DLL, their order is:

    [Rewired.CustomObfuscation]
    [UnityEngine.SerializeField]

    Looks like our serializer gets confused by it and thinks it should not serialize the field in the editor.

    Are you using different compilers to compile both DLLs? It might be worth a shot to build both with MIcrosoft's C# compiler, just one targeting .NET 3.5 and another one .NET for Windows Store.

    Another workaround would be to remove CustomObfuscation attribute temporarily until we fix it.
     
  5. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,835
    Thanks so much for taking a look at it so quickly! That's going above and beyond the call! :)

    That's very odd. The order shows the same for me in ILSpy on both DLLs. However, the order in the source code is reversed from what the compiler builds. In the source, SerializeField always comes first, but in the IL it's second.

    I'm compiling both in Visual Studio 12. The files in the .NETCore project are just linked from the same files in the .Net35 project. There are a few minor differences in code between the two using #IF statements, but never where serialized data is concerned.

    This is great news! I will do some experiments and see if I can find a combination that will get this to compile without breaking the serialized data in all my users' projects.

    Thanks again for the speedy help!
     
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,835
    It looks like the problem lies elsewhere. I just did a test where I removed the [CustomObfuscation] attribute from all fields in the class and disabled obfuscation entirely and it still has the error. Then I removed [CustomObfuscation] from all fields in my entire project, disabled obfuscation entirely, and the error still occurs. Should I resubmit the bug report with the unobfuscated version without the CustomObfuscation fields?

    Edit: I tried changing all serialized fields in all classes contained within UserData to public instead of private or protected and it still fails.

    Edit2: I tried removing [SerializeField] from all fields in all classes contained within UserData. Still fails.
     
    Last edited: Feb 28, 2015
  7. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,835
    I discovered the source of the problem:

    In my project, as a C# file included in the Assets folder I have a class "InputManager" which inherits from "InputManager_Base" which is an abstract class contained within the Rewired_Core.dll which inherits from MonoBehavior.

    MonoBehavior -> InputManager_Base (in DLL) -> InputManager (in project)

    I noticed the error said '[Assembly-CSharp]Rewired.InputManager_Base', which was odd because Assembly-CSharp does not contain InputManager_Base, but only InputManager. Deleting the InputManager.cs file from the project makes the error no longer occur. Further, if I change InputManager_Base into a non-abstract class and add its component to a game object directly, the project compiles.

    It looks like the inheritance of a class from within a DLL was broken in Metro in Unity 5 when it contains serialized fields that contain serialized classes (notice it doesn't choke on the private bool field, only the first class field UserData).

    Unfortunately, I don't think there will be any workaround for me on this as my structure of inheritance is absolutely necessary in order to be able to act on different platform defines from within the DLL.

    Note: It still occurs if I make the base class normal and no longer abstract.
     
    Last edited: Feb 28, 2015
  8. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    6,565
    Bummer. Either way, thanks for the report.
     
  9. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,835
    Thanks!