Search Unity

How to handle AssetPreview.GetAssetPreview()

Discussion in 'Immediate Mode GUI (IMGUI)' started by Twin-Stick, Jun 1, 2017.

  1. Twin-Stick

    Twin-Stick

    Joined:
    Mar 9, 2016
    Posts:
    111
    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().

    Code (CSharp):
    1. private class Tile
    2.     {
    3.         public GameObject prefab;
    4.         Texture2D icon;
    5.         public Rect boxRect;
    6.  
    7.         public Tile(GameObject prefab)
    8.         {
    9.             this.prefab = prefab;
    10.             icon = AssetPreview.GetAssetPreview(this.prefab);
    11.         }
    12.  
    13.         public void DrawBox()
    14.         {          
    15.             GUILayout.FlexibleSpace();              
    16.             GUILayout.Box(icon, GUILayout.Height(70), GUILayout.Width(70));
    17.             boxRect = GUILayoutUtility.GetLastRect();
    18.             boxRect.height += 30;            
    19.         }
    20.     }

    I've also tried using isLoadingAssetPreview like this...

    Code (CSharp):
    1.     public void DrawBox()
    2.     {
    3.         if (!AssetPreview.IsLoadingAssetPreview(prefab.GetInstanceID()))
    4.         {
    5.             GUILayout.FlexibleSpace();
    6.             GUILayout.Box(icon, GUILayout.Height(70), GUILayout.Width(70));
    7.             boxRect = GUILayoutUtility.GetLastRect();
    8.             boxRect.height += 30;
    9.         }
    10.     }
    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!
     
  2. Twin-Stick

    Twin-Stick

    Joined:
    Mar 9, 2016
    Posts:
    111
    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 :p

    Code (CSharp):
    1. public void DrawBox()
    2. {
    3.    
    4.     GUILayout.FlexibleSpace();
    5.     GUILayout.Box(AssetPreview.GetAssetPreview(prefab), GUILayout.Height(70), GUILayout.Width(70));
    6.     boxRect = GUILayoutUtility.GetLastRect();
    7.     boxRect.height += 30;          
    8. }
    9.  
     
  3. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    For a texture2D as preview it works only like this on 2019.2

    Code (CSharp):
    1. GUILayout.Label(
    2. AssetPreview.GetAssetPreview(LM_CreateTestTextures.rt) as Texture2D,
    3. GUILayout.Width(128),
    4. GUILayout.Width(128));
     
    JVSoft and Magnitude9 like this.
  4. TorbenDK

    TorbenDK

    Joined:
    Jun 28, 2016
    Posts:
    24
    I found another way that keeps the preview in a Texture2D (not sure for how long..lol):

    Code (CSharp):
    1. M.icon = GraphicTools.readableClone(AssetPreview.GetAssetPreview(previewMaterial));
    Code (CSharp):
    1. public static Texture2D readableClone(Texture2D texture2D)
    2.     {
    3.  
    4.         RenderTexture rt        = new RenderTexture(texture2D.width, texture2D.height, 24);
    5.         RenderTexture.active    = rt;
    6.         Graphics.Blit(texture2D,rt);
    7.  
    8.         Texture2D result        = new Texture2D(texture2D.width,texture2D.height);
    9.         result.ReadPixels(new Rect(0,0,texture2D.width,texture2D.height),0,0);
    10.         result.Apply();
    11.  
    12.         return result;
    13.     }    
     
    lvvova likes this.