Get the FULL version

Unity3D: Creating a GUI with both 3D and 2D elements

Unity3D: Creating a GUI with both 3D and 2D elements thumbnail

This post explains how to create a GUI on the Unity3D game engine that has both 2D and 3D elements in it. Some may say that is just a matter of setting up a new camera with a dedicated culling mask just to render the 3D elements on the GUI. While this is partially true, adding a 2D image using a script with GUI function calls will cause the 3D image to be covered by the 2D image. That’s why this post will focus on how to set a GUI that has a 3D element with a 2D background.

As usual, at the end of the post, a Unity3D project is available for download with everything that was explained here.

Before setting up any additional camera, it is necessary to place the 3D model we want to display in the GUI at a place the player cannot reach. A good candidate is below the terrain. So, after placing the 3D model at such position, select this object, and, in its inspector, click on the Layer dropdown menu, then select Add Layer. Choose an empty layer slot and type “3D GUI” in it. Select the same object again and set its layer to the 3D GUI layer:

Creating the 3D layer Image.

After creating the layer, add the 3D model to it.

The next step is to select the main camera at the Hierarchy tab, and set it’s Culling Mask to every layer except the 3D GUI layer:

Setting the main camera culling mask image

Unmark the '3D GUI' layer.

Take note of the Depth property value. You are going to need to remember it in the following step. Now, it’s time to create the dedicated camera that will render only the 3D GUI elements. Create a new camera by going to GameObject -> Create Other -> Camera. After it appears on the Hierarchy tab, give it the name of “3DGUICamera“. Place the camera in such manner that it renders the 3D model that you want to appear on the GUI. Delete all of the three standard components that already comes attached to the camera: the Audio Listener, Flare Layer and the GUI Layer. Still in this camera’s Inspector, adjust the following settings:

  • Change the Projection to Orthographic (leave as Perspective if the depth of the 3D models in the GUI matter).
  • Set the Size of the projection to 1.
  • If possible, reduce the value of the Far clipping plane distance.
  • Set the Depth to a value greater than the one from the Main Camera.
  • At the Normalized View Port Rect parameter, set both W and H values between 0,1 and 0,3. It depends on how large you want the 3D model to appear on the GUI.
  • Change the X and Y to position the 3D GUI model on the screen.
  • Set the Clear Flags to Depth Only.

Here’s a image of this camera’s Inspector tab, after all settings have been changed:

3D Camera Settings Image.

The arrows indicate which values have to be changed.

You should see the 3D model in the screen at this point. Now that you already have both cameras set up, it’s time to add the 2D elements to the 3D GUI. Let’s say that we wanted to add a 2D background, like a container for the 3D object. Normally, we would write a script to add this element, although, in this case, it wouldn’t work, since everything that is inside a OnGUI() method call clears the camera, whatever its depth.

The only way to add a 2D background to the 3D model is with a GUI Texture game object. Before creating it, import a image file you want to use as the background. Then, in the Project tab, set the Texture Type to GUI and hit apply:

Importing the 2D Background Image

Set the 'Texture Type' to 'GUI' and click on 'Apply'.

In this step, we are going to create a GUI Texture game object by going to GameObject -> Create Other -> GUI Texture. Click on this recently created object in the Hierarchy tab and name it “Background“. Place it as a child of the 3DGUICamera object. Now, at the Inspector, expand the Pixel Inset menu and set the texture to be the recently added image file and change the Width and Height values to match the ones from the image. Than set the X and Y values to place the background image behind the 3D model, like this:

Positioning the 2D background  Image

Change these values to position the 2D background behind the 3D model. Don't forget to insert the Width and Height values.

The last thing to do is to add the GUI Texture game object as a child of the 3DGUICamera. And that’s it for the 2D background. To add an image in front of the 3D model, just create a GUI script like usual (creating a script and adding code to the OnGUI() method) and attach it to the Main Camera. This will make the image to be rendered on top of the 3D model, as explained, it works because the OnGUI() method call clears the screen, whatever the camera depth is.

For this project, I’m using a simple GUI script that displays the number of collected boxes:

public class ItemCounter: MonoBehaviour 
{
	void OnGUI()
	{
		//draw text using black color
		GUI.color = Color.black;
		//Display the number of collected items
		GUI.Label(new Rect(87,548,258,89),"X   "+Item.numberOfItems.ToString());
	}
}

As promised on the beginning of the post, here’s a Unity3D project with a scene that has everything set up and the source code of the GUI, both in C# and JavaScript. Remember to run this project at the Standalone resolution (800×600), because the GUI elements don’t resize according to the screen resolution (explaining how to do it goes beyond the scope of this tutorial):

11 Comments to “Unity3D: Creating a GUI with both 3D and 2D elements”

  1. thevoid says:

    Excelent, thanks a lot

  2. altare says:

    This doesn’t work as intended for unity free version (3.4) so don’t waste your time trying to use it.
    Perhaps you could have added this fact to the top of the page.

    • DimasTheDriver says:

      I have just downloaded and installed Unity 3.4 (free) and upgraded the project.
      It still works normally, like it did in previous versions. Maybe you are forgetting to set the game resolution to 800×600?

  3. Fabio says:

    Very interesting, I am trying to setup a dashboard for my car, I would like to include shadows for the dashboard. I did set the 3dGuiCamera as child of the car, the same for the dashboard but it does not take in to account the dashboard shadows. Actually I can see them in the scene view but not in the game view…Any help will be appreciated.

  4. judo says:

    Excellent

  5. Elezor says:

    Hey,
    Thanks a lot.~

  6. KK says:

    Thanks for your great effort for this article,
    but I was wondering if it can be tweaked to work for any elements using UnityGUI? such as placing a mesh on top of GUI.Label ?
    because our GUI system has already been done, but it’s all in UnityGUI
    if we’re going to change everything to GUITexture it would be a lot of effort

    Hope you could guide me some workarounds, Much appreciated!! Thanks :)

  7. Marko says:

    Is there a way to show GUI object and item counter only when you pick up the item?

  8. Oh my goodness! Incredible article dude! Thank you
    so much, However I am encountering issues with your RSS.

    I don’t understand why I am unable to join it. Is
    there anybody getting the same RSS problems? Anyone who knows the solution can you kindly
    respond? Thanks!!

Leave a Comment

Post Comments RSS