How would you go creating a Unity Package which is dependent on something that is not an assembly?

Howdy folks, I have a question regarding creating Unity Packages & their dependencies.

Let’s say my Unity Package is dependent on some external class or library, but that class or library does not exist in a Unity Package of their own. How could I create a Unity Package which relies on it?

For example - the ironSource SDK for Unity is a Unity ‘plugin’, not a package. It exists in the project’s Assets directory and needs to stay there for its Editor scripts to work properly.

In a situation such as this, how would I create a Unity Package with code that relies on ironSource’s SDK? I wouldn’t be able to use their classes, because their namespace won’t exist in the context of my package’s assembly.
Unfortunately, because they don’t have an assembly definition like a normal Unity Package, I won’t be able to add it as a dependency via my assembly definition.

Has anyone managed to resolve an issue like this before? I’ve been stuck on this for ages so I would love so advice. Thanks in advance!

You can include it in your own package. That’s about the only way I can think of.

You should definitely raise it to the devs because not distributing such plugins as a package is a disservice to Unity users. There may be technical reasons preventing them from doing this, but I guess the real reason in such cases is mainly that they don’t want to spend the time.

No there are generally technical reasons behind this. The main one is that packages can not mutate their own files, while many packages require the ability to do so.

Odin Inspector is the same, it’s just a regular ‘plugin’ and not a package because of this reason. You can make it package, but 99% of the time it won’t work properly.

Even my own internal packages I have all have to work around this. Pretty much every one uses a SettingsProvider to get around this.

I’d say a package that NEEDS to mutate some of its own files is badly designed.

If the package needs settings, you can store them as an asset inside the project (I remember Odin used to do that) but it’s better to just save it to JSON under AppData.

If the package needs to generate code or assets, these should be generated under /Assets and ideally excluded from source control.

Are there any other reasons for a package to modify its own files? Can’t think of any at the moment. Nor are there any packages currently in the registry that have issues of this kind.

I wager Odin is a plugin (DLL) simply because it allows them to keep the code stable and not subject to whichever Unity version and Burst compiler is installed, that could generate weird bugs simply because they cannot possibly compile their code with every possible combination of compilers a user may have installed. Beside the fact that users themselves may make modifications to the sources that, in a project this large, can also cause weird issues that are hard to track down for both users and developers.

On top, distribution via DLL enables them to encrypt/obfuscate the compiled DLL. I don’t know if they do that, but given the complexity of the tool this is certainly a possibility that they want better protection of their codebase.

Thanks for the feedback @spiney199 @CodeSmile , I appreciate it :slight_smile:
It seems the tl;dr is that sometimes code is distributed as plugins and not packages for technical reasons (or sometimes lack of refactoring), and there is little to do about it if you want to depend on it via package other than try and turn it into a package yourself.

On a different note - this is the first I’ve heard of the SettingsProvider class - it seems pretty cool. I presume that while it can be utilized as part of a package, the settings it generates will be within the Assets directory. Did I understand correctly, or is this class purely plugin exclusive?

You can implement it however you want. My pattern is just to have it generate a singleton scriptable object you can put anywhere, putting it into your pre-loaded assets as the same time (scriptable objects in preloaded assets get their OnEnable method called, so it’s good for initialising singletons). Once the SO is generated, it just makes a UnityEngine.UIElements.InspectorElement and draws the SO that it looks up via AssetDatabase.

I really only use it for very low-level configuration settings.