- Home /
Help re-calculating camera's viewport on UI drag (when the required area changes)?
Hello, this is a follow-up of this question.
So after I got the cutting right, I'm facing a problem where I can't re-calculate the Camera's new viewport each time I drag my panel (I'm using NGUI). I can calculate it well the first time, but every time I drag the panel around, I see its screen coords go way out of screen, and gives me "NAN". I read this and found it to be similar to my problem, but the thing is, in that solution they're using a unity GUI function which I can't use in NGUI. How can I resolve that? what's the equivalent of GUI.ScreenToGUIPoint in NGUI?
Here's my UI setup just in case you think I should approach this differently. Basically, for the item examining I have two cameras, one for the whole UI, and another just to render the weapon/3dobject inside the "ExamineArea" (which is the grey shaded background you see in the middle of my UI)
Note that, the UIDragObject script is attached to the title bar, and the target of it is the whole panel, so when the panel moves, everything inside moves.
Here's my code of calculating the viewport:
public void CalcViewport()
{
// we need to convert the bottom left point of the examine area to its normalized viewport equivalent
// first take the top left
var vPort = _camera.WorldToViewportPoint(examineArea.transform.position);
// then subtract the height
vPort.y -= examineArea.transform.localScale.y / Screen.height;
// take the dims along the way
var dims = new Dimension2D(examineArea.transform.localScale.x / Screen.width, examineArea.transform.localScale.y / Screen.height);
// set our new screen viewport rect
_camera.rect = new Rect(vPort.x, vPort.y, dims.x, dims.y);
}
I also tried converting first from world to screen point, subtracting the height and then to viewport, but also had problems with that... I also tried pixelRect.
To recap one last time: I'm trying to re-calculate my viewing camera's viewport everytime I drag my UI panel, I can't seem to get it right, any help would be appreciated. Thanks.
Why are you dividing the local scale by screen width or height? Should that have been position?
Because I need to add it in its normalized form (0 -> 1), remember I'm adding it to the vPort, which is the normalized viewport of the cam.
To get the normalized size of exa$$anonymous$$eArea on screen, you need to divide its on-screen height by Screen.height.
Because you are using localScale, it means you (should) have a 1 pixel high semi-transparent plane (background_exa$$anonymous$$eArea) that you just scale to be the appropriate size on screen. If it's unscaled ( scale vector 1,1,1 ) then exa$$anonymous$$eArea.transform.localScale.y / Screen.height;
will return ~0.001.
Is that the code you use to calculate the View Port for the first time?
the exa$$anonymous$$e area is scaled to about 400 y. so its local scale is actually its height. right? the depth of the background is 1 (localScale.z == 1)
And yes, that is the code I used to calculate the vp the "first" time, it worked...
Answer by vexe · Aug 20, 2013 at 05:14 PM
SOLVED IT! :)))
@Jamora: You were right! Everything I had was all wrong! But, I wasn't wrong when I said it worked to some extent, no idea why :D
First and foremost, the NaN problem I was getting, was due to the fact that I was calculating the examineArea position from the examineCamera, which is a child to the area, this was fixed by using the main gui cam, for the whole Examine gui setup (above the anchor object)
Now that I'm getting the examineArea coords working, here's how I setup the examineCamera rect viewport:
public void UpdateViewport()
{
// take the examine area's bounds (which will give us the coords of min/max in world pos)
var examineBounds = NGUIMath.CalculateAbsoluteWidgetBounds(examineArea);
// our viewport will start from min, going up/right by size
var vPort = ExamineManager.guiCamera.WorldToViewportPoint(examineBounds.min);
// we need to get the width/height of the examine area in screen coords
// so that we can know the width/height of our vp rect
var examineScreenMax = ExamineManager.guiCamera.WorldToScreenPoint(examineBounds.max);
var examineScreenMin = ExamineManager.guiCamera.WorldToScreenPoint(examineBounds.min);
var dims = new Dimension2D( (examineScreenMax.x - examineScreenMin.x) / Screen.width,
(examineScreenMax.y - examineScreenMin.y) / Screen.height);
_camera.rect = new Rect(vPort.x, vPort.y, dims.x, dims.y);
}
Notice that ExamineManager.guiCamera is the gui cam I just mentioned (above the anchor), and _camera is the examineCamera, that just renders the object to be examined, this is the cam that we want to set its viewport.
Note that you don't really need NGUI to calculate the min/max of the examineArea, I just used it for convenience.
Note that if you stick the window to the sides, the vp changes accordingly, thus scaling nicely.
I hope this script will be useful for someone in the future trying to do something similar, with it you can have a cam's viewport follow a certain window/on-screen object. Thanks for anybody who tried to help :)
Your answer
Follow this Question
Related Questions
Camera Viewport Height - Horizontal Transition 0 Answers
Help with repositioning object to a random position in the FOV 1 Answer
Camera movement in a Third Person Shooter Game 2 Answers
How to resize a camera's orthoSize for an object to fit inside its rect viewport? 1 Answer
Adjust Viewport Locations When Going to Full Screen -1 Answers