- Home /
changing camera view
I need to change the camera angles at a constant rate, not at a decreasing rate.
I'm using the code from the script manual:
// Set an off-center projection, where perspective's vanishing // point is not necessarily in the center of the screen. // // left/right/top/bottom define near plane size, i.e. // how offset are corners of camera's near plane. // Tweak the values and you can see camera's frustum change.
@script ExecuteInEditMode
var left = -0.2; var right = 0.2; var top = 0.2; var bottom = -0.2;
function LateUpdate () { var cam = camera; var m = PerspectiveOffCenter( left, right, bottom, top, cam.nearClipPlane, cam.farClipPlane ); cam.projectionMatrix = m; }
static function PerspectiveOffCenter( left : float, right : float, bottom : float, top : float, near : float, far : float ) : Matrix4x4 { var x = (2.0 near) / (right - left); var y = (2.0 near) / (top - bottom); var a = (right + left) / (right - left); var b = (top + bottom) / (top - bottom); var c = -(far + near) / (far - near); var d = -(2.0 far near) / (far - near); var e = -1.0;
var m : Matrix4x4; m[0,0] = x; m[0,1] = 0; m[0,2] = a; m[0,3] = 0; m[1,0] = 0; m[1,1] = y; m[1,2] = b; m[1,3] = 0; m[2,0] = 0; m[2,1] = 0; m[2,2] = c; m[2,3] = d; m[3,0] = 0; m[3,1] = 0; m[3,2] = e; m[3,3] = 0; return m; }
The cool thing about this code is by changing the "right" or "left", "up" or "down" variables I can make the left or right side of the camera widen. in other words I can make the right side of camera field of view 67 degrees or higher instead of the regular 60 degrees.
The only problem is this: it doesn't widen at a constant rate! its on some exponential rate thingy where if I type in .5 for right it'll widen it alot, but if I type in 1.0 it doesn't widen it as much as it did for .5. does that make sense I'll give you a made up example:
right = .2 = 30 degrees
right = .7 = 50 degrees
right = 1.2 = 60 degrees
see how I keep incrementing it by .5 (a constant rate) but the angle gets bigger at a decreasing rate.
Is there any way I can tweak the code above to make it widen the angles at a constat rate so that (for example):
right = .9 = 90 degrees
right = .1 = 10 degrees
??? please help me, this is the last hurdle in my project :)
OR, if there's not a way to tweak the code to make it widen at a constant rate:
how do I calculate the decreasing rate? if I could do that then I could reverse engineer the number of degrees I want to widen to and put that number in.
WARNING FOR C# USERS
The C# version of the PerspectiveOffCenter function in the docs is broken ! All brackets have been omitted from the calculation, yielding completely wrong results.
Answer by Cyb3rManiak · Aug 12, 2010 at 01:08 AM
If you really want a smooth FOV opening I wouldn't go changing the left and right variables directly. As you guessed it will be a pain in the butt. What those values mean is actually the X offset to each side from the center line of the camera on the near clip plane (when Z = cam.nearClipPlane). And same for the top and bottom - Y offset on the near clip plane. So to change the FOV smoothly, you will go crazy doing the trig (I just tried and gave up after tearing half of my hair on my head. I'll post a picture if you want :).
BUT, you can calculate those values easily if you have 2 FOV values as floats in your script (one for each half of the camera if calculated from the center outwards). 4 floats If you want to change the "top" and "bottom" values. From these (lets say fRightFOV and fLeftFOV) you can calculate the "right" and "left" easily:
var right: float = 0.2; var fRightFOV: float = 30.0;
function LateUpdate () { right = Mathf.Tan(fRightFOV Mathf.Deg2Rad) cam.nearClipPlane; ... ...
Now you can lerp fRightFOV any way you want.
Oh yeah... it's really late here and this is untested in Unity, so double check my math and reasoning skills :)
I'd like to see that picture, it'll probably describe how I've felt for days :) I tested your code and it looks like it works perfectly! thanks man! this is so elegant :)
No problem. I like these puzzles. And I was doing matrix and projection stuff the last couple of weeks so it was still fresh in my $$anonymous$$d.
Answer by Magnus Wolffelt · Aug 11, 2010 at 09:11 PM
I'm just guessing really, but I think Tan() has a role to play here. It feels right.. :)
Answer by Aubrey Hesselgren · Aug 24, 2010 at 03:57 PM
Just a note, but I believe this is what Halo does: your crosshair is actually below center on the screen, BUT this angle is still pointing in the same direction as the camera transform's "forward".
It's just that the "top" of the screen has been extended, without changing the angle (i.e. stare at a point with your eyes squinting [widescreen], then let your top eyelid move back to reveal more of the sky. It's like this, but less blurry :D. Wow that's a terrible example, but hopefully you get it. )
By retaining forward as "forward", you keep the weapons aiming simple, but still let the player see more of the sky (and less of your potentially low texel floors :D ).
I'm going to try this out and see if things like Camera.main.ScreenToWorldPoint still work correctly (though I think they've likely thought this stuff through and are using the camera matrix, whatever it may be, to convert the mouse pos to a world ray).
You'd still have to figure out your HUD crosshair center position (i.e. it's not just (screen_width,screen_height) * 0.5), but that's easy enough by reverse Transforming the forward vector back to screen space.