(Case 1212874) Asset Pipeline v2 breaks ScriptedImporter functionality

If a ScriptedImporter depends on other textures, its OnImportAsset method is not called, if those dependent textures change their format more than once when using Asset Pipeline Version 2.

The provided sample uses a ScriptedImporter that outputs a Debug.Log message every time its OnImportAsset is called.

Changing a source texture should therefore cause the OnImportAsset method to be called and thus output a message to the Console window always.

Video

Reproduce

  • Open provided project
  • Set Asset Pipeline Version to 1
  • Select Bike, Gift and House textures
  • Change the Format to “RGB 24 bit” and press Apply
  • Change the Format to “RGB 16 bit” and press Apply
  • Change the Format to “RGB 24 bit” and press Apply
  • Change the Format to “RGB 16 bit” and press Apply
  • Change the Format to “RGB 24 bit” and press Apply
  • Notice a message is printed to the Console window always
  • Set Asset Pipeline Version to 2
  • Save project
  • Close Unity and reopen project
  • Select Bike, Gift and House textures
  • Change the Format to “RGB 24 bit” and press Apply
  • Change the Format to “RGB 16 bit” and press Apply
  • Change the Format to “RGB 24 bit” and press Apply
  • Change the Format to “RGB 16 bit” and press Apply
  • Change the Format to “RGB 24 bit” and press Apply

Actual
MyScriptedImporter.OnImportAsset is called always when using AssetDatabase Version 1.
MyScriptedImporter.OnImportAsset is called only once for every format change when using AssetDatabase Version 2.

Expected
MyScriptedImporter.OnImportAsset is called every time a texture changes, because it depends on those assets and must regenerate its asset output that depends on these source textures.

Note
In my specific case it breaks custom import pipelines such as this one: GitHub - pschraut/UnityTexture2DArrayImportPipeline: A Texture2DArray Import Pipeline for Unity 2019.3 and newer.

6 Likes

Unfortunately the bug-report was closed with:

Then the question is: How can I get the OnAssetImport event to regenerate my asset, when one of those dependencies change (their texture format)?

Right now, every ScriptedImporter that depends on textures is broken in Asset Pipeline v2 for me, because I don’t receive the OnAssetImport to update the “output asset”.

2 Likes

In your example, I see you selected multiple texture asset.
Does the problem happen with only one texture selected ?

In any case it’s bad :cry:

Asset Pipeline V2 has a cache on disk containing all previous import results.
Whenever an asset’s dependencies changes, the pipeline will try to match a previous import result, and if it finds one, it will use that instead.
In that case OnAssetImport is not called, as nothing needs to be imported.

This is a behavior change compared to Asset Pipeline V1, but a desirable one IMO. This functionality is what drives the fast platform switch functionality for example. This is also the behavior you get with V1 when connected to a cache server and a import result is matched and downloaded.

When you say that “every ScriptedImporter that depends on textures is broken”, can you provide some more detail.

Thanks for your answer!

I copy Texture2D’s into a Texture2DArray. The Texture2DArray uses the texture format of its source textures. If I change the texture format of a source texture in V2, the Texture2DArray ScriptedImporter does not receive the OnAssetImport event and thus does not update to the new texture format.

There currently seem no way to autogenerate the Texture2DArray even though it added the Texture2D’s as dependencies!

I’m using this Texture2DArray Import Pipeline as an example:
https://github.com/pschraut/UnityTexture2DArrayImportPipeline/blob/master/Editor/Texture2DArrayImporter.cs#L106

Yep, even more desirable if this works with ScriptedImporter and asset dependencies.

I have glanced through the code in https://github.com/pschraut/UnityTe…/master/Editor/Texture2DArrayImporter.cs
I see nothing wrong with it. It should just work.
But that is not the same as “It is expected that OnAssetImport is called whenever a dependency changed”.

In your original reproduction steps you write:

  • Change the Format to “RGB 24 bit” and press Apply
  • Change the Format to “RGB 16 bit” and press Apply
  • Change the Format to “RGB 24 bit” and press Apply

And you write that you expect OnAssetImport to be called after the third step.
That is NOT expected to happen, it is expected that Asset Pipeline will see that there is a previous import result already cached for the “RGB 24 bit” version, and that ‘old’ version is then returned instead (when loaded).

If you try to load your Texture2DArray asset after each modification, you should see the following:

  • Change the Format to “RGB 24 bit” and press Apply
  • Load Texture2DArray asset, and see that the output is in RGB 24 bit
  • Change the Format to “RGB 16 bit” and press Apply
  • Load Texture2DArray asset, and see that the output is in RGB 16 bit
  • Change the Format to “RGB 24 bit” and press Apply
  • Load Texture2DArray asset, and see that the output is in RGB 24 bit

It’s fine that it works for textures that way, but the Texture2DArray needs to update in this case too.

What I currently see is Unity doing it like:
“I have texture 1 in format x cached already, lets restore this and don’t tell anybody” and the texture array sits there knowing nothing about this change.

A) If Unity would “bundle” the import-result together with the Texture2DArray, that is “texture 1 in format x results in texture array y” and “texture 1 in format y results in texture array z” and restores the texture array import-result along with the texture 1 import-result, it wouldn’t be a problem.

B) If Unity triggers OnAssetImport on the Texture2DArray ScriptedImporter, not on the Texture2D, as in V1.

The better approach would be A.

V2 implements A
So you should indeed see that you previous Texture2DArray import result is restored, when modifying the dependent texture settings back to a previous value.

To put it differently:
When you perform step 3 in the reproduction steps, then:
The previous import result of the texture should be recovered
The previous import result of the Texture2DArray should be recovered
OnPostprocessAllAssets should be called with both the texture and the Texture2DArray in the
importedAssets argument
OnAssetImport should be called on no asset (since both import results were recovered from the cache)

Is this not what you are seeing?

Thanks for your reply.

What I’m seeing is that it perhaps restores an earlier outdated/garbage import result. I’ve captured a video where I go over it step by step and uploaded (link below) the project including the Library directory that I used in the video, which hopefully helps to figure out why that happens.

https://www.youtube.com/watch?v=zxFc-HXlW14

2019.3.0f6 project download:
http://www.console-dev.de/tmp/Test_ADB_v2.zip

The “Texture2D Array Import Pipeline” package uses some logic to decide whether the input textures/dependencies are valid. In case they are invalid, that is for example if the source texture formats are different, the Texture2DArray will be generated in magenta colors only. Maybe Unity restores that version of the asset?!

Thanks a lot for the repro.
I haven’t looked at it yet, but I will as soon as I land the bugfix I am currently working on.

2 Likes

any news?

4 Likes

Do you have any update for me?

3 Likes

Do you have any update for me?

3 Likes

Congratulations. I surrender, you win.

1 Like

You hit his nose right onto the bug and you explained it correctly from the first post.
thomasa1972 Joined Oct 11, 2016 And get fired after reaching max posts of 4?

I see other important threads like SubScene V2 where Unity-Technoligies-Unpaid-Interns change completely over time and the new 10th didn’t know anything about is related to the thread.

Anyway…
Is it possible to update the tex2d asset manually by pressing an additional button
[Update This One] [Update All Others] in any instance of your script? [Update All Others] it should search for all instances of your script and update others as well. Doesn’t matter how long it takes.

Perhaps it’s better to have a functionality to update manually…

I believe the problem is that Unity never reimports the Texture2DArray asset, because it thinks it has an up-to-date version of this asset imported already and just uses the cached one.

Right-clicking the Texture2DArray and choosing “Reimport” didn’t do anything. Pressing “Apply” in the Inspector didn’t cause a reimport either. Reimporting the dependencies also didn’t cause the Texture2DArray to be reimported, if the content (or hash) of that asset dependency didn’t change.

Perhaps there are some ScriptedImporter API’s to workaround this issue, but I’m not aware of them.