Search Unity

Package Manager and backwards compatibility

Discussion in 'Package Manager' started by fherbst, Nov 25, 2019.

  1. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    411
    So, we're heavily using our own packages (with our own registry etc) in our workflow.
    Some of those are used over quite a range of Unity versions. In fact, right now I'm trying to extend support "backwards" in Unity versions, e.g. some packages currently support 2019.1+ and I want them to support 2018.1+.

    This has lead to a number of questions:
    1. asmdefs default to "Use GUIDs" but that is not available e.g. on 2018.1. What's the advantage of using it? What's the downside to disabling it?
    2. some Unity packages (com.unity.timeline; com.unity.ui; com.unity.ugui) are not available in earlier versions. What's the right way to support both "old" and "new" Unity versions with the same package version? How do I specify those dependencies in a backwards-compatible way?
    3. some Unity packages use C#7 features but < 2018.3 does not support that (com.unity.mathematics). No idea how to handle that, as mathematics actually pretends to be working on 2018.1.
    4. Mesh.Optimize ist obsolete in 2018.3, but came back later (?), definitely alive and kicking in 2019.2; is there a list of such things or will I have to just find that on a case-by-case basis?
    Another fun thing: I can't find a version of Package Manager UI that works on 2018.3.14f1. 1.2.0 has no asmdef files (which are required for that Unity version in Packages) while 1.3.0 seems to use types only available in 2018.4. Most versions that I can find in the Changelog seem to have been unpublished already.
    EDIT: found a version that works by creating an entirely new project on 2018.3.14f1. It's the much newer 2.0.7.
     
    Last edited: Nov 26, 2019
  2. cassandraL

    cassandraL

    Unity Technologies

    Joined:
    Dec 7, 2017
    Posts:
    108
    Hello @fherbst ,
    First, let me advise that Unity is not supporting 2018.1 anymore, but we still support 2018.4.
    Also, please be aware that many features to help package usage has been added in 2018.4 and even more in the 2019 cycle and that trying to be backwards up to 2018.1 is not an easy task.

    Having said that, here are some answers to your questions.

    1. The advantage of using GUIDs over package name is to avoid losing links between asmdefs when said assembly changes name. This can be useful is some cases and not in others.

    2. Those packages are usually included in the build already, so adding them as a dependency will usually break. To deal with this, we would usually create a version of our package and set the minimum version of the editor supported.
    So it would look like this:
    package@1.0.0 -> targets 2018.4+, no dependency
    package@2.0.0 -> targets 2019.2+, depends on com.unity.timeline

    3. Unlike dependencies, you can handle code differently per editor version using Version Defines. The editor comes with built-in version defines since 2019.1. You can also setup your own version defines (See Version Defines here: https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html)
    More specifically, you can surround your code with preprocessors to run differently based on the version of the editor.
    Here is an example:
    Code (CSharp):
    1. #if UNITY_2019_2_OR_NEWER
    2.         var myVar = myNewFunctionThatExistsOnlyIn2019_2();
    3. #else
    4.         var myVar = myOldFunction();
    5. #endif
    If you setup your own assemblies' version defines, then you can also run your own code based on a version of your dependency.
    So if your package@1.0.0 depends on com.unity.timeline@1.0.0 and then your package@2.0.0 depends on com.unity.timeline@2.0.0, then you could create a version define based on com.unity.timeline to distinguish between version 1.0.0 and 2.0.0. For example: TIMELINE_NEWER_THAN_2. Then, you could surround your code with it:
    Code (CSharp):
    1. #if TIMELINE_NEWER_THAN_2
    2.         var myVar = timelineFunctionThatExistsIn2_0_0();
    3. #else
    4.         var myVar = timelineFunctionThatExistsIn1_0_0();
    5. #endif
    This can be useful because while your package has a direct dependency on timeline and specifies a version, that version might not be the one resolved in the project, since the user can overwrite timeline's dependency. That way, your code stays backward compatible.

    4. I am sorry to say that you will most likely have to find and deal with each of these on a case-by-case basis. The best you can do is see the Unity manual (https://docs.unity3d.com/Manual) as well as each package's documentation (https://docs.unity3d.com/Manual/pack-alpha.html) to follow on those.

    Sorry for a long post, but I hope this helps you in your quest!