Check if devs has assets

I am currently thinking about a problem of how to check if user has installed one or another asset into its project. Lets say I want to check if developer, who is using my asset has also installed Aaron Granberg A* Pathfinding system. If yes, then I want to calculate paths by using A*, otherwise use Unity’s built in NavMesh. I noticed that there are some hints about creating conditional compilation flags, like
#if ISASTAR
// calculate paths using A*
#else
// calculate paths via built-in NavMesh
#endif

Things would look nice that way, but the missing piece is of how to chase automatically when to define ISASTAR, without forcing developers to comment/uncomment parts of code, where #define ISASTAR and #undef ISASTAR statements are written?

It doesn’t have to be on a runtime - I can put a button in the editor inspector for such checks. One of my thoughts would be to write somehow #define and #undef into a separate .cs file, then to re-compile everything and set up other things afterward. Did anybody tried this?

I thought it could be quite important problem, as there are many assets on Asset Store and when we write new assets, it could be great to check if developers are using one or another asset or not…

Your code should ship with all of the conditional defines in place. The developer won’t have to comment/uncomment anything.

In your editor script, add global custom defines as described at the bottom of the Platform Dependent Compilation page. For example, if the developer ticks a “Support A* Pathfinding” checkbox, you can add ISASTAR to the global defines.

While you could always do an automatic search for A* Pathfinding, it’s probably better to let the developer specify whether to compile your product with support or not. First, the developer may want to use built-in NavMesh paths even though A* is in the project. Second, if the developer moved the A* Pathfinding installation folder, your search might not find it, or it might incorrectly identify something else as A*.

Does the bottom of the page means “Global Custom Defines” section? If so, would it work to simply overwriting smcs.rsp file and calling AssetDatabase.Refresh(), and executing everything else afterwards?

You can actually use BuildTargetGroup. For example, to add a define “ISASTAR” to the Standalone build settings:

using UnityEditor;
...
if (!PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone).Contains("ISASTAR")) {
    PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, "ISASTAR;" +
        UnityEditor.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone));
}

The code above is kind of sloppy and I didn’t test it for typos, but it should get you started at least.

Seems to be working, but it looks like there is needed also to use EditorApplication.isCompiling in the editor script to trace when compilation is complete. By default after 3rd line it continues to run further code without waiting when compiling would be over.

Good catch. Thanks for adding that.

Ok, so it’s nearly done, here I uploaded it on GutHub: GitHub - chanfort/AssetCompatibility

There are two classes ClassA and ClassB. As an analogy ClassB would correspond to A* project class while ClassA would be my project class. There is also inspector class which shows the tick and detects when dev is clicking on the tick. The tick is only visible when ClassB exist and is hidden then there is no ClassB in the project. Here comes the last problem which I can’t find out how to properly handle.

If developer is deleting or renaming ClassB and the tick is set to true before doing so, the error pop up first rather than waiting and unsetting. I guess I need to override some kind of editor function, which would run before compilation when something in project changes. It looks like that Update() and OnInspectorGUI() are not running when error pop-up first and the part of code, which should un-define symbols is never reached. Any ideas how could be possible to work around this?

You could use [ExecuteInEditMode] to wait and check, but why not leave this up to the developer? Just provide a checkbox that adds or removes the define, and give the developer the responsibility of making sure the asset is there when ticking the checkbox.

I tried with [ExecuteInEditMode] in the ClassA (if you looked there). That Update() is not running when there are errors. The checkbox is visible when ClassB is defined (there are checks with System.Type.GetType(“ClassB”) to make the tick visible), so you can’t tick when there is no asset in the project :slight_smile:

The problem is not ticking but un-ticking. You still need to un-tick the flag first before deleting/renaming ClassB. If developer deletes ClassB first, it will break up things and developer will need to manually clean symbols in Player Settings by hand, what can be not obvious for some devs.

I don’t think that’s very good idea to keep this last bit here, as it basically would require the similar amount of “clicks” spent in commenting/uncommenting the code + devs would become dependent on where in Player Setting would need to look for conditional keywords to clean up, what could be a topic of change between different versions of Unity :confused:

That’s a tough one, since you can’t run code if there are compile errors. Maybe just do a best-effort check for the asset (e.g., A*) when the developer tries to tick the checkbox. If you can’t find the asset, make the developer click OK on a confirmation dialog to actually set the define. And if the developer clicks anyway, he’ll have to deal with the consequences. Good luck!