Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411475 Posts in 69369 Topics- by 58424 Members - Latest Member: FlyingFreeStudios

April 23, 2024, 02:16:32 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Trouble saving byte arrays to disk in Editor
Pages: [1]
Print
Author Topic: Trouble saving byte arrays to disk in Editor  (Read 787 times)
damagefilter
Level 0
**



View Profile WWW
« on: January 12, 2017, 12:35:01 AM »

Hello there. This is a long standing issue of mine and I thought I might aswell try it here. Perhaps someone miraculously has an answer for it. I'm kid of desperate about that whole thing. Crazy

So here's the situation:
I have a byte array that belongs to scene data. It's part of a MonoBehaviour which implements ISerializationCallback.
And, unless I force-save the whole scene (via SceneManager in editor), that byte data is just thrown away by Unity
the moment I close the editor. Even the normal save option (ctrl+s) doesn't do the trick.
It's like Unity insists on me manually saving the scene as described above.
I'm at a complete loss here.
Perhaps it's just something incredibly simple and stupid but I can't see it. I'm currently on Unity 5.4.2f2

So here's a bit of code (below that a link to the full source because it's open source, why not)

Firstly, the MB that has saved data which gets ignored (stripped for brevity)

Code:
public class SequenceExecutor : MonoBehaviour, ISerializationCallbackReceiver {
    [SerializeField]
    [SaveableField(SaveField.FIELD_PROTOBUF_OBJECT)]
    private List<ValueField> globalDataContext;

    [SerializeField]
    [HideInInspector]
    private byte[] serializedModelTree;

    [SaveableField(SaveField.FIELD_PROTOBUF_OBJECT)]
    private UnityBtModel rootModel;

    public UnityBtModel RootModel {
        get {
            return rootModel;
        }
    }

    public void OnAfterDeserialize() {
        using (var ms = new MemoryStream(serializedModelTree)) {
            ms.Position = 0;
            this.rootModel = DataSerializer.DeserializeProtoObject<UnityBtModel>(ms.ToArray());
        }
    }

    public void OnBeforeSerialize() {
        this.serializedModelTree = DataSerializer.SerializeProtoObject(this.rootModel);
    }
}
(Code: https://github.com/damagefilter/PlayblackCore/blob/master/Game/Sequencer/SequenceExecutor.cs)
The reason I'm doing it this way is that Unity stops serializing when the tree structure gets too deep. It stops at 7 recursions. That's rather useless for my use case so I used ProtoBuf to turn this into saveable, Unity-friendly data.

Anyway. Changes to the serializedModelTree object are basically ignored entirely until I force-save the scene.
I double checked that Unity actually calls the serializer callbacks.
It does. Very... very frequently. (Strikes me as odd but if that is how they roll, so be it)

This is how the entry point of the whole editor script part looks like:
Code:
[CustomEditor(typeof(SequenceExecutor))]
public class SequencerInspector : UnityEditor.Editor {

    public override void OnInspectorGUI() {
        if (target == null) {
            return;
        }
        base.OnInspectorGUI();
        SequenceExecutor sequencer = target as SequenceExecutor;
        if (GUILayout.Button("Open Sequencer Settings")) {
            var window = GenericPopupWindow.Popup<SequencerEditorWindow>();
            window.SetData(sequencer);
        }
    }
}
(Code: https://github.com/damagefilter/PlayblackCore/blob/master/Editor/Sequencer/SequencerInspector.cs)
And the Sequencer Editor Window (stripped, of course:
Code:
public class SequencerEditorWindow : GenericPopupWindow {
    private BtSequencerRenderer sequencerWindow;

    private SequenceExecutor subject;

    private void DrawSequenceSettings() {
        EditorGUILayout.BeginVertical();
        {
            subject.TypeOfExecution = (ExecutionType)EditorGUILayout.EnumPopup("Execution Mode", subject.TypeOfExecution);
        }
        EditorGUILayout.EndVertical();
    }

    public void OnGUI() {
        EditorGUILayout.BeginHorizontal();
        {
            if (sequencerWindow != null) {
                this.DrawSequenceSettings();
                EditorGUILayout.BeginVertical();
                {
                    sequencerWindow.DoRenderLoop();
                }
                EditorGUILayout.EndVertical();
            }
            else {
                EditorGUILayout.HelpBox("Nothing selected", MessageType.Info);
            }
        }
        EditorGUILayout.EndHorizontal();
        Repaint();
    }
}
(Code: https://github.com/damagefilter/PlayblackCore/blob/master/Editor/Sequencer/SequencerEditorWindow.cs)

At some point in code I manually save the whole scene when data in that model tree is changed.
If it's relevant for you, it's here:
https://github.com/damagefilter/PlayblackCore/blob/master/Editor/Sequencer/OperatorEditorWindow.cs#L42

Recapping:
I have this tree of data which is a actually Behaviour Tree where each behaviour can have its own properties and you can edit them.
When editing this data Unity SHOULD see that the byte array, once serialized, has changed, and mark it for storing on disk.
That, however, does not happen.
In order to make it happen I have to use SceneManager and manually force-save the scene.

What I tried to trick Unity into recognising that the byte data has changed:
  • Passing down the SerializedObject to OperatorEditor and mark it dirty
  • Marking the serialized property dirty
  • Mark the GameObject dirty
  • Change a Unity-native property ("enabled" for instance) to trick Unity into saving the gameObject again

Nothing of this worked, except the above mentioned scene-saving method...

I'm sorry if that all seems a bit jumbled up, I'm having a hard time to explain myself :S
If you feel like asking more questions, please do.

Does anyone have a clue, a hint, anything really, why that would happen?
Logged

Logic is an amazing thing ...
for people that have it.

-Sir Munkleton
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic