0
\$\begingroup\$

I want to get image of any asset from code. Unity can display assets as with images of those assets. Is there a way to get that image from code? I need it to be able to display it in the inspector.

public class AssetIconDisplayAttribute : MultiSupportPropertyAttribute
{
#if UNITY_EDITOR
    public override void DrawInInspector(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUILayout.ObjectField(new GUIContent(property.displayName), property.objectReferenceValue, property.GetContainingObjectFieldType(), true);

        EditorGUI.DrawPreviewTexture(position, @that asset image here@);
    }
#endif
}

Asset Example

Is there a better way to achieve this? The ideal result I want is object field that is displayed like a Texture2D field in inspector but is not a type of Texture2D but stays its own type.

An example of Texture2D: enter image description here

EDITS:

With AssetPreview.GetMiniThumbnail: AssetPreview.GetMiniThumbnail

With AssetPreview.GetAssetPreview:

Gives null if the object reference is a component, you have to pass GameObject in order to get the value.

Fix:

AssetPreview.GetAssetPreview((serializedProperty.objectReferenceValue as Component).gameObject)

AssetPreview.GetAssetPreview

With AssetDatabase.GetCachedIcon: AssetDatabase.GetCachedIcon

@EDIT - note: the code won't work out of the box as some elements which are not important/related for/to this task are custom made. This is what I currently have and what has been working for me before in the old project. Because of some non-related errors after upgrading to new unity version I can't get an example of how it looked but anyway I wanted to share it.

public class AssetIconDisplayAttribute : MultiSupportPropertyAttribute
{
#if UNITY_EDITOR
    public override float GetPropertyExtensionHeight()
    {
        if (this.serializedProperty != null && this.serializedProperty.objectReferenceValue != null)
        {
            return EditorGUIUtility.singleLineHeight + 80f;
        }

        return EditorGUIUtility.singleLineHeight;
    }

    public override void DrawInInspector(Rect rect, SerializedProperty serializedProperty, GUIContent label)
    {
        EditorGUI.PropertyField(new Rect(rect.position, new Vector2(rect.size.x, EditorGUIUtility.singleLineHeight)), serializedProperty);

        if (serializedProperty.objectReferenceValue != null)
        {
            if (AssetPreview.IsLoadingAssetPreview(serializedProperty.objectReferenceValue.GetInstanceID()))
            {
                EditorGUI.DrawPreviewTexture(new Rect(new Vector2(rect.max.x - 82f, rect.position.y + EditorGUIUtility.singleLineHeight * 1.5f), new Vector2(64f, 64f)), AssetPreview.GetMiniThumbnail(serializedProperty.objectReferenceValue), null, ScaleMode.ScaleToFit);
            }
            else
            {
                EditorGUI.DrawPreviewTexture(new Rect(new Vector2(rect.max.x - 82f, rect.position.y + EditorGUIUtility.singleLineHeight * 1.5f), new Vector2(64f, 64f)), AssetPreview.GetAssetPreview((serializedProperty.objectReferenceValue as Component).gameObject), null, ScaleMode.ScaleToFit);
            }
        }
    }
#endif
}
\$\endgroup\$
7
  • 1
    \$\begingroup\$ Are you looking for this? docs.unity3d.com/ScriptReference/… \$\endgroup\$
    – DMGregory
    Jun 6 '18 at 11:45
  • \$\begingroup\$ @DMGregory almost but that is in the right direction. I will try to research it. Could find any information about it, didn't even know that this API existed. I am probably still bad at searching for info. \$\endgroup\$ Jun 6 '18 at 11:59
  • 1
    \$\begingroup\$ Re: your null, I noticed this in the docs: "Since previews are loaded asynchronously methods are provided for requesting if all previews have been fully loaded" so you might need to request the preview, tolerate an empty result for a little while, then check back for the real texture once it's finished loading. \$\endgroup\$
    – DMGregory
    Jun 6 '18 at 12:02
  • \$\begingroup\$ @DMGregory yeah, I am trying to do it now. I have also found that docs.unity3d.com/ScriptReference/… exists. Might, work if the previous method doesn't. \$\endgroup\$ Jun 6 '18 at 12:05
  • \$\begingroup\$ @DMGregory I seem not to be able to find a solution right now, maybe, I will get to it later eventually. Even though, they state that it's loaded async. The method itself isn't async and it doesn't have any callbacks to get the value. I have tried checking if it's loading, looping till it's loaded, coroutines in play mode, looping in play mode, nothing seems to work :( Maybe, in future I will be able to get that value via reflection or similar method. It seems to be working for some people, I have seen post where only half of the entries in array were loaded, thus it must work. \$\endgroup\$ Jun 6 '18 at 14:11
1
\$\begingroup\$

Try to keep things simple:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LoadTexture : MonoBehaviour {


    public GameObject texture;
    public Texture2D gameObjectTex;
    public Texture gameObjTex;

    // Use this for initialization
    void Start () {
        var getImage = UnityEditor.AssetPreview.GetMiniThumbnail(texture);
        print(getImage);

        gameObjectTex = getImage;


    }


    // Update is called once per frame
    void Update () {

        CheckIfNull();

    }

    void CheckIfNull(){
    var instance = texture.GetInstanceID();
    if(UnityEditor.AssetPreview.IsLoadingAssetPreview(instance)){

        Debug.Log("still fetching");
    } else {
        var getAssetPreview = UnityEditor.AssetPreview.GetAssetPreview(texture);
        gameObjTex = getAssetPreview;
    }
}

}

Now, since the code gets the GameObject directly (from the public dec.) it gets loaded immediately. If you are mapping an array, you can use the already integrated API from unity to check if its still loading to prevent nil status.

GetAssetPreview will give you the thumbnail, however, it will be small. In this case, if you want to create a bigger 'thumbnail' preview, you have to customize the editor via:

EditorGUI.DrawPreviewTexture

You could create a preview window via:

function OnGUI() {
        texture = EditorGUI.ObjectField(Rect(3,3,200,20),
                "Add a Texture:",
                texture,
                Texture);

and then add via if statement:

if(texture) {
            EditorGUI.PrefixLabel(Rect(25,45,100,15),0,GUIContent("Preview:"));
            EditorGUI.DrawPreviewTexture(Rect(25,60,100,100),texture);
            }


}

to draw the picture. Now you'd simply have to write a function that injects the texture automatically into your new Preview window. Before you do that, i suggest you to do everything and 'manually' add the texture when you run unity to check everything works fine.

Greetings!

\$\endgroup\$
1
  • \$\begingroup\$ Glad i could help! \$\endgroup\$
    – Prometheus
    Jun 7 '18 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.