I had posted this earlier in the general editor forum, but it was suggested I post it here instead. Original post follows
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, 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.
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.
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?
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.
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.
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.