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

Custom Material Editors: How can i do this (picture)

Discussion in 'Immediate Mode GUI (IMGUI)' started by Nanako, May 11, 2015.

  1. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Hi all. I'm presently modifying (a copy of) the StandardShaderGUI, while making my own shader that extends Standard.

    What I need to do is have four colour pickers arranged in a sort-of neat fashion. My current idea is something like this:




    I'm looking at the way this is done internally, it uses this function:
    http://docs.unity3d.com/ScriptReference/MaterialEditor.TexturePropertySingleLine.html

    Unfortunately it seems to support a maximum of two extra properties, eg; colour pickers. But i need four.

    Any idea how i might accomplish this? Or any ideas on a different layout which would look okay?
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,228
    Hi,

    You should be able to do this. Are you creating a custom editor for your shader? Look at EditorGUI.ColorField to add in your color pickers.

    K
     
  3. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Not creating exactly, i'm only trying to modify the StandardShaderGUI. I'm a litle new to GUI coding, i need a little more information. That function on its own (with a new Rect()) doesn't seem to produce a result that i can see. I'm guessing the position is the issue there ? But i've no idea which rectangle or context it should be placed in.

    The function that the code is already using (linked in my OP) does not take any placement information at all, and seems to slot things into a predefined layout. how am i supposed to build ontop of that?
     
    Last edited: May 12, 2015
  4. blizzy

    blizzy

    Joined:
    Apr 27, 2014
    Posts:
    775
    You will want to use EditorGUILayout.ColorField() instead because it meshes well with legacy GUI layouts, such as GUILayout.BeginHorizontal(). Using EditorGUI.ColorField() doesn't seem to be a good idea in custom inspectors.
     
  5. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Are you saying that this is a legacy layout? This is the custom shader GUI that came with unity 5, its about as new as we can get surely? D:
     
  6. blizzy

    blizzy

    Joined:
    Apr 27, 2014
    Posts:
    775
    It's a standard Editor, and yes, Editor.OnInspectorGUI() uses the legacy GUI.
     
  7. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,649
    The way that MaterialEditor.TexturePropertySingleLine works is something like this:

    Code (csharp):
    1.  
    2. public Rect TexturePropertySingleLine (GUIContent label, MaterialProperty textureProp, MaterialProperty extraProperty1, MaterialProperty extraProperty2)
    3.     {
    4.         Rect r = GetControlRectForSingleLine();
    5.         TexturePropertyMiniThumbnail (r, textureProp, label.text, label.tooltip);
    6.  
    7.         if (no extra properties)
    8.             return r;
    9.  
    10.         if (one extra property)
    11.         {
    12.             get appropriate sub rectangle of 'r' for drawing the one property
    13.             draw the property into it
    14.         }
    15.         else
    16.         {
    17.             get appropriate sub rectangles of 'r' considering that there needs to be space for two properties
    18.             draw property one
    19.             draw property two
    20.         }
    21.         return r;
    22.     }
    23.  
    The simplest thing for you to do is probably going to be to call TexturePropertySingleLine with no additional properties, but then to make use of the rectangle it returns: calculate appropriate sub-rectangles for each of your colour properties, then call ShaderProperty(Rect, MaterialProperty, string) with an empty label for each of your four colour slots.
     
    Nanako and blizzy like this.
  8. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,649
    Also, I'm going to move this to a different forum, as the Unity UI forum is intended for the new runtime UI rather than editor customisation stuff.
     
  9. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    This sounded pretty helpful, but TexturePropertySingleLine returns void, not Rect, in all variants listed in the reference. and it seems to be likewise in code. that control rect function looks interesting though

    Edit: Nope, it doesn't exist. Back to square 1.

    Other than getting there by trial and error, im pretty stuck as to how to position these colour pickers :(
     
    Last edited: May 12, 2015
  10. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,649
    Oh, damn, sorry - it's changed from void to Rect in an upcoming release (5.1, I think).

    Still, the approach you can use is similar. Call EditorGUILayout.GetControlRect() to reserve a chunk of space in the Inspector; that's all that GetControlRectForSingleLine() does, albeit with a predefined value for the height of the rectangle - try a value around 18 for height to match the built-in controls. Then you can divide up that rectangle into smaller pieces and draw individual controls into each piece.
     
    Nanako likes this.
  11. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Victory ^___^
    Thank you superpig



    I achieved this using the following code
    Code (CSharp):
    1.  
    2.   void DoColorMaskArea()
    3.   {
    4.   //ColorMask Block Here
    5.   Rect a = EditorGUILayout.GetControlRect();
    6.   m_MaterialEditor.TexturePropertyMiniThumbnail(a, maskMap, Styles.maskText.text, Styles.maskText.tooltip);
    7.   a.x += ColorIndent;
    8.   a.width = ColorWidth;
    9.   color1.colorValue = EditorGUI.ColorField(a, color1.colorValue);
    10.   a.x += (ColorWidth + ColorSpacing);
    11.   color2.colorValue = EditorGUI.ColorField(a, color2.colorValue);
    12.   a.x += (ColorWidth + ColorSpacing);
    13.   color3.colorValue = EditorGUI.ColorField(a, color3.colorValue);
    14.   a.x += (ColorWidth + ColorSpacing);
    15.   color4.colorValue = EditorGUI.ColorField(a, color4.colorValue);
    16.   //Color Mask Block Ends
    17.   }
    18.  
    The variable values that are relevant here are

    Code (CSharp):
    1.     float ColorSpacing = 12f;
    2.     float ColorIndent = 221f;
    3.     float ColorWidth = 50f;
    I had to figure those out with trial and error. Height was auto set (by the way it was 16, not 18)
     
    Last edited: May 12, 2015
    superpig likes this.
  12. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    @superpig, @Nanako I would like to know if it's possible to create the TexturePropertySingleLine behaviour in a classic inspector editor script instead of a material editor.