Search Unity

PersistentData

Discussion in 'UI Toolkit' started by Devi-User, Oct 24, 2018.

  1. Devi-User

    Devi-User

    Joined:
    Apr 30, 2016
    Posts:
    61
    In the VisualElement class, I found things like persistentKey and GetOrCreatePersistentData <T> (), OnPersistentDataReady (), SavePersistentData (), GetFullHierarchPersistenceKey ()
    I would like to get a little more information about how this works.
    My questions are as follows:
    - How does SavePersistentData () understand what needs to be saved?
    What kind of things does it save? Does this include ScriptableObject, Serializable, or primitives? Does encapsulation affect (data must be public)? How close is it to the rules for storing objects in MonoBehaviour?
    What key is used to save - persistentKey or GetFullHierarchicalPersistenceKey ()?
    - How does GetOrCreatePersistentData <T> () understand exactly what we are going to get? Does it depend on the type? From GetHashCode ()?
    - Where is the data file stored?

    Are there any other methods and fields that I need to know about in order to use it?
     
    Last edited: Oct 24, 2018
  2. Devi-User

    Devi-User

    Joined:
    Apr 30, 2016
    Posts:
    61
    I found out that GetOrCreatePersistentData returns a value by type. Because of this, I have an even greater misunderstanding of how data is stored. Especially enters the discord in a situation where there are two objects of the same type.
    Does it store only 1 object of each type? How does it choose what to store?

    Also, I saw that GraphView uses private fields for storage, which are not marked with an attribute, which goes against what is said in the documentation.
     
  3. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    This API lets you save view data only information so it can persist across editor sessions and domain reloads (like going into playmode). Primary uses case are things like scroll position in a window, or tree view items expanded states. This is not meant for persisting settings or anything that should be part of version control.

    Right now, only ListView and ScrollView support having their persistenceKey set. If set, their scroll position will survive domain reloads.

    The other related APIs are for actually setting up this persistence support on your own custom VisualElements. That said, these APIs will not be available in the final release as we rethink this feature to be easier to use.
     
  4. AndrewKaninchen

    AndrewKaninchen

    Joined:
    Oct 30, 2016
    Posts:
    149
    What is the recomended way to store data about things like Nodes' positions, which are relevant in the editor but not ingame?
     
  5. Devi-User

    Devi-User

    Joined:
    Apr 30, 2016
    Posts:
    61
    This is exactly what I'm trying to use it.
    I think it makes no sense to keep this data separate from the nodes and you can just enclose it inside UNITY_EDITOR. We can use the internal level of visibility, and then let the editor assembly see this internal. This is the best solution I have found. Otherwise, constant synchronization between the game and editor entities is required, which in my opinion will cause problems in a huge number of cases. Another circumstance is that it still remains important information that needs to be under version control.

    So you create two asmdef files for the editor and for the runtime. You link runtime for editor assembly. And create AssemblyInfo.cs in runtime assembly:
    Code (CSharp):
    1. using System.Runtime.CompilerServices;
    2.  
    3. [assembly: InternalsVisibleTo("MyModule.Editor")]
    4. [assembly: InternalsVisibleTo("MyModule.Editor.dll")]
    And use in runtime:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. [SerializeField]
    3. internal int myEditorField;
    4. #endif
    it is important to understand the difference between the individual information of the editor, which is important only for a specific user (zoom, scroll) and public (node position e t.c.)
     
  6. Devi-User

    Devi-User

    Joined:
    Apr 30, 2016
    Posts:
    61
    Do you already have any suggestions on this? I ask about this, because there is also another topic that concerns such data. The fact is that some of them should be able to be used with Undo / Redo. For example, if we are talking about a list of selections, it becomes relevant. We may want to use Undo / Redo for such things. Will the rethinking include addressing this issue, or should such things be done independently?
     
  7. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    All current internal implementations of GraphView store the node position as part of the model, which in most cases is just a collection of ScriptableObjects. This means node positions can be undone/redone and will be part of version control. You actually want this for any graph because you want the node layout to survive from user to user.

    [Edit] If you want your model (ScriptableObjects) to be part of your runtime, but have extra Editor-only saved state separately, you should create 2 sets of ScritpableObjects (one Runtime, one Editor) and have each node in your graph reference both.
     
    Last edited: Oct 31, 2018
    AndrewKaninchen likes this.
  8. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    @uDamian are you saying there are no gotchas with having conditional serialized fields anymore? because in older versions, Unity would error when building because different serialization layout between platforms (tried on my own skin multiple times :( )
     
  9. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    @M_R You're right. Conditionally compiled fields in a SerializedObject is not the ideal solution. I changed my answer above. My recommendation now is:

    Thanks for the reminder!
     
    M_R likes this.