How to use RenderStaticPreview OR get project viewer thumbnails for ScriptableObject assets?
I'm using the code from the example here
Here is how my current script looks (Tile3D is a ScriptableObject, it's sub-classing another base class I wrote that doesn't have much going on it it yet.)
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Tile3D))]
public class Tile3DEditor : Editor
{
public override Texture2D RenderStaticPreview(string assetPath, UnityEngine.Object[] subAssets, int width, int height)
{
Tile3D tile = target as Tile3D;
if (tile == null)
return null;
Texture2D cache = new Texture2D(width, height);
EditorUtility.CopySerialized(AssetPreview.GetAssetPreview(tile.mat.mainTexture), cache);
return cache;
}
}
public class Tile3D : CGridObject
{
public GameObject shape;
public Material mat;
private void Awake()
{
mat = (Material)Resources.Load("Tilemap3D/assets/DefaultMat");
shape = (GameObject)Resources.Load("Tilemap3D/assets/TileCube");
}
[MenuItem("Assets/Create/Tilemap 3D/Tile3D")]
public static void CreateTile3D()
{
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
if (path == "")
{
path = "/Tile3D/tile3D.Asset";
}
else
{
path += "/tile3D.Asset";
}
Tile3D asset = ScriptableObject.CreateInstance<Tile3D>();
AssetDatabase.CreateAsset(asset, path);
}
}
It Almost works, but every time Unity starts up, the first time RenderStaticPreview() is called, AssetPreview.GetAssetPreview() returns null, and a NullReferenceException occurs. Every sequential call after that seems to be fine.
All I want is for my custom ScriptableObject assets to have their own custom icons in the project viewer, as well as the ability to keep them updated relative to a texture reference the object has. It seems like RenderStaticPreview() is the way to go about this, but what am I missing here? Is there a more proper way to go about using this method?
Or is there a more proper way to accomplish this task in general?
Answer by TomateSalat · Nov 11, 2019 at 04:47 PM
I was able to get rid of this NullReferenceException with this line:
while (AssetPreview.IsLoadingAssetPreview(item.ItemImage.GetInstanceID()));
But it might could end up in an endless loop.
Answer by Rastatronics · Jan 09, 2021 at 12:49 PM
I fixed this issue by adding a simple null check to GetAssetsPreview:
public override Texture2D RenderStaticPreview(string assetPath, UnityEngine.Object[] subAssets, int width, int height)
{
Tile3D tile = target as Tile3D;
if (tile == null)
return null;
var preview = AssetPreview.GetAssetPreview(tile.sprite);
if (preview == null)
{
return null;
}
Texture2D cache = new Texture2D(width, height);
EditorUtility.CopySerialized(preview, cache);
return cache;
}