Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

Serializable PackageInfo

Discussion in 'Package Manager' started by ShawnFeatherly, May 30, 2018.

  1. ShawnFeatherly

    ShawnFeatherly

    Joined:
    Feb 22, 2013
    Posts:
    32
    What's the right way to load package.json when working on creating a package? I want to do this so I can automatically update package.json's version number to match the version in PlayerSettings.bundleVersion/Application.version

    I was hoping to use
    var packageInfo = JsonUtility.FromJson<UnityEditor.PackageManager.PackageInfo>("Assets/CustomPackageName/package.json");
    , however this doesn't work because UnityEditor.PackageManager.PackageInfo has properties, properties can't be serialized.

    Is the correct approach, for now, to replicate the UnityEditor.PackageManager.PackageInfo class using fields instead of properties? This works great, but seems silly.
    Code (CSharp):
    1. public class PackageInfoSerializable {
    2.   public string packageId;
    3.   public string version;
    4. }
     
  2. maximeb_unity

    maximeb_unity

    Unity Technologies

    Joined:
    Mar 20, 2018
    Posts:
    144
    Hi @ShawnFeatherly,

    The
    PackageInfo
    class cannot be deserialized from a file using
    JsonUtility
    for various reasons:
    - it uses properties (as you discovered);
    - it contains non-(JsonUtility-)serializable data structures like
    Dictionary<K,V>
    ;
    - most importantly, it does not actually represent a
    package.json
    file (i.e., it contains properties that are actually not part of the file, and vice versa)

    For authoring purposes, using your own serializable class with
    JsonUtility
    may be a good simple approach, but it only works as long as your package does not have dependencies (remember,
    JsonUtility
    cannot (de)serialize
    Dictionary<K,V>
    ).

    We are working on the package authoring process, which will include programmatic ways to manipulate these files and proper inspector support. In the meantime, my suggestion to you would be to define your own class that actually mirrors the file properties, and use more a generic JSON solution such as Json.NET to read and write this file from your tooling code.
     
  3. ShawnFeatherly

    ShawnFeatherly

    Joined:
    Feb 22, 2013
    Posts:
    32
    @maximeb_unity thanks for the clarification! Now it makes sense why "unity" and "keywords" only showed up in package.json. I am curious why the contents of package.json are different than UnityEditor.PackageManager.PackageInfo.

    I'll stick to my simple class and JsonUtility for now. It's good to know I have Json.NET around in case dependencies are a good fit for the package.
     
  4. maximeb_unity

    maximeb_unity

    Unity Technologies

    Joined:
    Mar 20, 2018
    Posts:
    144
    Hi @ShawnFeatherly,

    The
    package.json
    file provides metadata strictly about that package on its own (that specific version), without considering external factors like what included it in the project, what other versions of the package exist, etc. It's one of the basic building blocks for the whole system.

    On the other hand, the class
    UnityEditor.PackageManager.PackageInfo
    contains information provided to Unity by the package manager. Some of this information is pulled from the
    package.json
    file, and some is synthesized from other information sources such as the package registry, the file system, or even other packages. In other words, it's a "logical" representation of the package that provides enough information for Unity to do something useful with it :)
     
  5. ShawnFeatherly

    ShawnFeatherly

    Joined:
    Feb 22, 2013
    Posts:
    32
    Ah, I've got a much better picture of how it works now. Thanks for that description.
    package.json
    is for the package to describe itself and
    UnityEditor.PackageManager.PackageInfo
    is an outside package being referenced from within a project.