Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How can I create a texture/sprite field in Inspector like this?

Discussion in 'Immediate Mode GUI (IMGUI)' started by IntDev, Sep 2, 2015.

  1. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    I want to create a property like this:
    Untitled-1.png

    using a PropertyDrawer. Can you help me?

    This is what I have so far:

    Code (CSharp):
    1.  
    2. [CustomPropertyDrawer(typeof(CombinableSpritesAttribute))]
    3. public class CombinableSpritesAttributeEditor: PropertyDrawer
    4. {
    5.     public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
    6.     {
    7.         var ident = EditorGUI.indentLevel;
    8.         EditorGUI.indentLevel = 0;
    9.  
    10.         var spriteRect = new Rect(position.x + x, position.y + y, position.width, position.height);
    11.  
    12.         property.objectReferenceValue =
    13.             EditorGUI.ObjectField(spriteRect, property.objectReferenceValue, typeof(Sprite), false);
    14.  
    15.         EditorGUI.indentLevel = ident;
    16.     }
    17.  
    18.     public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
    19.     {
    20.         return base.GetPropertyHeight(property, label) + 50f;
    21.     }
    22. }
    But the sprite is not rendered properly, the field stays blank (dark color as if empty):

    Capturar.PNG

    If I scroll the Inspector, the preview image blinks inside that box...
     
    Last edited: Sep 2, 2015
    Tymianek, JoRouss and bitbiome_llc like this.
  2. edwardrowe

    edwardrowe

    Joined:
    Feb 11, 2014
    Posts:
    52
    I think you are wanting the ObjectField to be of type Texture2D instead of a Sprite.

    Just try this:
    Code (csharp):
    1.  
    2. property.objectReferenceValue = EditorGUI.ObjectField(spriteRect, property.objectReferenceValue, typeof(Texture2D), false);
    3.  
     
  3. bitbiome_llc

    bitbiome_llc

    Joined:
    Aug 3, 2015
    Posts:
    58
    Couldn't get scriptableobject sprites to draw consistently in a property drawer. The default EditorGUI.ObjectField when large enough to show the icon would randomly flicker the sprite and render it with a delay after clicking in the inspector panel.

    Between this thread and http://answers.unity3d.com/questions/377207/drawing-a-texture-in-a-custom-propertydrawer.html I finally got a working solution.

    In the end I changed the height of the ObjectField so the default icon is not drawn and use a GUIStyle to render the sprite as a background. Using this method I can mash the arrow key down through my scriptableobjects and the sprites show instantly with now weirdness in the inspector.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. [CustomPropertyDrawer(typeof(Sprite))]
    7. public class SpriteDrawer : PropertyDrawer {
    8.  
    9.     private static GUIStyle s_TempStyle = new GUIStyle();
    10.  
    11.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    12.     {                                    
    13.         var ident = EditorGUI.indentLevel;
    14.         EditorGUI.indentLevel = 0;
    15.  
    16.         Rect spriteRect;
    17.      
    18.         //create object field for the sprite
    19.         spriteRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
    20.         property.objectReferenceValue = EditorGUI.ObjectField(spriteRect, property.name, property.objectReferenceValue, typeof(Sprite), false);
    21.  
    22.         //if this is not a repain or the property is null exit now
    23.         if (Event.current.type != EventType.Repaint || property.objectReferenceValue == null)
    24.             return;
    25.  
    26.         //draw a sprite
    27.         Sprite sp = property.objectReferenceValue as Sprite;
    28.  
    29.         spriteRect.y += EditorGUIUtility.singleLineHeight+4;
    30.         spriteRect.width = 64;
    31.         spriteRect.height = 64;    
    32.         s_TempStyle.normal.background = sp.texture;
    33.         s_TempStyle.Draw(spriteRect, GUIContent.none, false, false, false, false);
    34.              
    35.         EditorGUI.indentLevel = ident;
    36.     }
    37.  
    38.     public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    39.     {
    40.         return base.GetPropertyHeight(property, label) + 70f;
    41.     }
    42. }
    43.  
     
    CodeKiwi, Tymianek, Xaegr and 2 others like this.
  4. nntgam

    nntgam

    Joined:
    Mar 9, 2019
    Posts:
    9
    Your code error if using to choose 2 image at the same time, the image is change same
     
    Tymianek and Eater_Games like this.
  5. Tymianek

    Tymianek

    Joined:
    May 16, 2015
    Posts:
    97
    Quick workaround: disable multi editing by pasting the following code on top of the OnGUI (`public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)`) method:
    Code (CSharp):
    1. if (property.serializedObject.isEditingMultipleObjects)
    2. {
    3.     GUI.Label(position, "Sprite multiediting not supported");
    4.     return;
    5. }
     
    Last edited: Feb 20, 2021