"Sticking" the Player to Rotating Spherical Ground

We’re creating a prototype game that involves the player roaming around the surface of planets trying to find the key necessary to get to the next one. After a few weeks of tinkering (and bickering), I finally decided to swallow my pride and ask for some assistance.

You see, our planets rotate around an axis to simulate a day/night cycle. This is a core feature and cannot change. The main issue is that while the player stands upon the planet surface, they do not move with the spot on which they stand. In other words, they don’t “stick” to the ground and move with it as the planet rotates.

Take a game like Outer Wilds, for example. The planets rotate as the player is on the surface. When the move, they “inherit” the planet’s rotation as well, almost as if they were a child object of the planet itself. This effect is not happening for us, but it needs to. And we can’t just make our player object a child of the planet either, given how other aspects are structured.

I’m not looking for someone to “write the code for me” of course, I’m simply wanting to understand the mathematics and physics behind how this is achieved. I need to translate player’s position upon the planet (which is also cruising through space with its own velocity) and make them “stick” to it, so they rotate with the world.

Any insight as to what the logic is here would be most helpful!

The way that I would try:

  • every frame:
  • determine the amount of rotational movement of the planet on the surface where the player‘s position is
  • determine the amount of translation of the planet
  • add both to the rigidbody.position of the player (and any other physics object on the planet) after FixedUpdate

This should in theory adjust the player‘s position to match the planet‘s rotation and movement. Of course this can get more complex if you use physics inter/extrapolation, networking, and you‘ll almost certainly run into issues where things don‘t match up perfectly or lag a frame behind.

Alternatively, considering that the planet‘s movement doesn‘t need to affect physics, you could treat the planet as stationary in terms of physics. As in: during physics update the planet position and rotation is fixed, and all other objects on that planet are relative to the planet. Then in LateUpdate you‘ll translate every transform to their visual positions (= add planet position + rotation), and before fixed update you reset everything. You may have to use a custom PlayerLoopSystem at the right point in time to have a callback before FixedUpdate.