Moving a file in AssetPostprocessor.OnPreprocessAsset()

I’ve got some tool-generated files that are coming into Unity, and one of the file types needs to be renamed as it’s coming in (just adding a “.txt” to the path name). I’m running the following code in an asset pre-processor:

void OnPreprocessAsset() {
    if (assetPath.EndsWith(".foo")) {
        File.Move(assetPath, assetPath + ".txt");
        AssetDatabase.Refresh();
    }

    return;
}

However, when I import the files, I get the following error:

My guess is that the asset importer is operating on the original file, and when I move that file, it throws the error because it loses the reference to the original. The “AssetDatabase.Refresh();” call was added later, but doesn’t seem to have any effect.

Is there a proper way to rename a file in an asset pre-processor, and have the new file processed right away, and/or avoid this error when Unity tries to continue processing a now-nonexistent file?

Hey @nickfourtimes1 , here is come documentation on importing assets into Unity. Hope this helps!

The problem isn’t so much with getting the files into the project – they’re already in the directory. What I want to do is rename an asset in an AssetPostprocessor.OnPreprocessAsset() call.

I can get to the point of identifying the right assets for renaming, but when I perform the rename on the OS level, the asset processor throws the “missing file” error from the original post.

Just tried moving the code into AssetPostprocessor.OnPostProcessAsset(), and doing the work in the post-processor does work. I do force an AssetDatabase.Refresh() after moving the file, to make sure the new asset is properly reimported. This doesn’t necessarily answer the question of how to rename a file during pre-processing, though.

Well maybe I was hallucinating because I could swear that latter approach with OnPostprocessAssset() worked, but looking at the documentation page, no such method exists. Weird.

Anyway, I did manage to do things without crashing the pre-processor by copying the file in the pre-process, and then deleting the original in the post-processor, like so:

void OnPreprocessAsset() {
    if (assetPath.EndsWith(".foo")) {
        File.Copy(assetPath, assetPath + ".txt");
        AssetDatabase.ImportAsset(assetPath + ".txt");
    }
    return;
}


static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) {
    foreach (var path in importedAssets) {
        if (path.EndsWith(".foo")) {
            File.Delete(path);
            AssetDatabase.Refresh();
        }
    }

    return;
}
4 Likes