Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    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:
    94
    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