Unity 2018.2.0b7 / FlowCanvas 2.8 exception during deserialization

Forums General Discussion Unity 2018.2.0b7 / FlowCanvas 2.8 exception during deserialization

This topic contains 4 replies, has 2 voices, and was last updated by  Gavalakis 3 months, 3 weeks ago.

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #1832

    kalms
    Participant

    Hi,

    I recently tried upgrading our project to Unity 2018.2.0b7. The game runs correctly within the Editor, but I get a bunch of errors like the ones below when I attempt to build a stand-alone Win64 player. This prevents us from moving our game to Unity 2018.2.

    Example callstack:

    
    GetKeys is not allowed to be called during serialization, call it from OnEnable instead. Called from ScriptableObject 'Ability'.
    See "Script Serialization" page in the Unity Manual for further details.
    UnityEngine.AnimationCurve:get_keys()
    ParadoxNotion.Serialization.FullSerializer.Internal.DirectConverters.AnimationCurve_DirectConverter:DoDeserialize(Dictionary_2, AnimationCurve&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/Converters/Unity/AnimationCurve_DirectConverter.cs:27)
    ParadoxNotion.Serialization.FullSerializer.fsDirectConverter_1:TryDeserialize(fsData, Object&, Type) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsDirectConverter.cs:31)
    ParadoxNotion.Serialization.FullSerializer.fsSerializer:InternalDeserialize_5_Converter(Type, fsData, Type, Object&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsSerializer.cs:886)
    ParadoxNotion.Serialization.FullSerializer.fsSerializer:InternalDeserialize_4_Cycles(Type, fsData, Type, Object&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsSerializer.cs:878)
    ParadoxNotion.Serialization.FullSerializer.fsSerializer:InternalDeserialize_3_Inheritance(Type, fsData, Type, Object&, List_1&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsSerializer.cs:857)
    ParadoxNotion.Serialization.FullSerializer.fsSerializer:InternalDeserialize_1_CycleReference(Type, fsData, Type, Object&, List_1&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsSerializer.cs:743)
    ... snip a number of lines, all within fsSerializer.cs ...
    ParadoxNotion.Serialization.FullSerializer.fsSerializer:InternalDeserialize_4_Cycles(Type, fsData, Type, Object&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsSerializer.cs:878)
    ParadoxNotion.Serialization.FullSerializer.fsSerializer:InternalDeserialize_3_Inheritance(Type, fsData, Type, Object&, List_1&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsSerializer.cs:857)
    ParadoxNotion.Serialization.FullSerializer.fsSerializer:InternalDeserialize_1_CycleReference(Type, fsData, Type, Object&, List_1&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsSerializer.cs:743)
    ParadoxNotion.Serialization.FullSerializer.fsSerializer:TryDeserialize(fsData, Type, Type, Object&) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/Full Serializer/fsSerializer.cs:705)
    ParadoxNotion.Serialization.JSONSerializer:Deserialize(Type, String, List_1, Object) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/JSONSerializer.cs:102)
    ParadoxNotion.Serialization.JSONSerializer:Deserialize(String, List_1, GraphSerializationData) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/_Commons/Runtime/Serialization/JSONSerializer.cs:73)
    NodeCanvas.Framework.Graph:Deserialize(String, Boolean, List_1) (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/Runtime/Graphs/Graph.cs:116)
    NodeCanvas.Framework.Graph:Deserialize() (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/Runtime/Graphs/Graph.cs:80)
    NodeCanvas.Framework.Graph:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize() (at Assets/Plugins/ParadoxNotion/FlowCanvas/Framework/Runtime/Graphs/Graph.cs:42)
    

    The gist of this seems to be that AnimationCurve.GetKeys() (a Unity API method) is not allowed to be called from
    within ISerializationCallbackReceiver.OnAfterDeserialize().

    At least one – and probablly all – graphs which exhibit this problem contain a node which references an AnimationCurve like this:

    
    public class CreateVisualProjectileNode : FlowControlNode
    {
        private ValueInput<AnimationCurve> heightCurveInput;
        ...
    
        protected override void RegisterPorts()
        {
            heightCurveInput = AddValueInput<AnimationCurve>("Height Curve");
            ...
        }
    }
    

    Now I’m not 100% certain, but I suspect that this is the story: when Unity decides that it is time to deserialize, it will begin deserialization of a lot of things, across multiple threads. It will invoke OnAfterDeserialize() for each object right after deserialization has completed for that particular item. At that point in time you cannot be sure that all other items also have completed deserialization, and therefore the API remains in “serialization ongoing, do not disturb” mode even whileOnAfterDeserialize() is triggered for some objects. This causes potential problems for all the *_DirectConverter classes. Again, not 100% sure if this is the problem, and if so, if this is intended behaviour or a bug in Unity 2018.2.

    #1834

    Gavalakis
    Keymaster

    Hello,

    Thanks for letting me know. NodeCanvas indeed does use the OnAfterDeserialize to deserialize all things that need deserialization (graphs and blackboards more specifically).

    Unity has a bad habit of changing critical things like these. I also don’t know if Unity changing this was intentional or a bug, but to me it seems un-intentional, since keyframe[] should be possible to access like most other “normal” API can.

    I will try to find an alternative solution (probably with a reflection hack) to get this working, or maybe Unity changes/fix this in a later version.

    Is it possible for you to remain on your current Unity version? If not, let me know and I will take a look at this sooner for you.
    Thank you.

    #1835

    kalms
    Participant

    We are considering moving to 2018.x within the next few months. This is the only blocker that we know of. I can’t seem to find any good way to get more info on this on a timely manner from Unity themselves (looking at reference C# code, …)

    If you can find a workaround, that would be appreciated.

    #1838

    kalms
    Participant

    Good news: This has been reported, and fixed, in the latest 2018.2 beta.

    Original Unity Issue Tracker report here

    The 2018.2.0b8 patch notes includes the note, “Animation: Fixed use of AnimationCurve scripting API in threads. (1041793)”

    I have confirmed that we can build a player without errors with 2018.2.0b9.

    In other words: no action needed on your part!

    #1845

    Gavalakis
    Keymaster

    That’s awesome and thanks for the follow up!
    I knew it was going to be one of those Unity accidents 🙂

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.