Hey @spiney199!
Thanks for showing me a working example, it helped me figure out what’s going on. Apparently it’s a bug with AssetPreview.GetAssetPreview.
I have a folder of prefabs, so I select all of the prefabs and run my editor script. Here’s the full code:
AssetDatabase.StartAssetEditing();
var items = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
for (var i=0; i<items.Length; i++) {
var o = (GameObject) items[i];
var name = o.name.Replace("_Static", "");
Texture2D texture;
do {
// GetAssetPreview is an async call, so we need to wait for texture to get populated
texture = AssetPreview.GetAssetPreview(o);
// waits while asset is loading...
while (AssetPreview.IsLoadingAssetPreview(o.GetInstanceID())) {
Thread.Sleep(1);
}
// despite IsLoadingAssetPreview returing false, I found that texture may still return null
// at times, so this outer loop ensures that it refetches in case of null
// this is a red flag that something is amiss...
} while (texture == null);
// hideFlags needed here because the texture generated has protections that doesn't allow
// it to be saved.
texture.hideFlags = HideFlags.None;
AssetDatabase.CreateAsset(texture, "Assets/AddressableStaging/Thumbnails2/" + name + ".asset");
}
AssetDatabase.StopAssetEditing();
AssetDatabase.Refresh();
I find that about 90% of the assets created this way are valid, while the rest are not. I select the first asset generated and can see the preview in the inspector just fine, and I just go down the list one by one and every now and then an asset will display nothing in the inspector, and this happens for about 10% of the assets generated. This tells me that somewhere between the IsLoadingAssetPreview returning false and the CreateAsset call, something is destroying the texture behind the scenes. During testing, I found that when I select a single prefab and run the code, it seems to generate fine, but when I selected two, it failed a lot on the first one. This has me thinking perhaps the item selection itself may be interfering with this process somehow, perhaps because it does its own preview of the highlighted items in the inspector.
To sum this all up, I select more than a hundred prefabs and run an editor script to generate previews of the items I selected, but Unity also runs previews of its own on the selected items and displays them in the inspector, and I think that this may be interfering with GetAssetPreview calls and causing some of the generated textures to get destroyed while you’re trying to save them. I’m able to save them just fine via saving texture.EncodeToPNG() to file though, so my guess is that since texture.EncodeToPNG() is a method that texture knows is running, it doesn’t allow any destroy logic to run while it’s executing, but that’s just a guess.
Any Unity devs out there in the know?
update: Interesting… when I show my generated assets in list view (text only), when I select a good asset I see the inspector show the preview just fine, but when I select a bad asset the inspector is completely blank. But when I change the view to display icons instead, I can actually see the icon of the bad asset just fine, but selecting it still shows an empty inspector.
workaround update: I got it working, but I had to use Graphics.CopyTexture to copy it before calling CreateAsset, and there’s probably still a chance of some race condition happening.