AssetDatabase.ImportPackage Callbacks don't work ?

Hello !

I’m making a tool where I have to import a custom package from Github, and I need a call back when it’s completed in editor.

For that I use as recommend by the doc the AssetDatabase.ImportPackage callback, more precisely AssetDatabase.importPackageCompleted.

Here is the function where I declare the callbacks:

void Download()
{
AssetDatabase.importPackageCompleted += ImportCompleted;
                            AssetDatabase.importPackageCancelled += ImportCancelled;
                            AssetDatabase.importPackageFailed += ImportCallBackFailed;
                            AssetDatabase.importPackageStarted += ImportStarted;

AssetDatabase.ImportPackage(path, true);

}

And here the functions called by the callbacks:

 static void ImportCompleted(string packageName)
        {
            Debug.Log ("Completed " + packageName);
            AssetDatabase.importPackageCompleted -= ImportCompleted;
        }
       
        static void ImportCancelled(string packageName)
        {
            Debug.Log ("Cancelled " + packageName);
            AssetDatabase.importPackageCancelled -= ImportCancelled;
        }
       
        static void ImportCallBackFailed(string packageName, string _error)
        {
            Debug.Log ("Failed " + packageName);
            AssetDatabase.importPackageFailed -= ImportCallBackFailed;
        }
       
        static void ImportStarted(string packageName)
        {
            Debug.Log ("Started " + packageName);
            AssetDatabase.importPackageStarted -= ImportStarted;
        }

The only callback that works is the ImportStarted one.
Any idea?

You can maybe find a explanation here: Unity Issue Tracker - AssetDatabase.importPackageCompleted callback doesn't fire if scripts have been recompiled during the import process.

Maybe call a AssetDatabase.Refresh?

Hello !
I try to put an AssetDatabase.Refresh (before and after by the way ^^) but it doesn’t work.

Oh btw, the issue tracker is put as fixed but no version is precise.

up ?

Someone?

It doesn’t say fixed. It says by design which means that’s how it’s supposed to work.

1 Like

The AssetDatabase.importPackageCancelled does not reimport or recompile and it’s not being called. Is there a specific way to receive those calls? @karl_jones

If it’s not being called then it sounds like a bug. Can you please send a bug report?

Neither the AssetDatabase.importPackageCompleted and AssetDatabase.importCallBackFailed.
That was part of the original question. Or maybe there is something I don’t understand…

@karl_jones do we need to post three bug report or just 1 ?

One bug report is fine.

@Martin_Gonzalez Did you send a bug report? If yes, could you share a link to the issue tracker?

It was already created. Here it is.

https://issuetracker.unity3d.com/issues/assetdatabase-dot-importpackagecancelled-callback-is-not-called-at-all

Did you manage to make the other callbacks (Completed, Started, Failed) work? @Martin_Gonzalez

I didn’t use other evenst, I just wanted that one because my idea was to delete the file after import is completed.

As I see others wondering about receiving complete callback, will add some info. I receive complete callback. What I did: added log in static constructor to see when my class, waiting for callback is recreated. It is recreated for example, if assembly in which it resides is being recompiled. It may happen, if you import package which contain code. Note that. To save state between recompiles, you can write to file or use PlayerPrefs. I suggest you start from logging, like I did:

    [InitializeOnLoad]
    public class PackageRegistrar : AssetPostprocessor
    {
        static PackageRegistrar()
        {
            Debug.Log("PackageRegistrar: s_ctor");
            AssetDatabase.importPackageStarted += OnImportPackageStarted;
            AssetDatabase.importPackageCompleted += OnImportPackageCompleted;
        }

        public static void OnPostprocessAllAssets(
            string[] importedAssets
            , string[] deleted
            , string[] movedAssets
            , string[] movedFrom)
        {
            LogIfAny("importedAssets", importedAssets);
            LogIfAny("deleted", deleted);
            LogIfAny("movedAssets", movedAssets);
            LogIfAny("movedFrom", movedFrom);
        }

        private static void OnImportPackageStarted(string packagename)
        {
            Debug.Log($"PackageRegistrar: OnImportPackageStarted({packagename})");
        }
     
        private static void OnImportPackageCompleted(string packagename)
        {
            Debug.Log($"PackageRegistrar: OnImportPackageCompleted({packagename})");
        }
}

The output is:

PackageRegistrar: PackageRegistrar: OnImportPackageStarted(external-dependency-manager-latest)
PackageRegistrar: PackageRegistrar: s_ctor // so, it is recompiled in-between
PackageRegistrar: PackageRegistrar: OnImportPackageCompleted(external-dependency-manager-latest)

2 Likes

Thank you. You are right about the recompilation thing that I ignored. So basically if the unitypackage contains any script file or assembly definition that will trigger the recompilation process, the callback function delegate will be cleared. Therefore, the delegate registration needs to take place after the recompiling. What Ive done is to put the delegate registration in a OnInitializeLoad class.

Just found out you have done the same thing. And it is very nice to use EditorPrefs store the state.