August 18, 2013

Well I said I would talk about our Mario Galaxy style gravity.  So here goes.

We cast a ray along the local space down direction from the midpoint of the body of our player character.  This is a simple call in unity, Physics.Raycast.  We have a mask that only looks for a collision with the planet.  Once we register a collision we take the normal of the surface, reverse its direction and update the players gravity with this new vector.  We then apply some smoothing with a smooth interpolation function and reorient the player to the new vector.  Because this is a game jam we have left the logic at this step.  We have higher priority things to implement and polish. The gravity works well enough that the player will not notice any significant jitter or jumpiness. Once we have more time (we want to continue working on this project once the jam ends) we will take the normals of the triangle our ray intersected, weight them based on distance from collision point, and then create a new vector from these verts and apply that as gravity.  This should smooth out the gravity even further when moving between triangles.  As a further step I imagine we would sample neighboring triangles as well

We also do not cast our ray very far down at the moment. This is because for the jam we will not have jumping, so there is only one way for the player to leave the surface of the planet–that being falling off of the dock. For this special case we apply a new gravity vector from the player position to the center of the planet and pull the player home.

Below is the code for our raycast and gravity update logic, and a diagram.  Be gentle, I wrote this code (with John and Shea’s help) while they were busy with the heavy lifting of the game and systems.  So don’t judge the teams coding prowess on the artists hacks!

void FixedUpdate ()

{

       RaycastHit hit;

       Vector3 newGravity;

       if (Physics.Raycast(PlayerTransform.position, -PlayerTransform.up, out hit,  2f, mask))

       {

       newGravity = -hit.normal;

       }

       else

       {

            newGravity = (Game.Planet.center – PlayerTransform.position).normalized;

       }

       Physics.gravity = Vector3.Slerp(Physics.gravity, newGravity * 5f, Time.fixedDeltaTime * 10f);

       Quaternion.FromToRotation(Vector3.up, -Physics.gravity );

       Quaternion q = Quaternion.FromToRotation(PlayerTransform.up, -newGravity);

       q = q * PlayerTransform.rotation;

       PlayerTransform.rotation = Quaternion.Slerp(PlayerTransform.rotation, q,

       Time.fixedDeltaTime * 2f);

}

 

And a quick diagram for reference.

Oculus Blog Post 2 Diagram

That is all for today. I hope in the next update to talk a bit about shaders. I also want to talk about Rift development in general soon.

Thanks for reading.  Here is another screenshot of the game in action.

Screenshot4_8_18_13

Note: I want to point out that the logic for this gravity system came from a blog post we all read a few months ago. Unfortunately I cannot find the post.  Sorry to whomever out there wrote the article, I wish I could give a shout out and a link!  Link to 3rd post about Jam and game