- Home /
[SOLVED] Third Person Spherically Orbiting Camera
Hi, everyone. So I'm on a quest to make my own third person controller, but I've hit a bit of a wall with the camera.
This is how the camera will work:
Update/Fixed Update()
//Camera position = Player Position + Camera Offset Value
//Point towards player
So that should work in theory, but the reason I'm structuring it this way is so that in order to adjust the camera to whatever position I want, I simply adjust the offset position of the camera rather than the camera itself via the right stick or another special move. The code in Update/Fixed Update will simply correct the camera's position in the next frame.
Here's the issue. How do I adjust the offset value so that it curves around the player?
I want the camera to receive a 2d direction (being up,down,left,right) and a magnitude then be able to do some math and figure out how to adjust the offset while spherically curving around the player.
Thanks for your time!
Answer by AlwaysSunny · Dec 27, 2016 at 04:05 AM
Don't forget to format your code with the 1010101 button.
There are many strategies for creating the type of camera behavior you're asking for.
I would recommend a strategy which uses the rotation of a dummy object to help you find the best position for the camera. Then the camera will seek this dummy object's position. All this can be done mathematically without dummy objects too, but building logical rigs of objects is often a helpful strategy.
Depending on what you want, you may need to change several things about the approach, but this should get you started:
Create your camera rig (empty game object) and use a script to make it copy the player's position each frame. (It shouldn't be a child of the player, unless you want the behavior that comes with that decision).
Use input to control the rotation of this dummy object. Give this dummy object a child and offset it from the parent some desired distance. This child object is what your camera script will seek towards, trying to occupy its position. The camera script also looks at the player.
This is the least sophisticated version of this approach, but it's a good foundation to build from.
Thank you so much for that quick response! That solution is genius! I'm going to try and plug that in as soon as I can. I'll let you know if I stumble upon any $$anonymous$$or issues. Then I'll mark this case closed.
I do have one question though: What were you referring to when you mentioned formatting with the 1010101 button?
In your case they were short snippets so that's fine, but for multi-line code with different indentation levels, you should always paste the code, highlight it, and click the 101010 button in the web form toolbar. That'll format it like so:
This is some code
Glad to help - I remember first grasping the power of this concept. It's a useful approach for solving many kinds of problems! Best,
Got it. Yeah I just noticed that 10101 button.
Woops
So seems like I'm good to go. The only problem I'm having is figuring a good way to constrain the rotations so that the player can't look too far overhead or too far below the character. I built the camera system exactly as you said.
I tried something like:
if (transform.eulerAngles.x > maxHeight)
{
transform.rotation = new Quaternion(maxHeight,transform.rotation.y,transform.rotation.z,transform.rotation.w);
}
if (transform.eulerAngles.x < $$anonymous$$Height)
{
transform.rotation = new Quaternion($$anonymous$$Height,transform.rotation.y,transform.rotation.z,transform.rotation.w);
}
But to no such luck. Seems I have a problem.
The rotation of the main empty camera rig (the one glued to the player but not childed) gets very skewed to the point where I can't rely on a single rotation value (by rotation value I mean x,y,z,w I don't know what you would call those individually) to measure a $$anonymous$$ and max value for the camera.
So, how should I measure a $$anonymous$$ and max height for the camera system?
In response to latest post - it only lets you "reply" so deep...
You did your own debugging + research - I wish all newbies were just like you! :)
You are - perhaps for the first time - encountering the shortco$$anonymous$$gs of Euler representation. This phenomenon (often called "gimbal lock" although technically that's something more specific) is why Quaternions are used internally for processing rotations.
The gist is this: Unless you also $$anonymous$$ch it how, almost anything dealing with Euler angles in Unity doesn't care about the sign of angles, and doesn't consider angles greater than 180 degrees or less than zero degrees.
It requires some mental gymnastics every time this comes up, but there is always a relatively painless way to overcome this quirk. Eventually you'll appreciate the elegance of the workarounds more than the lost convenience of Euler, though I must admit it will take some time.
The Quaternion class offers several mathematical operations and methods which help programmers overcome their un-intuitive nature. Have a glance over their API reference to get an idea. Unless you know precisely what you're doing, you shouldn't mess with the components (.x .y .z .w) of a Quaternion - they don't mean anything automatically useful to a human brain.
For that reason, it's frequently more intuitive to convert them to Euler angles, perform human-friendly math on those angles, then convert those Euler angles back into Quaternion space (which is what we just did). But you will definitely run into this situation again down the road, where that procedure creates a similar problem. Next time you'll recognize it right away.
The first thing to try is avoiding the problem. Outside of playmode in the editor, detatch the grandchild camera target from the hinge. Rotate the hinge 90 degrees along X, then re-attach the grandchild. Change the $$anonymous$$ / max angles to values between greater-than-zero and less-than-180.
I recommend putting the camera target grandchild at a local position such as ( 0, 0, 10 ) so the line between the camera target's "resting position" and its parent is parallel to the floor.
We do all this to make the "halfway point" through your envelope also be the halfway point through the Euler representation's useful range. (So with the hinge at 90 degrees, the camera will be "straight out" and looking at the player straight on, you'll have 90 degrees of freedom up or down without worrying about gimbal lock.)
If this works for your situation, perfect! (I think it should.) If not, we'll try opening that can o' worms, but beyond here there be dragons.
Took some tuning but I finally got it! Works smooth and everything is seamless! No jitters or anything!
I'm gonna have to call this long conversation a success! $$anonymous$$y next goal is to get a bit of a deacceleration with the camera movements so it doesn't whip around so quickly and some motion blur.
After all your help it's hard for me to let you go :c You've proven to extremely helpful! Thanks for everything! This won't be my last question so I'll see you around!
Your answer
Follow this Question
Related Questions
FPS cam for Roll -a-Ball like game 1 Answer
How to move camera position to player object's direction while having looking at object? 0 Answers
How to make a camera Follow an Object moving in zigzag path? 1 Answer
Rotate camera diagonally over object 0 Answers
How to change the focus of the camera? 0 Answers