BUG (critical): ActionListPlayer deserialization

Forums 💬 NodeCanvas ⚙️ Support BUG (critical): ActionListPlayer deserialization

Viewing 15 posts - 1 through 15 (of 15 total)
  • Author
    Posts
  • #18263
    bcristian
    Participant

      an ActionListPlayer referencing a global BB will crash on deserialization, because it tries to resolve the global BB reference from the deserialization callback.
      Repo is simple – create a scene with a global BB and an ActionListPlayer with an action referring it, e.g. “set integer” with an integer from the global BB. Save, close, reload.
      Help fixing this would be greatly appreciated, as the systems involved are quite complex (been sifting through the code for a couple of hours) and would likely take me a lot of time to figure it all out.
      Thanks

      #18277
      Gavalakis
      Keymaster

        Hey,

        My bad sorry. That’s indeed an issue.
        I have attached for you here a fixed version of ActionListPlayer.cs in a package.

        Let me know if everything works correctly on your end as well.
        Thanks!

        #18276
        bcristian
        Participant

          It’s working, thanks.

          #18275
          bcristian
          Participant

            Actually, there is still an issue, but it seems non-critical: in play mode, the first time the action that references the global variable plays the following pair of warnings:

            Dynamic Parameter Variable ‘Global/myInteger’ Encountered…
            Blackboard: Variable with name ‘myInteger’ already exists in blackboard ‘Global’. Returning existing instead of new.

            #18274
            bcristian
            Participant

              Hello
              You left the SendTaskOwnerDefaults call in OnValidate in the new version, which brings back the initial issue.
              However, simply commenting it out leads to the missing task owner error.
              I’ve added the [ExecuteInEditMode] attribute to the script, which causes Awake to be called, which in turn calls SendTaskOwnerDefaults.
              Ran a few tests, seems to be working.
              Could you please confirm if this is a proper fix?

              #18273
              Gavalakis
              Keymaster

                Hello again,

                I don’t really get any issues with the SendTaskOwnerDefaults being in OnValidate like this:

                What problem are you getting?
                Regardless, using [ExecuteInEditMode] to make Awake run in editor and thus SendTaskOwnerDefaults is also correct, yes.

                Regarding the issue about Dynamic Variable encountered, I’ve attached for you here an improvement to the GlobalBlackboards.cs script which fixes this issue.

                Let me know.
                Thanks.

                #18272
                bcristian
                Participant

                  The repo is the same from the first post. The error only shows after loading the scene, not the first time creating the action list player and the global BB.

                  OnValidate() is also called during deserialization, and SendTaskOwnerDefaults cannot work at that time, as not even accessing the gameObject from the component is allowed at that time. Unfortunately, there is no way (at least that I could find) to determine if the currently executing code is during deserialization or not.

                  Using Unity 5.5, forgot to mention.

                  #18271
                  Gavalakis
                  Keymaster

                    Hello again,

                    That is very weird. I am also on Unity 5.5 and tested exactly what you said. Having a task that references a global bb variable, saved the scene, closed unity, reopened it and loaded the scene. I get no errors at all.
                    OnValidate() is not really called during serialization as far as I know, otherwise there would be much more problems that this one in all of my projects 🙂

                    I’m sorry, but I really can’t reproduce the error you have here :/

                    #18270
                    bcristian
                    Participant

                      Oops, I’ve made a mistake when merging your new version with the old one modified by me, the new one doesn’t have the OnValidate, it calls SendTaskOwnerDefaults directly from OnAfterDeserialize.
                      The end result is the same though, as it still uses API’s not usable at that time.

                      But it gets even weirder.

                      All of the following happens in a new project, only NodeCanvas imported (none of my changes), Unity 5.5.0f3.

                      https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnValidate.html
                      This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).

                      New scene, new empty GO, add the script, save, new scene, open the previously saved scene.
                      On my machine, it prints out “OnValidate” every time. Does the same happen on your side?

                      New scene, new global BB and new ActionListPlayer. Add an integer to the BB, and an action to increment said integer in the ALP.
                      Save, new scene, open the previously saved scene.

                      And now the weird part.
                      If Android is set as the build target, I get these 2 errors:
                      FindObjectsOfType is not allowed to be called during serialization, call it from Awake or Start instead. Called from MonoBehaviour ‘ActionListPlayer’ on game object ‘ActionList’.
                      See “Script Serialization” page in the Unity Manual for further details.
                      UnityEngine.Object:FindObjectsOfType()
                      NodeCanvas.Framework.GlobalBlackboard:Find(String) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/GlobalBlackboard.cs:42)
                      NodeCanvas.Framework.BBParameter:ResolveReference(IBlackboard, Boolean) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:270)
                      NodeCanvas.Framework.BBParameter:set_bb(IBlackboard) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:175)
                      NodeCanvas.Framework.BBParameter:SetBBFields(Object, IBlackboard) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:54)
                      NodeCanvas.Framework.Task:set_blackboard(IBlackboard) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Tasks/Task.cs:331)
                      NodeCanvas.Framework.Task:SetOwnerSystem(ITaskSystem) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Tasks/Task.cs:169)
                      NodeCanvas.ActionListPlayer:SendTaskOwnerDefaults() (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:71)
                      NodeCanvas.ActionListPlayer:set_actionList(ActionList) (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:38)
                      NodeCanvas.ActionListPlayer:OnAfterDeserialize() (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:28)

                      UnityException: FindObjectsOfType is not allowed to be called during serialization, call it from Awake or Start instead. Called from MonoBehaviour ‘ActionListPlayer’ on game object ‘ActionList’.
                      See “Script Serialization” page in the Unity Manual for further details.
                      UnityEngine.Object.FindObjectsOfType[GlobalBlackboard] () (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:227)
                      NodeCanvas.Framework.GlobalBlackboard.Find (System.String name) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/GlobalBlackboard.cs:42)
                      NodeCanvas.Framework.BBParameter.ResolveReference (IBlackboard targetBlackboard, Boolean useID) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:270)
                      NodeCanvas.Framework.BBParameter.set_bb (IBlackboard value) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:175)
                      NodeCanvas.Framework.BBParameter.SetBBFields (System.Object o, IBlackboard bb) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:54)
                      NodeCanvas.Framework.Task.set_blackboard (IBlackboard value) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Tasks/Task.cs:331)
                      NodeCanvas.Framework.Task.SetOwnerSystem (ITaskSystem newOwnerSystem) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Tasks/Task.cs:169)
                      NodeCanvas.ActionListPlayer.SendTaskOwnerDefaults () (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:71)
                      NodeCanvas.ActionListPlayer.set_actionList (NodeCanvas.Framework.ActionList value) (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:38)
                      NodeCanvas.ActionListPlayer.OnAfterDeserialize () (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:28)

                      switch platform to PC, Mac & Linux Standalone, and now the errors when opening the scene change to:
                      get_isPlaying is not allowed to be called during serialization, call it from Awake or Start instead. Called from MonoBehaviour ‘ActionListPlayer’ on game object ‘ActionList’.
                      See “Script Serialization” page in the Unity Manual for further details.
                      UnityEngine.Application:get_isPlaying()
                      NodeCanvas.Framework.BBParameter:set_bb(IBlackboard) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:162)
                      NodeCanvas.Framework.BBParameter:SetBBFields(Object, IBlackboard) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:54)
                      NodeCanvas.Framework.Task:set_blackboard(IBlackboard) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Tasks/Task.cs:331)
                      NodeCanvas.Framework.Task:SetOwnerSystem(ITaskSystem) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Tasks/Task.cs:169)
                      NodeCanvas.ActionListPlayer:SendTaskOwnerDefaults() (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:71)
                      NodeCanvas.ActionListPlayer:set_actionList(ActionList) (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:38)
                      NodeCanvas.ActionListPlayer:OnAfterDeserialize() (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:28)

                      UnityException: get_isPlaying is not allowed to be called during serialization, call it from Awake or Start instead. Called from MonoBehaviour ‘ActionListPlayer’ on game object ‘ActionList’.
                      See “Script Serialization” page in the Unity Manual for further details.
                      NodeCanvas.Framework.BBParameter.set_bb (IBlackboard value) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:162)
                      NodeCanvas.Framework.BBParameter.SetBBFields (System.Object o, IBlackboard bb) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/BBParameter.cs:54)
                      NodeCanvas.Framework.Task.set_blackboard (IBlackboard value) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Tasks/Task.cs:331)
                      NodeCanvas.Framework.Task.SetOwnerSystem (ITaskSystem newOwnerSystem) (at Assets/ParadoxNotion/NodeCanvas/Framework/Runtime/Tasks/Task.cs:169)
                      NodeCanvas.ActionListPlayer.SendTaskOwnerDefaults () (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:71)
                      NodeCanvas.ActionListPlayer.set_actionList (NodeCanvas.Framework.ActionList value) (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:38)
                      NodeCanvas.ActionListPlayer.OnAfterDeserialize () (at Assets/ParadoxNotion/NodeCanvas/Modules/ActionListPlayer/ActionListPlayer.cs:28)

                      Copied your new version and made it ExecuteInEditMode, moving the SendTaskOwnerDefaults to Awake (if _actionList not null) and deserializing into _actionList seems to make it work.

                      #18269
                      Gavalakis
                      Keymaster

                        So, I am completely lost now as of which version of ActionListPlayer.cs and GlobalBlackboard.cs you have in the end 🙂
                        I am attaching the local modified versions I have for both here just to confirm.
                        These two work fine for me here. Can you confirm the same?

                        Thanks.

                        #18268
                        bcristian
                        Participant

                          [quote quote=11651]All of the following happens in a new project, only NodeCanvas imported (none of my changes), Unity 5.5.0f3.[/quote]

                          Could you also test the OnValidate thing?

                          #18267
                          Gavalakis
                          Keymaster

                            Hey,
                            OnValidate is called every time a scene is loaded (once), yes. Is that what you mean to test? 🙂

                            #18266
                            bcristian
                            Participant

                              Yes, that – since you said “OnValidate() is not really called during serialization as far as I know”.

                              Other than that, have you had the time to look at the error?
                              The following is my current modified version (based on 2.6.2), and it seems to work.

                              #18265
                              Gavalakis
                              Keymaster

                                Hey,

                                I am using Unity 5.5 and I still don’t get any errors at all by using SendTaskOwnerDefaults() in OnValidate. The problem with doing this in Awake with ExecuteInEditMode as you do above, is that Awake will not be called after a re-compile and as such this will result in “Owner System Is Null” for the action list. OnValidate though is called after a re-compile.

                                #18264
                                bcristian
                                Participant

                                  Yeah, I’ve noticed that null owner system too.
                                  My current version. Seems to be working now. No idea why, probably stuff from the new version got mixed up with the old one 😀

                                Viewing 15 posts - 1 through 15 (of 15 total)
                                • You must be logged in to reply to this topic.