Search Unity

Gravity and Rotation

Discussion in 'Scripting' started by Dinosaurs, Oct 21, 2015.

  1. Dinosaurs

    Dinosaurs

    Joined:
    Aug 11, 2013
    Posts:
    17
    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):
    1.  
    2. Vector3 downward = (thisTransform.position - target.Body.position).normalized;
    3.  
    4. target.Body.AddForce(downward * Gravity * target.Body.mass);
    5.  
    6. Quaternion targetRotation = Quaternion.LookRotation(-downward);
    7.  
    8. Quaternion rotation = Quaternion.Slerp(target.Body.rotation, targetRotation, RotationSpeed * Time.deltaTime);
    9.  
    10. target.Body.MoveRotation(rotation);
    11.  
    edit: Here's a gif that sorta illustrates what I mean; as soon as I cross the pole, the camera spins 180 degrees.
     
    Last edited: Oct 21, 2015
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    This might work. Not sure if the normalised is required, it will be more performant without it.

    Code (CSharp):
    1. transform.up = (transform.position - planet.position).normalised;
     
  3. Dinosaurs

    Dinosaurs

    Joined:
    Aug 11, 2013
    Posts:
    17
    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.
     
    Last edited: Oct 21, 2015
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    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.
     
    eses likes this.
  5. Dinosaurs

    Dinosaurs

    Joined:
    Aug 11, 2013
    Posts:
    17
    the transform.lookat solution seemed like it should work to me, but it's exhibiting the same behavior.
     
  6. Dinosaurs

    Dinosaurs

    Joined:
    Aug 11, 2013
    Posts:
    17
    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.
     
  7. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    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?
     
  8. Dinosaurs

    Dinosaurs

    Joined:
    Aug 11, 2013
    Posts:
    17
    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.
     
  9. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    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.
     
  10. Dinosaurs

    Dinosaurs

    Joined:
    Aug 11, 2013
    Posts:
    17
    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.
     
  11. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    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.
     
  12. Diericx

    Diericx

    Joined:
    Jun 8, 2013
    Posts:
    62
    Sorry this is off topic, but how did you make that gif? Is there an easy way to do that?
     
  13. Dinosaurs

    Dinosaurs

    Joined:
    Aug 11, 2013
    Posts:
    17
    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.
     
    Last edited: Oct 23, 2015
  14. Diericx

    Diericx

    Joined:
    Jun 8, 2013
    Posts:
    62
    Oh my gosh this is amazing...thank you so much:D