In this project I’m trying to make a gravity system similar to Super Mario Galaxy, and to do so I have an object following the player (the ball that’s rolling) and orients itself according to the normals of the land below to add gravity in the right direction. The problem is that the camera follows this object, and due to the direction of some normals, it will flip 180 degrees and face the wrong direction (Hard to explain but you can see it on the third side of the cube in the gif).
How could I rotate the object so that the ‘up’ direction is always matches the normals, but the other axes don’t rotate? Or if there is another way to go about this?
mistylongamericancrow
I don’t understand your picture, but going by what you wrote…
That’s not entirely a well-defined goal. Technically speaking, every rotation you apply to the object changes the direction of at least 2 of its 3 axes. For example, if you are walking forward over a spherical horizon and you rotate “downward” to keep your up axis pointing away from the center of mass, then your forward axis is also rotating to remain parallel with the ground. You can’t keep both of the other axes stable while just rotating Y.
I think you probably mean something like: you want to make the smallest possible rotation that aligns your “up” axis correctly. But that’s still not quite a complete specification. Suppose you need to flip entirely upside-down; you can achieve that by rotating 180 degrees in any direction–forward, backward, left, right, or any combination. “Smallest” is not a unique answer.
If you actually fire up Super Mario Galaxy and try walking from one “pole” of a planet to the opposite “pole”, I believe you’ll find your camera ends up in a different state depending on which direction you walked to get there.
(Worth noting that Mario Galaxy also has several areas where the camera goes to a fixed position or applies some other special logic that appears to have been defined by-hand as part of creating the level, rather than following a general algorithmic rule.)
But I think what you want to do for the standard case is:
-
Make sure that the camera never has to rotate 180 degrees or more in a single frame
-
Always do a relative rotation from the current orientation; never “start from scratch” (unless you really want to reset the camera ignoring your history up to the current point)
-
Calculate the actual rotation to perform using Quaternion.FromToRotation, to move your current “up” direction to the new desired “up” direction
1 Like
Thanks for the response! I ended up getting it to work. I was using LookRotation instead of FromToRotation to point ‘up’. I haven’t worked in 3D for years so I didn’t know about that.
Fair point about the axes as well, that’s true. But this is a lot of useful information I’ll keep in mind. Thanks for the help.