I've been trying to build gravity around spheres for a bit and while I mostly have it working, I can't get the rotation to work quite how I want. My current code works fine for the force of the gravity, and mostly handles the rotation, except that the look rotation is always facing the poles of the planet, so if you move around the hemispheres, the players local Y axis spins in a way that doesn't make sense for gravity. Does anyone know how I can solve this? Here's my current code being run on the planet: Code (CSharp): Vector3 downward = (thisTransform.position - target.Body.position).normalized; target.Body.AddForce(downward * Gravity * target.Body.mass); Quaternion targetRotation = Quaternion.LookRotation(-downward); Quaternion rotation = Quaternion.Slerp(target.Body.rotation, targetRotation, RotationSpeed * Time.deltaTime); target.Body.MoveRotation(rotation); edit: Here's a gif that sorta illustrates what I mean; as soon as I cross the pole, the camera spins 180 degrees.
This might work. Not sure if the normalised is required, it will be more performant without it. Code (CSharp): transform.up = (transform.position - planet.position).normalised;
Hm, that seems to just shift the axis that it rotates around to another spot. edit: it was suggested to me that passing the players forward vector into Quaternion.LookRotation in addition to the downwards vector, might fix this, but it didn't seem to.
I thought it might of been too nieve. Another option is to parent the object to the centre if the sphere and rotate. Or you can project in front of the player with transform.forward. And use transform.LookAt with the gravity direction as the up parameter.
the transform.lookat solution seemed like it should work to me, but it's exhibiting the same behavior.
I was able to mostly solve this by using Quaternion.LookRotation(downward, target.transform.up), but it makes the player face the planets head on, rather than landing feet first. It does fix the weird axis rotation issue though, so I'll probably find another super hacky workaround to fix the rest, like separating the rigidbody from the players collider.
Hi, what do you mean by "face the planets head on"? Do you mean your character stumbles on his face or are you jumping from small planet to other?
I mean the players forward vector faces toward the center of the planet, rather than the bottom, and every configuration I've tried has resulted in either that or (I think?) gimbal lock.
Dinosaurs: should be doable the way BoredMormon explained it. Only I wouldn't trust forward direction; Get the gravity direction (current, but remember that it may need reversing). Then get side direction of your character (Vector.right or such). Then calculate the new forward direction of this frame using Vector3.Cross. And don't use built in gravity just add it manually, and lock the orientation of rigidbody, so that it won't fall on it's face on micro planet's round terrain / gravity.
Thank you for the suggestions; I already have the rigidbody locked, and have gravity off in the scene. I have also attempted getting the right angle via the vector cross product, which results in the same rotation behavior. After doing some research I believe the issue I'm experiencing is gimbal lock; any time I apply Vector3 based rotations to the player, I experience the unexpected rotations around planet poles. Only by using the unmodified Quaternion.LookRotation does the player correctly rotate relative to the planet. I believe the solution is to do all the math with quaternions, but I'm not well versed enough in quaternion operations to figure out the right way. I ended up resorting to a bit of a hack; I separated my collider from my rigidbody, and keep the collider rotated locally to appear correct.
It might not be as bad as you think. In theory, you should be able to map a point on a sphere to a quaternion, i.e. take whatever position the player is at in relation to the planet and make that a quaternion (how exactly to do that I have no F***ing clue, normalize euler? ). After that, keep track of where the previous position was, get the delta of the two (using Quat.FromToRotation), then just add (the multiply operator; shut up, quats are hard to explain) the delta to the player/camera/whatever.
I use Screen To Gif : https://screentogif.codeplex.com/ There are a number of plugins and asset store packages you can buy to do this in-editor, but this is by far the easiest to use and the results are pretty good (though usually a little bit large in terms of filesize). And @RockoDyne thank you for the suggestion, I'm still trying to work out how to do the actual math described in your post but I'll update when I get it working.