Draw a simple rectangle filled with a color

We can draw labels with a texture inside, but how to draw a rectangle (label) with just a color in it?

  1. Create a new Texture2D(1,1)
  2. Fill it with the desired color ( SetPixel )
  3. Set it’s wrap mode to repeat
  4. Use Texture2D.Apply() to apply the changes
  5. Create a GUIStyle
  6. Set it’s .normal background texture to the texture you just created

Thanks, that´s what I do so far, thought there must be an easier way!

This is pretty efficient. No need for anything else.

1 Like

function OnGUI () {
GUI.Label (Rect (25, 25, 100, 30), color);
}

would be muuuuuch easier :smile:

It’s how it should look
GUI.Label(Rect(25, 25, 100, 30), style);
Simple as that.

Make sure to initialize the texture2d and the style just once, otherwise your garbage collection will go crazy and cause spikes.

Ok, thanks, what I don´t like is filling up a texture and blowing it up just to render some pixels on screen -especially when the color is changing often in runtime.
No problem if there´s no other way!

1 Like

I found this code in another thread and it helped me doing this easy:

void DrawQuad(Rect position, Color color) {
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0,0,color);
texture.Apply();
GUI.skin.box.normal.background = texture;
GUI.Box(position, GUIContent.none);
}

I hope it helps others as well.

6 Likes

Awesome! that code really worked for me. Thanks kblood.

1 Like

kblood’s code is horrible and will cause your game to break. Do not use it. Read the warning from jedy two messages up: initializing a new Texture2D object in every OnGUI call (i.e. every frame) will be a huge memory problem. Additionally, there’s no reason to set “GUI.skin.box.normal.background” - this is changing the look of a default skin and can affect how other GUIs appear.

As an aside, I don’t understand why this is so hard to do in Unity’s own GUI tools - why aren’t there simple DrawRect, DrawLine, DrawCircle, etc. functions? It’s very odd to me.

Here is code that works and doesn’t chew through memory indefinitely:

	private static Texture2D _staticRectTexture;
	private static GUIStyle _staticRectStyle;

	// Note that this function is only meant to be called from OnGUI() functions.
	public static void GUIDrawRect( Rect position, Color color ) 
	{
		if( _staticRectTexture == null )
		{
			_staticRectTexture = new Texture2D( 1, 1 );
		}

		if( _staticRectStyle == null )
		{
			_staticRectStyle = new GUIStyle();
		}

		_staticRectTexture.SetPixel( 0, 0, color );
		_staticRectTexture.Apply();

		_staticRectStyle.normal.background = _staticRectTexture;

		GUI.Box( position, GUIContent.none, _staticRectStyle );


	}
6 Likes

Thanks for sharing, I’m new to Unity and was looking for some tutorials on simple 2D app creation.

I find it interesting that unlike other IDEs, adding a button/box/text/etc… seems a little more complex in Unity. Maybe I am missing a toolbar or something.

Let me know if you can help.

As an example, in my signature I show an app (PopQuiz!) I created with Visual Studio for WIndows 8. Creating an app like this for Unity is my goal, so I can transfer it to other platforms easily.

Thanks very much IQpierce, just what I needed.

Be careful Texture2D texture = new Texture2D(1, 1); will eating your memory :slight_smile:

No need to update the texture all the time. Just set the texture pixel to white (once, when creating it) and set the GUI.color before drawing the box. (You should also save the original GUI color and restore it after drawing the box.)

1 Like

Why there isn’t an option of (new Rect (x,y,w,h),colour) is beyond me.

The code given in this thread isn’t terribly efficent. This is what I use:

public static class EditorGUITools
{

    private static readonly Texture2D backgroundTexture = Texture2D.whiteTexture;
    private static readonly GUIStyle textureStyle = new GUIStyle {normal = new GUIStyleState { background = backgroundTexture } };

    public static void DrawRect(Rect position, Color color, GUIContent content = null)
    {
        var backgroundColor = GUI.backgroundColor;
        GUI.backgroundColor = color;
        GUI.Box(position, content ?? GUIContent.none, textureStyle);
        GUI.backgroundColor = backgroundColor;
    }

    public static void LayoutBox(Color color, GUIContent content = null)
    {
        var backgroundColor = GUI.backgroundColor;
        GUI.backgroundColor = color;
        GUILayout.Box(content ?? GUIContent.none, textureStyle);
        GUI.backgroundColor = backgroundColor;
    }
}
10 Likes

Cameron860

is

 private static readonly Texture2D backgroundTexture = Texture2D.whiteTexture;

possible at runtime? I tried it but the “texture” is being transparent/invisible as if it does not present. Variant with initializing new texture at Start/Awake works fine ofc:

public void Awake()
{
        if(drawTexture == null )
        {
            drawTexture  = new Texture2D( 1, 1 );
           drawTexture.SetPixel( 0, 0, color );
           drawTexture.Apply();
        }
}

Works like a charm! Thank you so much!

First off that was just rude. With that aside, it would be better to define the texture at the beginning in an awake or start function. Here’s how I would do it:

    private static Texture2D _staticRectTexture;
    private static GUIStyle _staticRectStyle;
   
    void Awake(){
           _staticRectTexture = new Texture2D( 1, 1 );
           _staticRectStyle = new GUIStyle();
    }

    public static void GUIDrawRect( Rect position, Color color )
    {

        _staticRectTexture.SetPixel( 0, 0, color );
        _staticRectTexture.Apply();

        _staticRectStyle.normal.background = _staticRectTexture;

        GUI.Box( position, GUIContent.none, _staticRectStyle );

    }
2 Likes

I don’t understand why he is being rude. He is clearly right. The code was horrible and people liked it.

And your code implies to work in a MonoBehaviour, clearly not much better.

3 Likes