How to handle AssetPreview.GetAssetPreview()

Hi All!
(NOTE I posted this on the answers section however going on 3 days it is still pending moderation :\ So I decided to post here too)

I’m wondering of someone could share their experience… I’m writing an EditorWindow which loads in the asset preview image from an asset - however am having some troubles working around the fact that method is async.

The first time this runs, the icon draws in my window as a white square - I’d imagine because it hasn’t pushed the Texture2D into the cache yet. Close my editor window and run it again, boom works brilliantly.
Close Unity and try again, repeatable issue.

First Run

Close CustomWindow - Open Again

I’ve experimented with using the AssetPreview.IsLoadingAssetPreview() method however that isn’t running well.

Here is what I have so far…
I am creating a class named Tile which holds the Texture2D from GetAssetPreview.
It has a member method DrawBox() which basically draws a box using this Texture.

Then on my OnGui method I have it call DrawBox().

private class Tile
    {
        public GameObject prefab;
        Texture2D icon;
        public Rect boxRect;
  
        public Tile(GameObject prefab)
        {
            this.prefab = prefab;
            icon = AssetPreview.GetAssetPreview(this.prefab);
        }
  
        public void DrawBox()
        {           
            GUILayout.FlexibleSpace();               
            GUILayout.Box(icon, GUILayout.Height(70), GUILayout.Width(70));
            boxRect = GUILayoutUtility.GetLastRect();
            boxRect.height += 30;             
        }
    }

I’ve also tried using isLoadingAssetPreview like this…

    public void DrawBox()
    {
        if (!AssetPreview.IsLoadingAssetPreview(prefab.GetInstanceID()))
        {
            GUILayout.FlexibleSpace();
            GUILayout.Box(icon, GUILayout.Height(70), GUILayout.Width(70));
            boxRect = GUILayoutUtility.GetLastRect();
            boxRect.height += 30;
        }
    }

However if the cache is not ready, it doesn’t draw it at all until the next instance of the editor window is open - I would expect this to be true for a few milliseconds while it loads the Texture2D, however it doesn’t update at all until the EditorWindow is closed and open again.
It seems the OnGui draw method is stuck or something.

Really looking forward to some pointers!

After some more playing around, I have found a workaround - not what I was intending but works nonetheless…

Rather than storing the asset preview into a Texture2D within the class, I am just calling GetAssetPreview in the draw method and it works. I’d have rather used the stored texture in the class, but meh - whatever :stuck_out_tongue:

public void DrawBox()
{
   
    GUILayout.FlexibleSpace();
    GUILayout.Box(AssetPreview.GetAssetPreview(prefab), GUILayout.Height(70), GUILayout.Width(70));
    boxRect = GUILayoutUtility.GetLastRect();
    boxRect.height += 30;           
}
4 Likes

For a texture2D as preview it works only like this on 2019.2

GUILayout.Label(
AssetPreview.GetAssetPreview(LM_CreateTestTextures.rt) as Texture2D,
GUILayout.Width(128),
GUILayout.Width(128));
2 Likes

I found another way that keeps the preview in a Texture2D (not sure for how long…lol):

M.icon = GraphicTools.readableClone(AssetPreview.GetAssetPreview(previewMaterial));
public static Texture2D readableClone(Texture2D texture2D)
    {

        RenderTexture rt        = new RenderTexture(texture2D.width, texture2D.height, 24);
        RenderTexture.active    = rt;
        Graphics.Blit(texture2D,rt);

        Texture2D result        = new Texture2D(texture2D.width,texture2D.height);
        result.ReadPixels(new Rect(0,0,texture2D.width,texture2D.height),0,0);
        result.Apply();

        return result;
    }
1 Like