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. 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 the3D GUI layer: 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: 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’sInspector, 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: 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: 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 toGameObject -> 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 3DGUICameraobject. 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: 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 the3DGUICamera. 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 theOnGUI() 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 post)
|