Getting None or Missing Texture from AssetPreview.GetAssetPreview
Asked Answered
D

5

0

Hi,
I have a strange problem. The first few objects of my gameobject array which contains the asset previews from the specified folder return none or a missing texture. And every second time building the scene the textures from Element 10 to 20 are none or missing and the textures that were none before are assigned properly.

My code:

using UnityEngine;
using System.Collections;
using UnityEditor;

public class Items : MonoBehaviour
{	
	public GameObject[] item;	
	public Texture2D[] itemIcon;  
	void Start ()
	{
		itemIcon = new Texture2D[item.Length];
		for(int i = 0; i < item.Length; i++)
			itemIcon _= AssetPreview.GetAssetPreview(item*);*_
	}
}

I’m using Unity 4.
Sorry for my english :stuck_out_tongue:

[12535-unbenannt0.png|12535]
[12536-unbenannt.jpg|12536]

Distant answered 24/1 at 12:32 Comment(1)

It looks like a bug in Unity. See duplicate here: http://answers.unity3d.com/questions/259608/editorutiltiygetassetpreviewobject-asset.html

Bathtub
A
0

GetAssetPreview is really running asynchronously in the background, and if the preview you want is not available when you ask for it you will get a null instead of a texture.

You can work around this by polling the preview multiple times:

int counter = 0;
Texture2D thumbnail = null;
while (thumbnail == null && counter < 75)
{
    thumbnail= AssetPreview.GetAssetPreview(o);
    counter ++;
    System.Threading.Thread.Sleep(15);
}

However this does give a lag time of as much as 1 second for each preview. On my machine I rarely see more than 30 or 45 ms but disk access, processor speed, and other hidden stuff will all affect that. Use with caution.

Adminicle answered 24/1 at 12:32 Comment(1)

I tried this code and it didn't solve the problem, just jammed unity pretty badly. For many objects GetAssetPreview never seems to return anything, no matter how long you wait. I think GetAssetPreview is simply buggy.

Balk
M
0

After several hours of research I found a way to do it:
Run the while loop until the texture is not null and then continue. Here’s a small example

Texture2D bTexture =  null;
while(bTexture==null)
{
							
	bTexture = AssetPreview.GetAssetPreview(go);
											
	Thread.Sleep(80);
}
						
if(bTexture != null)
{
	bTexture.mipMapBias = -1.5f;
	bTexture.Apply();
	byte[] data = bTexture.EncodeToPNG();
	string pathAndName = path+go.name+".png";
	File.WriteAllBytes(pathAndName, data);
}
Mutant answered 24/1 at 12:33 Comment(1)

Thank you, man! You saved my time, but I already lost 2 hours.

Dorolice
K
0

I found that the texture from GetAssetPreview() is not always available.
I’m copying it to a local texture once I get it.

Texture2D tx = AssetPreview.GetAssetPreview(myPrefab);
if (tx == null)
	_tex = null;
else
{
	_tex = new Texture2D(tx.width,tx.height);
	_tex.SetPixels(tx.GetPixels());
	_tex.Apply();
}
Keepsake answered 24/1 at 12:34 Comment(0)
A
0

For 2021, I think the best way to do this is probably set off a Coroutine to just query until an image is found. In my code I’m looking to set the thumbnail of some canvas objects but they aren’t setting.

I did this and it seems to work.

IEnumerator SetThumbnail()
{
    Texture2D thumbnail = null;
    while (thumbnail == null)
    {
        thumbnail = AssetPreview.GetAssetPreview(myPrefab);
        yield return new WaitForSeconds(.5f);
    }
    var sprite = Sprite.Create(thumbnail, new Rect(0.0f, 0.0f, thumbnail.width, thumbnail.height), new Vector2(0.5f, 0.5f), 100.0f);
    SetImage(sprite);
}

In my Start() method I just fire it off using:

StartCoroutine( SetThumbnail() );
Anatollo answered 24/1 at 12:34 Comment(0)
A
0

Coroutine is definitely better than a thread-blocking while loop.

However, if you aren’t in unity Object-land, and are instead working with UI Toolkit, I’d suggest using the Scheduler. This has worked for me.

Image thumbnail;
schedule.Execute(() =>
{
    var preview = AssetPreview.GetAssetPreview(asset);
    if (preview != null)
        _thumbnail.image = preview;
})
.Until(() => !AssetPreview.IsLoadingAssetPreview(asset.GetInstanceID()));

There’s room for optimisations, and you should likely ensure the task is stopped if it cannot be completed for whatever reason.

Also note that if you are trying to display many thumbnails simultaneously, you may run into the cache limit. See Unity - Scripting API: AssetPreview.SetPreviewTextureCacheSize

Ares answered 24/1 at 12:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.