3D GUI Question

Is it possible to add 3D GUI objects instead of 2D textures? If so can anyone help me with that? It seems after following some tutorials and such it gives me only 2D appearances, is that because its in the GUI or in my code itself.

Thanks

What you can do is use render to texture (Pro only) to render off-camera 3D objects to a texture and display that in the GUI. With this approach, however, you would need to handle mouse position remapping on your own.

Alternatively you could attach 3D objects to the camera object - in order to have them move with the camera - giving the illusion of being GUI. With this approach you get MonoBehaviour mouse events, but you need to deal with those objects potentially colliding with the environment (or use Physics.IgnoreCollision to avoid that).

In any version of Unity, by using Camera.Render(), you can draw any camera at any time - including right in the middle of your OnGUI() function, like this:

function Start()
{
  camera.enabled = false; // We don't want this camera drawing normally
  camera.clearFlags = CameraClearFlags.Depth; // Transparent where no objects
}

function OnGUI()
{
  GUILayout.Label("There are 3D objects on top of this!");
  if (Event.current.type == EventType.Repaint)
    camera.Render(); // We want it drawing NOW
  GUILayout.Label("There are 3D objects beneath this!");
}

Of course, you don't need to do the GUI in the OnGUI of the same object as the camera.

For the GUI objects, you will need to have a "GUI" layer, put the GUI objects on that layer and set the GUI camera's Culling Mask to just render that layer, and your normal scene camera to exclude that layer. Similarly for lights for the GUI and normal scene.

Here is an entire script as used in a game of mine:

// GUICamera.js

function Start()
{
	camera.enabled = false;
}

function Layout(width : int, height : int, style : GUIStyle)
{
	var area : Rect;
	if (style) {
		GUILayout.Box("",style,GUILayout.MinWidth(width+style.padding.horizontal),GUILayout.MinHeight(height+style.padding.vertical));
		if (Event.current.type == EventType.Repaint)
			area = GUILayoutUtility.GetLastRect();
	} else {
		area = GUILayoutUtility.GetRect(width,height);
	}
	if (Event.current.type == EventType.Repaint) {
		var x = area.x;
		var y = area.y;
		if (style) {
			x += style.padding.left;
			y += style.padding.top;
			width = area.width-style.padding.horizontal;
			height = area.height-style.padding.vertical;
		}
    	var sMin = GUIUtility.GUIToScreenPoint(Vector2(x,y));
    	var sMax = GUIUtility.GUIToScreenPoint(Vector2(x+width,y+height));
	    camera.pixelRect = Rect.MinMaxRect(sMin.x,Screen.height-sMax.y,sMax.x,Screen.height-sMin.y);
	    camera.Render();
	}
	// could do mouse clicks etc. here...
}

Given one of these components, you just use it like a regular GUILayout function:

var uicam : GUICamera;
...
uicam = GetComponent.<GUICamera>();
...
uicam.Layout(100,100,"Box"); // size and style

UnityGUI is 2d only, however, you can achieve similiar effects to 3d with planes in front of your camera, if you don't want multiplayer, or by making 2d images that look 3d.