Optional package dependencis?

I had posted this earlier in the general editor forum, but it was suggested I post it here instead. Original post follows :slight_smile:

How can I set up something so that one package depends on and uses another package but only if that other package is present. In other words that second package is optional and extends functionality if present. If it is not present, the first package can still run without it.

The “old” way I could do this using #define conditionals, but with packages it seems more complicated because you have to define the dependencies

Hi @jwvanderbeck ,

Please take a look at the Version defines section of https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html. I think it should do what you want. You do not need to define a dependency in the package.json, otherwise the dependency will not be optional (as you have probably guessed).

1 Like

Hi, thanks for the reply. I did read that section but to be honest it didn’t completely make sense to me. Maybe I need to revisit it and just play with it in the editor to see what happens.

The idea is that the asmdefs in your own package can list defines that are enabled automatically when the specified package is present and it’s version matches the version range you specify. This gives you control over the define name, and avoids clashes with the same names in other packages, all the while requiring no interaction on the part of the other package developer.

That sounds about what we want. I’ll play around with it once I get back from Siggraph. Thank you for the insight!

1 Like

Ok so I’m back and taking a look at this now, but running into an immediate problem in that the Version Defines section isn’t even showing up in my asmdef’s inspector. I’m pretty sure I saw it there before so I’m not sure why it is gone now. Does it only show up under certain preconditions or only in certain Unity versions? I’m working in a couple different versions of the editor including 2018.3 and 2019.2.

As far as I know, this is a 2019.2+ feature. There’s nothing specific that needs to be done to make it show up.

Hi, wanted to loop back to this. I finally got a chance to work with this in Unity 2019.3 and it isn’t quite working as expected.

I setup a define to look for com.unity.mathematics and that define does properly propagate into my package, so its set when Mathematics is present, and unset when it isn’t. So far so good.

However, when it is set, the actual assembly, com.unity.mathematics doesn’t get added as a dependency so I can’t actually access it. I can manually set it as a dependency, but then that defeats the purpose.

I am not 100% sure if I got your problem right, but that option enables optional defines so that the compiler can compile different portion of code depending if the assembly is present or not. It seems that you instead want dependencies to be downloaded optionally depending if an assembly is already present or not, but I may be wrong.

What I am trying to do is make code in a package OPTIONALLY use another package IF that package is installed rather than REQUIRING that other package.

In other words, if Unity.Mathematics is installed, my package will expose methods that work with float2, if not it will fall back to methods that use Vector2.

Ah ok then from what I remember that option is what you are looking for. In your assembly you enable the define uf unity.mathematics is present. I think when I did my test months ago was actually for the same precise reason (optionally enable unity math if present) and it worked. If you can’t figure it out I’ll dig the example when I have time .

Well the conditional works just fine, but the problem is the package dependency. Unity essentially doesn’t make the Mathematics assembly even visible to my package unless I add it as a dependency. At which point, isn’t it now required rather than optional?

Hmm yes what you say makes sense , I’ll do some tests to remember what I did

Would be most appreciated! Thanks :slight_smile:

OK now I remember, that option is only to have different behaviours according the version of the package, but the package must be included. It’s a shame, I see how it could be used like you say.

Tagging @HaraldNielsen and @karl_jones who replied to me the first time on a similar question.

Hmm. Based on what @maximeb_unity said originally, it should be doing what we are wanting.

well it’s true that in my original post they were saying the same thing. I am not sure anymore :slight_smile:

After reading that thread as well, I think I understand what is happening. Sort of. Some clarification would be nice.

But what I think is happening here is you can declare that Package A has a Reference to Package B. If Package B is installed, great it can be used. If Package B is NOT installed, then the system will still try to compile Package A anyway and as long as it doesn’t use code from Package B it should compile fine with no errors.

This is where the Version Defines would work.

However, the one piece I would like clarification on, is what is the difference from “Reference” and “Dependency” as far as asmdefs go. So the above system sounds like exactly what we are after. If a “referenced” package is installed, we can use it, just as long as we handle when it isn’t installed. A “soft” dependency. But a “hard” dependency would be we MUST have this package, and I don’t see where that is defined by the system. A large part of a package manager of course is managing those dependencies so if I install one package it also installs all the others that it NEEDS to have.

Going to do a big more digging.

1 Like

Ahh nevermind I see it now. Makes perfect sense.

What confused me was that I was focused in on the assembly definition and forgetting the package.json all together.

Ok so in summary this is how it works. You have two things that factor in. The overall package’s “package.json” file, and the Assembly Definition (asmdef file) for each assembly in your package.

In the package.json is where top level information about package is contained along with hard dependencies. If MyPackage must have Mathematics installed to work, then it would be defined as a dependency here in the package.json

In the Assembly Definition for a given assembly (eg runtime, or editor) is where you define what other assemblies your assembly references. These are soft references, in that if the reference is not found, Unity will still try to compile the assembly anyway. This is where you can also set up preprocessor defines to be set if an assembly reference is installed. This allows you to wrap the relevant code so that if the reference is not installed, it will still compile.

5 Likes

I see, so one should add the soft dependency anyway, regardless if is installed or not, so that the check can be done. Yes it makes sense.