- Home /
Trying to make a 2nd camera viewport follow a GUI.Window
Ok, this is probably NOT the best way to accomplish what I am trying, but it was the only thing I could come up with.
What I am trying to do is show a Character window, as a GUI.Window. I want the character model to show in the middle of this window.
What I did, was create the window with a transparent background, then way in the middle of nowhere, I have the code clone the character model and place it on a layer I named 3DGUI. It also places a camera, Spotlight and a cube to act as a backdrop.
In the OnGUI, I am calculating the normalized viewport position for the 2nd camera so that the model and backdrop fit exactly within the window frame.
This is working just fine as long as the window stays put. The problem is when I drag the window, the 3D objects from the 2nd camera lag behind the move, and catch up when I stop moving the window.
This works, but sure doesn't look very good.
Does anyone know a way to work around this? Or possibly a better way of accomplishing the desired results?
I am using the indie version, so I don't have the option of creating a texture on the fly.
The code I am using for the viewport movement is below..
Any help would be greatly appreciated. -Larry
float x = (_CharacterWindowRect.x / Screen.width) + -.074f;
float y = (_CharacterWindowRect.y / Screen.height) * -1 + .43f;
GUICamera.rect = new Rect(x, y, .5f, .5f);
Update: Just realized that the calculated viewport position is NOT working correctly when you drag the window near the bottom, left or right edge of the screen. Dragging to the left or right edge results in the 3D portion skewing outside of the window to one direction or the other, and dragging to the bottom of the screen causes the 3D portions to shrink. This really doesn't look good :( Hoping someone has a better way of accomplishing this.
Answer by aldonaletto · Jan 08, 2012 at 01:44 PM
I suspect that you're not adjusting the viewport accordingly. I edited the DragWindow example, added a viewport adjustment code and attached the script to the second camera, and it worked fine (and without any lag!):
var wRect : Rect = Rect (20, 20, 300, 350);
function OnGUI () { // Register the window. wRect = GUI.Window (0, wRect, DoMyWindow, "My Window"); // clamp wRect to the screen: wRect.x = Mathf.Clamp(wRect.x, 0, Screen.width-wRect.width); wRect.y = Mathf.Clamp(wRect.y, 0, Screen.height-wRect.height); }
// Make the contents of the window function DoMyWindow (windowID : int) { // Make a very long rect that is 20 pixels tall. // This will make the window be resizable by the top // title bar - no matter how wide it gets. GUI.DragWindow (Rect (0,0, 10000, 20));
// viewport adjustment code:
var w = Screen.width;
var h = Screen.height;
var rect = wRect; // make a copy of the window rect...
rect.y += 20; // add the top margin...
rect.x += 10; // add the left margin...
rect.width -= 20; // adjust width to include left + right margins...
rect.height -= 30; // adjust height to include top + down margins...
// set the camera viewport size:
camera.rect = Rect(rect.x/w, (h-rect.y-rect.height)/h, rect.width/w, rect.height/h);
}
EDITED: If you just want a still image, it can be done in the indie version too: use GetPixels to get the second camera image from the screen, then disable the camera and display the window with the image acquired (2nd camera script):
var rGui = Rect(20, 20, 300, 350); // GUI window coordinates var lftMargin = 6; // margins var rgtMargin = 6; var topMargin = 20; var botMargin = 5; private var switchTime = 2; // time to acquire the image private var tex: Texture2D; private var rect: Rect; private var rTex: Rect;
function Start(){ rect.x = rGui.x + lftMargin; rect.y = Screen.height - (rGui.y + rGui.height) + botMargin; rect.width = rGui.width - (lftMargin + rgtMargin); rect.height = rGui.height - (topMargin + botMargin); camera.pixelRect = rect; tex = new Texture2D(rect.width, rect.height, TextureFormat.RGB24, false); rTex = rect; rTex.x = lftMargin; rTex.y = topMargin; }
function Update(){ if (switchTime > 0){ switchTime -= Time.deltaTime; if (switchTime
function OnGUI(){ if (switchTime
function PaintWindow (windowID : int) { GUI.DragWindow (Rect (0,0, 10000, 20)); GUI.DrawTexture(rTex, tex); }
I replaced my calculation for the viewport with your sample above, and ended up with almost identical results. Your code dealt better when dragging to one side or the other, it didnt skew outside of the window, but the 3D objects still shrunk when drug to the bottom, and I still had the same lag on the viewport.
The image shrinks when the window starts to "escape" from the screen - it's a camera feature: a viewport with offscreen portions causes this effect, and we can't change this. The solution is to clamp the window to the screen, thus the viewport will always be valid (notice that I'm already clamping the window in OnGUI).
I noticed the lag: it seems that viewport changes only take effect in the next frame; I tried to delay the window movement, but had no success. You can reduce the effect a little using wider margins, but maybe another alternative would be necessary (GUITextures, for instance).
Thanks for your help. I believe I am going to end up going with an alternative static texture with a generic silhouette. Just thought that using the actual model would look better :) But not at the expense of a laggy window :)
$$anonymous$$y first thought, before I tried the 2nd camera was to create a texture on the fly based on the model at character creation, but from what I can tell, that is not possible in the indie version. $$anonymous$$aybe I will look into it again when I end up getting the pro version.
Thanks, -Larry
If you just want a still image, you can capture it from screen with GetPixels. Take a look at my answer: I edited it to include this version - this time there's no lag, window clamping or image shrinking!
hello, i know this is a long time after the post, i used the code successfully but the window still renders on top of the viewport, and the custom mouse cursor... any idea how to fix this? yes i need it to be interactive ins$$anonymous$$d of an image that's why i don't want to use guitextures :)
Your answer