🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Camera Orbit and Position Player Problems

Started by
4 comments, last by kensarto 5 years ago

The desired result:
A camera that follows a player or object as it moves, doesn't automatically rotate with the object's own rotation. Is capable of orbiting around the player's Y axis via left and right arrow keys. Is capable of orbiting around the player's X and Z axis to produce a change from top down to side on view via the up and down arrow keys regardless of current rotation around the Y axis. Is clamped to only being able to go directly above the player or directly horizontal to the player so that the player does not become upside down or the map invisible as it is viewed from underneath. Zooming with the scroolwheel also desired.

Currently Completed : 

Rotation around Y axis


transform.RotateAround (player.transform.position, Vector3.up,2*Input.GetAxis("Horizontal"));

Following the player's position without being a child of the player (thus avoiding auto following player model rotation).


playerMoveOffset = player.position - playerPrevious; //all Vector3 variables, work out difference between player position now and previous
transform.position += playerMoveOffset; //transform belongs to camera, move camera equal to amount player moved since last update
playerPrevious = player.position; //set latest player location

The issue:

I have only managed to get the up and down motion working on a single axis at a time, rotating around the Y axis and attempting to rotate both axis at the same time to give the proper effect becomes skewed due to the difficulty in managing the different euler values, quaternions and other nonsense that one has to deal with when manipulating unity rotations.

The concept was to determine the ratio between X axis rotation and Z axis rotation needed to get a clean vertical line from any angle, then multiply the speeds of those rotations by that ratio. I came very close with the following 


var x = UnityEditor.TransformUtils.GetInspectorRotation(gameObject.transform).x + 180; // value from 0 to 360
		var y = UnityEditor.TransformUtils.GetInspectorRotation(gameObject.transform).y + 180; // value from 0 to 360
		var z = UnityEditor.TransformUtils.GetInspectorRotation(gameObject.transform).z + 180; // value from 0 to 360
		var zMod180 = z % 180; //values from 0 to 1 are positive, values form 1 to 2 are negativet
		var zMod90 	= z % 90 ; //determines % of forwards:left backwards:right

		Debug.Log (zMod90);

		transform.RotateAround (player.transform.position, Vector3.left,(90-zMod90)/90*2*Input.GetAxis("Vertical"));
		transform.RotateAround (player.transform.position, Vector3.forward,zMod90/90*2*Input.GetAxis("Vertical"));

This was my latest attempt which is incorrect. I do not have, nor would it be appropriate to post my other attempts as it constitutes hundreds of lines of failed code.
Assistance working out the final part of this camera script would be greatly appreciated.

Advertisement
Quote

I have only managed to get the up and down motion working on a single axis at a time, rotating around the Y axis and attempting to rotate both axis at the same time to give the proper effect becomes skewed due to the difficulty in managing the different euler values, quaternions and other nonsense that one has to deal with when manipulating unity rotations.

To be fair to Unity, I doubt the issues you're encountering are specific to Unity. Quaternions and Euler angles are commonly used representations, and I don't think there's anything particularly special about how Unity deals with them. I suspect the issues here are conceptual and that you'd probably encounter them outside of Unity as well.

Quote

Is capable of orbiting around the player's Y axis via left and right arrow keys. Is capable of orbiting around the player's X and Z axis to produce a change from top down to side on view via the up and down arrow keys regardless of current rotation around the Y axis.

I'm not quite sure what you mean here by orbiting around the player's X and Z axes, but I'll take a guess. It sounds like you want an 'orbital' camera that allows for rotating 'up and over' the target and back down. I searched for 'orbital camera' and found this:

https://www.youtube.com/watch?v=aZpW2wQPSD0

Aside from being able to rotate under the player, is this similar to what you have in mind?

Assuming the answer is yes, then I don't think you want to implement the 'elevation' part of the rotation by working with X and Z axes (whether world or local to the player) directly.

There are different ways you could do it, but a simple way would be to ditch the relative rotations and instead maintain a single spherical coordinate, that is, azimuth, elevation, and distance. (The angles can have different names depending on convention, for example yaw and pitch rather than azimuth and elevation.)

With this system, the controls would modify these angles directly, and then you'd compute the camera position from the player position and camera spherical coordinates as needed.

There may be other behaviors you want, such as spring-like behavior for the camera position, that might require a different approach. Regardless though, I doubt separate rotations around X and Z are what you want. (If you want to stick with relative rotations, an alternative would be for pitch rotations to occur about an axis parallel to the cross product of the world up vector and the vector between the player and the camera position. You could try this without fundamentally altering the approach you're using currently, so this might be a good starting point.)

Visually that is what I am after, however I am using keyboard controls not mouse controls for the camera so the math shown in this video isn't of much use to me. I will look up examples of Azimuth elevation and distance after i finish waking up. 

If i have no luck your last statement may have clicked a switch as to how it could work. Rather than rotating around one of the three major axis, i find the axis i need to rotate around, which will likely be much more complicated than (1,0,0) for obvious reasons. But once i find that axis, i can rotate around it in a simple fashion, no percentages needed. Just an assumably quick vector calculation.

15 minutes ago, kensarto said:

Rather than rotating around one of the three major axis, i find the axis i need to rotate around, which will likely be much more complicated than (1,0,0) for obvious reasons. But once i find that axis, i can rotate around it in a simple fashion, no percentages needed. Just an assumably quick vector calculation.

For what it's worth, it shouldn't be too complicated to compute. As I think I mentioned earlier, it should just be the normalized cross product of the world up vector and the vector between the player and the camera position. (You can change the way the cross product 'points' if you want by negating it, negating one of the cross product input vectors, or swapping the input vectors.)

Note that when the camera is more or less directly above the player, the cross product may not be normalizable due to small or zero magnitude. (An advantage of using spherical coordinates is that it would avoid this problem.)

Looked into Spherical Coordinates, found a set of classes that do exactly what I'm after. for now the thread is resolved since it is working but ill definitely need to study over this for a while until I am able to make a few changes. It currently doesnt go directly overhead and ive realised i might want to limit the camera to slightly above directly parallel so that you cant see the skybox under the world. But other than that thanks for the pointers again Zakwayda.

This topic is closed to new replies.

Advertisement