Random Reimports of all FBX files

I am getting this problem that during just editing of general scripts I come back into Unity and it all of a sudden just starts reimporting all the fbx files for no reason, the fbx files have not changed or been touched in anyway, I just make a change to a general script and then randomly out of nowhere I have to sit and wait minutes for Unity to reimport the objects, what is causing that?

I would suspect some editor script touching these, or forcing them to re-import for whatever reason.

Perhaps the profiler with deep profiling in edit mode can help out here. Start profiling, change a script, then stop profiling after import is done and the fbx reimport occured. Then step through the frames to see if anything in the call stack stands out - I would expect these methods to have a high ms time associated with it.

Otherwise I’d probably either disable any possible packages/assets that may cause this (perhaps in a copy of the project). Also I’d be seaching all files for every use case of a script hooking into assembly reload events or other events/attributes that cause a method to run after assembly reload (eg InitializeOnLoad).

Whenever faced with “something reimported, but why?” question, I’d always check Import Activity Window (since Unity 2021) first Unity - Manual: Import Activity window – it lists all the imports that happened, including, crucially, why it imported. Usually it’s something like some asset postprocessing C# script in the project changing some setting etc.

3 Likes

Thanks Aras I will check that out during todays random crashes and imports :slight_smile:

So checked the Activity window for ingo and the reason it gave for the last round of random imports was:

the value of the custom dependency 'ScriptTypes-v1/MonoScript/3-7951c6d989372584cbc6eaf0ca401f89-11500000' was changed from '8b6db6dfe8ac3d6d4f733195c34af230' to '44462f74a5cd72eb311b20c0ac3afc9f'

So not sure that really helps track down the problem, looks like something Unity decided to do for some reason.

I would say the Activity Monitor is not very useful in trying to find out what the issue is, it doesn’t give you actual filenames just GUID’s, you would think if you clicked a dependency in the list it would help out by showing the file in the project or something. I have attached a grab of the Activity Window showing the user friendly and useless info it gives for reimporting all the assets.


And if it is a change to a script in the project that is triggering all this the question is why? What does a change in a game logic script have to do with an FBX file requiring reimporting. I have tried putting the GUID’s into the new search window which is supposed to show assets from GUIDs but it doesn’t find anything.

Hmm good question, I’ve never seen a cause of reimport that looks like yours. Maybe @Unity_Javier would know?

2 Likes

Hi @SpookyCat ,
I agree that the Import Activity Window could use a bit more love when it comes to showing GUIDs.
However, for your immediate problem, can you search for this value inside all your .meta files: 7951c6d989372584cbc6eaf0ca401f89 ?
That is the GUID of one of your scripts. This Script dependency is registered most likely because that script is a MonoBehaviour which has been added as a component to your FBX Asset, and then becomes registered as a dependency.

From your screenshot I can see there are quite a few components added to this FBX Asset, which means that if any of them change then you’ll be reimporting this FBX…and I can see it takes 21s to import too!

One idea could be to extract some of the code in your MonoBehaviour to a different C# file, so as to prevent this re-importing anytime the MonoBehaviour changes.

Thanks for the help, but I don’t understand why changing a script that is added to a gameobject triggers a full reimport of the fbx file, that script doesn’t change anything to do with the fbx file itself? So extrapolating this to a very large game with 1000’s of objects and there maybe a small script of two that has been added to all those objects, so you then make a tiny change to the script logic and all of a sudden your project decides it needs to reimport a 1000 fbx files, how can that be a sensible thing?

Plus the other point is that it doesn’t happen for every change to the script, I can be changing for 15 minutes going back and forth, then all of a sudden make another small change to the script and wham another full reimport of a load of objects, that doesn’t make sense to me either, either changing a Mono attached to the object triggers a reimport every time, or not at all, not a random occurence?

The “”“prefab”“” generated by the fbx importer is a trap, never use it for anything.

Hi @SpookyCat .

The asset database register script type dependencies to all the types that is in an import result. If the serialization format of a script type changes, it will trigger reimports for assets that produces import results (objects) with this type. The reason for the dependency is to ensure consistent import results.

Thanks for the info, so what would be the suggested strategy when one has a custom Importer making use of Custom User Properties to add scripts to an object during import, to save to tedious manual doing one by one after import, which I kinda assuming is part of the reason custom importers, post processors and support for User properties exist. In previous versions of Unity this worked just fine you could add scripts during import and after that nothing got reimported if you made a tiny change to any of these scripts, but now it seems if you do that you have non stop reimports for no real valid reason as the small changes to the scripts in no way have any effect on the object in regards to it requiring a full reimport of all its data. So that combined with the nightmare long delays now in Unity when you make a tiny change to a script in an editor and have to wait 30s before Unity finishes reloading all the domains, repainting and other stuff just makes using Unity now a really bad experience from what it used to be.

So if you could suggest what one should be doing that would be helpful, is it a case of letting the object be imported, keeping track of all the changes you want to make then duplicating the object and applying the scripts to that? But that just seems like you end up with copies of everything contanimating the project, increasing build times and sizes. So if some official guidelines on how to go about adding scripts to object during import using the Unity systems that doesn’t lead to having to wait 10 minutes when making a small script change for everything to reimport would be useful I think.

We are aware that script type dependency causes more imports, but it is at the same time of the fix for the problem it solves. Before script type dependencies you could end up with a corrupt library folder that had broken references. This often resulted in users deleting library folder or having do manual imports to fix broken references.

We are working on reducing imports required, but can’t provide more details.

So it is not reccomended to apply any scripts to objects using Prost Processors?

Can you clarify what you mean by “apply any scripts to objects using Prost Processors”?

Here is an example of how script type dependencies are registered. If you have an AssetPostprocessor that adds an object to import result like this:

var myScriptableObj = ScriptableObject.CreateInstance<MyScriptableObjType>();
context.AddObjectToAsset(myScriptableObj);

Then the asset db will register a script type dependency to MyScriptableObjType. If the serialization format of MyScriptableObjType changes (unity serialization rules) it will trigger a reimport (or use an existing matching import result, if such should be available - like if a field is removed and added again).

@volblob73 while you’re figuring out this particular issue, I think this (and many other similar) cases point to a different issue altogether: that ever since ADBv2, in the name of consistency (a noble goal!), “way more reimports” are happening, doing costly work, which in the ideal world would not be happening (if asset database had a slightly different design and/or cached things differently).

For example, “I added a new texture asset postprocessor script → all textures reimport!” is a huge cost, even if the postprocessor script does nothing whatsoever. Same in the above example: the thing that “adds some script to the final imported FBX prefab” is a thing that happens at the end, after the FBX import is done; the “do the actual work of FBX import” bit is still exactly the same no matter if the script is added at the end or not. I remember discussing this (in the context of textures) with y’all maybe back in 2020, that it would be nice to somehow cache this “costly work” (texture import / compression, FBX import, …) bit independently of the final imported result (I had an internal google doc about this somewhere, but of course I no longer have access to it…).

I would imagine it might work like this:

  • The overall “Texture Importer”, similar to today, has inputs that are the full source file content, full .meta file content, current platform, whatever else. In the end, it does produce the same thing as today, i.e. say a whole serialized Texture2D object.

  • But internally, it it “somehow” split into separate sub-importers and/or importers chained together:

  • one that reads and decodes input file, plus only the minimal set of settings that affect input file decoding (mipmap calculation, texture size, etc.). It produces a blob of uncompressed raw pixel data, for all the texture mipmaps. As such, it does not depend on current platform or whatever, only on the settings that could possibly change the uncompressed pixels part. The result is cached somewhere in the asset cache innards.

  • one that takes the uncompressed pixel blob from previous step, and applies texture compression. This one as an input has only the settings that affect texture compression (compression format, compressor quality, etc.). The result of that is a blob of compressed pixel data, again cached somewhere.

  • one that takes compressed pixel blob from previous step, and produces final Texture2D (or other texture) object. Compared to step 1 and 2, this is typically way less costly in terms of import time.

A thing like above would solve the problem of, for example, “I changed texture filter mode, it reimports whole texture”. With the above, only step 3 would actually be re-ran (since filter mode is a setting that only affects step 3). Or, if a texture is same size and same compression format between all of iOS, tvOS and Android (with same texture size setting on all of them), it would not need to be cached and reimported separately for each of those platforms, since the result and settings used in each of the steps above are exactly the same between them.

Likewise for FBX importer, it could also be split into “1) step that reads input FBX and produces intermediate data about models/animations/rigs/whatever”, and “2) step that creates final prefab out of that and possibly attaches scripts or whatever, driven by user postprocessor”. If postprocessors related to step 2 change, the (actually costly) step 1 does not need to re-run.

Similar thing could be done for audio & video files too of course.

6 Likes

Our game objects are created in 3ds Max and I have added 200+ modifiers to Max to allow the artists to setup the objects, get them rigged, and add all sorts of stuff to the objects, we then have a custom FBX exporter that scans for these modifiers and serializes it to custom user properties.
Then we have custom importers in Unity that looks for the User properties during an FBX import and then adds components as needed to the objects and deseriaizes all the values to them, so for example when we import a Car model fbx that fbx can then be dropped straight into the game project and it is fully driveable with all the engine, physics, electrical wiring, opening and closing objects, IK targets, sounds everything fully working.

You can see an example of that in the video below at about 1:21:39 onwards where I added a Modifier to Max to define the setup of a Windsock object, and you can see when the FBX is imported and added to the scene everything is already setup and working.

https://www.youtube.com/watch?v=_BgNUNBjofY

This has worked perfectly from Unity 2018 onwards, but with 2023 along with the painfully slow changing of a single line in VS and going back to the editor there are now constant reimports of objects for again no reason I can see, what does it matter to the whole object if something in a script attached to an object changes.

1 Like

@aras-p You are right. We are working on improving this and changing the asset db design to reduce imports. Part of this is splitting imports into smaller results which allows more fine-grained dependencies (fewer imports) and in general prevent importing of assets not used.

3 Likes

@SpookyCat From my understanding of what the video is showing, I don’t see anything wrong. The “windsock” scene object use “Wind Sock” scripts, which a dependency will be registered to. If serialization format of this type is changed, it will trigger a reimport and how things are working right now.

Does this mean you started getting the issue with reimports in version 2023? Script type dependencies have been in unity since 2019.3 or 2019.4.

I recently switched over to start testing 2023 from 2019.4 and it is only now I see reimports, 2 years or so of 2019.4 with the same import system assinging scripts to objects during the import and it never reimported an object due to me changing a script, as I said it worked flawlessly for years, no issues with corrupted anything it all just worked, but with 2023 the whole editor has turned into an unseable nightmare, change a script, loads of things reimport, change a script for something that isnt attached to any imported object and you sit through 30s+ of Unity telling you its reloading some domain, repainting, doing something else before you can finally see the result of the change, again this never happened in 2019, it was instant, you make a change in VS save it and before you could even switch back to Unity 2019 it was all ready to go.
If I came across Unity now and was presented with 15 to 30 seconds for every tiny change to a script, let alone half the project deciding to reimport I would just say no thanks what else is out there.

1 Like

@SpookyCat when using 2019.4, are you using asset db v1 or v2?