Serialization layout and asset bundles

Hello,

We are currently working on a UWP version of our game and have ran into a problem.
We are getting the [quote]
A script behavior (probably someScript) has a different serialization layout when loading. (Read X bytes but expected Y bytes)
[/quote]

Some of our scripts have variables enclosed in #if UNITY_EDITOR condition. If such a script is attached to a prefab that is part of an asset bundle, then the above mentioned error will appear.

My guess is that when the asset bundles are being built, the UNITY_EDITOR token is valid, so the variables that are wrapped by the #if UNITY_EDITOR condition are also serialized. I’m not sure if this is a bug or a feature, but I would like to know how I can handle this case.

I can provide a small test project if required that demonstrates the problem.

You can work around this by repositioning the #if UNITY_EDITOR so that any serialized fields is still there on device.

This will cause the error.

public class SomeClass : Monobehaviour
{
#if UNITY_EDITOR
    public float SerializedField; // This field is missing on device and will cause an error

    public void EditorOnlyFunction() { }
#endif
}

This will remove the error.

public class SomeClass : Monobehaviour
{
    public float SerializedField; // Still gets serialized on device. Serialization is the same for device and editor. No error.

#if UNITY_EDITOR
    public void EditorOnlyFunction() { }
#endif
}

Thanks for your answer. I’ll try this solution.

This error keeps popping up but unfortunately it doesn’t say which script is the culprit: script unknown or not yet loaded.

Is there a way to get more information. Our game was initially made for XBOX one so we do have some #if UNITY_XBOXONE in our scripts that might cause this. Unfortunately those are not as easy to circumvent and I want to be sure before I start refactoring.

Hi,

another customer reported this issue to us two weeks ago. The fix is being worked on, but it is not trivial and will definitely not get backported to 5.3.

The reason this bug happens is that let’s say you have class like so:

class MyClass : MonoBehaviour
{
#if UNITY_EDITOR
   int myInt1 = 16;
#endif
   string myString2 = "Hello";
}

Then, for the editor, serialization data for this class would be:

0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x00

However, for the player, it actually should be this:

0x06, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x00

There is a bug in our asset bundle build pipeline that we look at the wrong fields, so we serialize wrong data. We look at the fields for when you run the game in the play mode, as opposed to the fields that would get built when you build the player.

At runtime, it will try to first read the string length, so it reads it as 16 and then it tries to read the string from the following 16 bytes. However, there aren’t actually that many bytes left. So we crash. The reason this doesn’t happen on other platforms is that the .NET scripting backend (which is the default on UWP) depends on data being correct, and does no validation whether it is deserializing the correct field.

Unfortunately, there is no easy way to find out the culprit without debugging when you crash. The best way to find them I can suggest would be to open scripts VS solution, press CTRL + SHIFT + F, then look for “#if UNITY_” in the whole solution and finally go through all the instances that it found and remove those (or add “|| ENABLE_DOTNET”) that guard serializable fields.

Thanks for your help Tautvydas!

I went and checked the code and removed all the #if UNITY_EDITOR guards around fields. The ones that I have left are inside or around methods. However I still get 2 errors. The first one is “The referenced script on this Behavior is missing” and the second one is the serialization layout but this time without the name of the affected script (script unknown or not yet loaded).

I’ve managed to track when the errors start to pop. Basically we have a splash screen scene, followed by a login scene.
Each scene has a manager singleton with Don’t Destroy on Load. Inside that singleton there is a reference to an asset inside one of the asset bundles.

The splash screen loads all the asset bundles and then switches to the login screen. The moment we switch to the login screen all the errors start to pop up.

I know that this is really specific to our project and the way our asset bundles are set up so if you need any more information let me know.

Could you copy paste the serialization error? Is it fatal (does it crash the app)?

Here are the errors I’m getting. And no, it’s not fatal, I can keep running and navigate the menus. It would even load the assets but because of the missing scripts the game won’t play as it should.

The weird thing for me is that the errors in which a prefab is mentioned don’t have any scripts that have #if UNITY_EDITOR guards.

2669293–188318–errors.txt (70.6 KB)

Any chance you have compiler errors when building your game? There was also a bug that the editor did not stop the build in some cases if compiling C# scripts failed, causing it them not to get serialized.

Could you show me the editor log of the session where you built the game?

I’m not getting any errors while building the UWP project (from inside the unity editor) or when launching the app (from the generated .sln). Here’s the editor log.

2670389–188437–editor.txt (193 KB)

Hmm, any chance you’re using “C# projects” checkbox when building? Could you try disabling it? Just shooting in the dark here, but I’m close to running out of ideas of what could cause this. We’d like a bug report on this so we could investigate.

I get the error in even with “C# projects” and “Development Build” disabled. I’ve tried with Debug, Release and Master but it’s not working. Unfortunately I’m not able to isolate and reproduce the problem in an empty project, so I’ll have to send the entire thing if that’s ok.

Sure, that’s perfectly fine. Post the bug number (not the link to the bug) when you submit it.

I’ve submitted the bug report, the number is 804163.

Thanks, we’ll take a look.

while we investigate the bug report: are you set on shipping on .NET scripting backend? A quick look seems like the issue is not present on IL2CPP. I’m not sure what are the constraints of your game, but it could be a viable alternative.

Thanks for the tip! We don’t have any plugins that require .NET Core 5 functionality so IL2CPP backend should be fine. I’ll try it on Monday and report back.

Hi,

I fixed the bug and it is en-route to a patch release. I can’t promise the exact date when it will reach it, but hopefully it will not take too long.

Wrong thread? :slight_smile:

Wrong thread indeed :stuck_out_tongue: Thanks for your help on the issue. For now I have removed the asset bundles as we were only using them to improve loading times on Xbox one, which won’t be needed for UWP.