Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am trying to highlight a rectangle of arbitrary height. I thought the easiest way to do this would be to create a separate "box" gameobject that outlines the rectangle.

I've tried with both a MeshRenderer + Transparent Texture, and a LineRenderer to outline the four points of the rectangle. Neither are very satisfactory.

enter image description here

(Line renderer on in the middle, scaled cube on the right)

What's the right way to go about this? I am trying to get something like the left rectangle - a simple perimeter of fixed width through four points of my choosing.

share|improve this question

3 Answers 3

up vote 3 down vote accepted

Use GUI.Box().

If you only need a 2D rectangle, GUI is the way to go. Create a new GUIStyle using a simple rectangle as a texture (the inside of the rectangle should be transparent, of course), set up its Border value so that it is not stretched, and call GUI.Box(new Rect(...),"",myGuiStyle);.

You can use Camera.WorldToScreenPoint method if you want to outline something in world coordinates (i.e. 3D), just remember that in Unity's world coordinates y goes from bottom to top, and in GUI y goes from top to bottom.

Code Example:

void OnGUI()
{
    //top left point of rectangle
    Vector3 boxPosHiLeftWorld = new Vector3(0.5f, 12, 0);
    //bottom right point of rectangle
    Vector3 boxPosLowRightWorld = new Vector3(1.5f, 0, 0);

    Vector3 boxPosHiLeftCamera = Camera.main.WorldToScreenPoint(boxPosHiLeftWorld);
    Vector3 boxPosLowRightCamera = Camera.main.WorldToScreenPoint(boxPosLowRightWorld);

    float width = boxPosHiLeftCamera.x - boxPosLowRightCamera.x;
    float height = boxPosHiLeftCamera.y - boxPosLowRightCamera.y;


     GUI.Box(new Rect(boxPosHiLeftCamera.x, Screen.Height - boxPosHiLeftCamera.y, width, height),"", highlightBox);
}
share|improve this answer
    
Unless I'm mistaken, GUI.Box() will always be drawn on top of any objects in the scene? Is it possible to have a GUI element behind or partially behind a gameobject? –  Raven Dreamer Feb 5 '13 at 14:13
    
Yes, GUI is always drawn after other objects. There's a hack that you can use to render a separate camera on top of GUI, but it's kinda unwieldy. –  Nevermind Feb 5 '13 at 18:25
    
This answer got me what I needed, but I'm keeping it open for now in the hope that there's a better way to do this in the general case. –  Raven Dreamer Feb 6 '13 at 2:28
    
I accepted your edit adding code sample, and fixed the GUI-y-upside-down bug in it. –  Nevermind Feb 6 '13 at 4:53

A simple way is to use a Shader with two Passes: the first Pass uses the vertex shader to scale up the object a bit and uses the pixel shader to color it to a solid color matching to the color you want the outline to have, and then the second Pass does the regular rendering.

share|improve this answer
    
Could you give a code example to better explain what you mean? –  Raven Dreamer Feb 6 '13 at 14:13
    
This would only work for convex objects ( like a rectangle ) whose origin is at it's geometric center. –  rootlocus Feb 6 '13 at 14:40

Below is a non-shader approach.

Think of your 2d box as nothing more than four lines, where each line is stretched in only one dimension (the other two dimensions are the cross-section of the edge). This is much like if you were to construct a box in real-life, where you are piecing together variable lengths of wood that all have the same cross-section size.

With that in mind, you can devise a Component, say BoxBuilder, which when attached to a GameObject, creates and manages four child GameObjects. Each child game object is one of your box edges, and can simply be a 3d cube that is stretched in only one dimension. With a width and height defined BoxBuilder level, you can calculate the necessary positioning and non-uniform scale of the four child edges. It will be a lot of pos.x=w/2, pos.y=h/2, ..., scale.x=h, scale.y=w, etc. sort of code.

Though I believe you're asking for 2-d only, note that this same idea can be applied to 3d boxes if needed, where the BoxBuilder now must create and manage 12 child edges, but again only scaling each edge in one local dimension.

share|improve this answer
    
Workable, but WAY too complicated. –  Nevermind Feb 5 '13 at 10:36
    
If I had to do it this way, I'd simply use 4 line renderers... –  Raven Dreamer Feb 6 '13 at 2:35
    
This does properly handle depth however. –  DuckMaestro Feb 6 '13 at 9:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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