Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Struggling with complex data

Discussion in 'Visual Scripting' started by Canley, Aug 19, 2022.

  1. Canley

    Canley

    Joined:
    Jun 17, 2022
    Posts:
    37
    Hey guys,
    I have a number of situations where I need to use more complex data and am struggling to find a way forward. For example, I'd like to allow app users to add records each with a category, name, location, and quantity.

    - I want to be able to save the data - I believe that means I shouldn't use structs and instead prefer classes.
    - I want to stick to using visual scripting as much as I can since my C# knowledge is limited. (I learnt C in the late 80s and haven't used it since.)
    - I want to avoid using any database backend like SQL etc

    I think I could use a number of dictionaries or lists with matching keys for each record field, but that seems very cumbersome. (IE key #0 corresponds to item zero on each of the category, name etc lists.)

    As an example record using custom classes I've tried copying this code from the unity manual & just changed the name of the class (https://docs.unity3d.com/Packages/com.unity.visualscripting@1.8/manual/vs-custom-types.html):
    ---
    using System;
    using UnityEngine;
    using Unity.VisualScripting;

    [Serializable, Inspectable]
    public class CustomClasses
    {
    [Inspectable]
    public string name;
    [Inspectable]
    public string type;
    [Inspectable]
    public string color;
    [Inspectable]
    public int level;
    }
    ---
    I had errors from that code that seem to have been resolved by adding MonoBehaviour inheritance. But I believe it's not supposed to need MonoBehaviour(?)

    To implement the script, I have:
    - attached it to an empty object, "AppManager"
    - added the class as a type in Project Settings
    - created a variable of type CustomClasses attached to another game object

    On the inspector for my AppManager object, the fields show up ok:

    Screenshot 2022-08-19 132042.png

    But now I'm stuck.

    I would like to create a dictionary or list of type CustomClasses.

    Starting with a simpler case, I made a test variable, and expected it to show the name, type, color, and level fields on the blackboard. But it just looks like the image below:
    Screenshot 2022-08-19 131730.png

    I can show nodes for each separate field in the visual scripting graph. That's 4 nodes to get or set a complete record though & I'd prefer a single node I can fill with each field at once if possible.

    Are classes even the best way to go here?

    Have spent quite some time watching youtube etc which has gotten me this far.

    Any advice or help would be amazing, thank you :)
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
    Load/Save steps:

    https://forum.unity.com/threads/save-system-questions.930366/#post-6087384

    An excellent discussion of loading/saving in Unity3D by Xarbrough:

    https://forum.unity.com/threads/save-system.1232301/#post-7872586

    When loading, you can never re-create a MonoBehaviour or ScriptableObject instance directly from JSON. The reason is they are hybrid C# and native engine objects, and when the JSON package calls
    new
    to make one, it cannot make the native engine portion of the object.

    Instead you must first create the MonoBehaviour using AddComponent<T>() on a GameObject instance, or use ScriptableObject.CreateInstance<T>() to make your SO, then use the appropriate JSON "populate object" call to fill in its public fields.

    If you want to use PlayerPrefs to save your game, it's always better to use a JSON-based wrapper such as this one I forked from a fellow named Brett M Johnson on github:

    https://gist.github.com/kurtdekker/7db0500da01c3eb2a7ac8040198ce7f6

    Do not use the binary formatter/serializer: it is insecure, it cannot be made secure, and it makes debugging very difficult, plus it actually will NOT prevent people from modifying your save data on their computers.

    https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide
     
    Canley likes this.
  3. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    2,049
    There's a lot to unpack here but here or some of my thoughts:

    1. Structs containing base types can be saved without effort. There is nothing inherent to structs that would disallow serializing the data they contain. What structs are not great for is tracking some data over the game's lifecycle since structs are value types - it's hard to change the data a struct contains after the struct is already created. So that's why a class is better since it's a reference type - tracking data in a custom class is much easier.
    2. You won't be able to display contents of a Monobehaviour in the Variables inspector. Use [Inspectable][Serializable] plain C# class or struct. Custom non-Monobehaviour classes can't be attached as GameObject components but that's the whole idea behind the linked example. It's entirely handled in the Variables window without extra components.
    3. Monobeviour inheritance does not fix any code errors for the code sample listed. It should work on its own. Post the errors here so we can see what's up.
     
    Canley likes this.
  4. Canley

    Canley

    Joined:
    Jun 17, 2022
    Posts:
    37
    Thanks heaps Kurt - I’ll have a read of all that stuff. Really appreciate your help & the time you’ve taken, that’s awesome :)
     
  5. Canley

    Canley

    Joined:
    Jun 17, 2022
    Posts:
    37
    Thanks very much PanthenEye. I’ll work through the stuff Kurt posted but I’ll post the errors too as it seems like I’m stumbling over some basics.

    Being new at this I am anxious to get the data structures right so I don’t stuff up users’ saved data with any updates I push out after launch.

    Thanks again :)
     
  6. Canley

    Canley

    Joined:
    Jun 17, 2022
    Posts:
    37
    Thanks again for the help here. Still working through - but thought I'd post this link in case anyone else has similar questions.

    Very clear example of saving and loading data including use of structs. I note he does use binaryformatter which, Kurt mentioned above, is insecure.

    Unity C# Saving and Loading Tutorial

    About to give this a try.
     
  7. Canley

    Canley

    Joined:
    Jun 17, 2022
    Posts:
    37