# How to rotate a player when using Mario Galaxy style gravity?

I'm working on Mario Galaxy style walking and physics.

This code will attract the player (capsule with controller) towards the centre of the scene (0,0,0) and also rotate them so that they orient the right way up. It also stops the player from falling when they hit the planets surface. For my game I don't need to calculate rotations based upon the normal of the ground like they do in Mario. Just rotate towards a point.

This all works. However, now I need to rotate the player with the input controls. But I can't because the planet orientation code over rides this meaning that the player will not turn around when I press the keys!! How can I solve this???

Here is all my code so far:

``````/// This script moves the character controller forward
/// and sideways based on the arrow keys.
/// It also jumps when pressing space.
/// Make sure to attach a character controller to the same game object.
/// It is recommended that you make only one call to Move or SimpleMove per frame.
var speed = 6.0;
var rotateSpeed = 3.0;
var faux = Vector3.zero; //gravity value

private var moveDirection = Vector3.zero;
private var targetPos = Vector3.zero;

function FixedUpdate()
{

// Obtain Controller
var controller : CharacterController = GetComponent(CharacterController);

// Apply Gravity and Check to see if we have landed on planet (if so stop gravity)
var targetDir = transform.TransformDirection (-Vector3.up);
Debug.Log (targetDir);
if (!Physics.Raycast (transform.position, targetDir, 1.2))
{
print ("No Collision.");
//Debug.Log ("No collision found.");
faux += (transform.position - Vector3.zero).normalized * -2 * Time.deltaTime; //apply gravity
controller.Move(faux);

}
else
{
faux = Vector3.zero; // reset gravity
}

//Rotate Player towards centre of planet
transform.rotation = Quaternion.FromToRotation (Vector3.up, (transform.position - Vector3.zero).normalized);

//Apply movement from keys
moveDirection = Vector3(0 ,0 , Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;

// Apply rotation from keys. DOESNT WORK!!
transform.Rotate(0, Input.GetAxis ("Horizontal") * rotateSpeed, 0);

// Move the controller
controller.Move(moveDirection * Time.deltaTime);

}

``````

This isn’t perfect, but this is what I used in the end (or at least a simple version of the final script):

``````var planet : Transform; // The planet to rotate around
var speed = 8.0; // move speed
var rotateSpeed = 10.0; // rotate speed for player
private var faux = Vector3.zero; //gravity value
var ground = 0; // if on the ground
var fauxMag = 0.0;
var gravMag = 20.0; // power of gravity
var jumpMag = 10.0; // power of jump
var hit : RaycastHit;
var groundHeight = 1.25; // offset that pushes the player up above the ground slightly

private var moveDirection = Vector3.zero;

function Update()
{
if (!planet)
return;

var controller : CharacterController = GetComponent(CharacterController);

var targetDir = transform.TransformDirection (-Vector3.up);

if (!Physics.Raycast (transform.position,-transform.up, hit, groundHeight))
{
ground = 0;
faux +=(transform.position - planet.transform.position).normalized * -gravMag *Time.deltaTime; //apply gravity

}
else
{
if(hit.distance < groundHeight-0.1)
{
transform.position = hit.point + transform.up*groundHeight;
}
ground = 1;
faux = Vector3.zero; // reset gravity
}
print ("Ground = " + ground);
// Here you're overwriting the current orientation (as you noted in
// something like (note that subtracting Vector3.zero isn't
// needed):
QuaternionRotation = Quaternion.FromToRotation (transform.up, (transform.position - planet.transform.position).normalized);
transform.rotation = QuaternionRotation * transform.rotation;

moveDirection = transform.forward * Input.GetAxis("Vertical") * speed;

if (Input.GetButton ("Jump"))
if (ground == 1)
{
//moveDirection += transform.up * 10;
faux = transform.up * jumpMag;
ground = 0;
}

// Now that you're not overwriting the orientation every update,
// this should work.
if (!Input.GetButton ("View1"))
{
transform.Rotate(0, Input.GetAxis ("Mouse X") * rotateSpeed, 0);
}

controller.Move((moveDirection + faux) * Time.deltaTime);
fauxMag = faux.magnitude;

planetScript = planet.GetComponent(PlanetBehaviourScript);
planetRotateSpd = planetScript.rotateSpd;
planetMoveVec = planetScript.moveVec;

transform.RotateAround(planet.transform.position, Vector3.up, planetRotateSpd * Time.deltaTime);
transform.position.x += planetMoveVec.x * Time.deltaTime;
transform.position.y += planetMoveVec.y * Time.deltaTime;
transform.position.z += planetMoveVec.z * Time.deltaTime;

}
``````

Why reinvent PhysX?

``````var planet : Transform;

function FixedUpdate() {
// could be optimized
var direction = (planet.position - transform.position).normalized;