x


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);

}
more ▼

asked Aug 20, 2010 at 04:56 PM

Sydan gravatar image

Sydan
286 35 26 39

subcribing.....

Aug 29, 2010 at 05:01 PM headkit
(comments are locked)
10|3000 characters needed characters left

5 answers: sort voted first

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
   // your post). Instead, you want to apply a corrective rotation,
   // 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;

}
more ▼

answered Sep 08, 2011 at 02:07 PM

Sydan gravatar image

Sydan
286 35 26 39

(comments are locked)
10|3000 characters needed characters left

Why reinvent PhysX?

var planet : Transform;

function FixedUpdate() {
  // could be optimized
  var direction = (planet.position - transform.position).normalized;
  rigidbody.AddForce(
    Physics.gravity.magnitude * direction, // pull towards planet center
    transform.position - transform.up, // pull from feet to orient character
    ForceMode.Acceleration // gravity is pure acceleration
  );
}
more ▼

answered Dec 16, 2010 at 07:35 PM

Max Kaufmann gravatar image

Max Kaufmann
618 28 23 31

You mean AddForceAtPosition right?

Sep 17, 2011 at 10:44 PM Super Flat
(comments are locked)
10|3000 characters needed characters left

Have a look at Faux Gravity topic at the forums

more ▼

answered Jan 21, 2011 at 03:35 PM

Bart 1 gravatar image

Bart 1
11 1

(comments are locked)
10|3000 characters needed characters left

Did you have any luck with this? I'm trying to do the same type of movement and having issues as well.

more ▼

answered Nov 28, 2010 at 07:34 PM

boomcrash gravatar image

boomcrash
20 8 8 11

Hey, I managed it in the end, but I didn't take the answer from here. What I plan to do is write a tutorial on my website: http://www.sydan.co.uk/tutorials.html It should be there eventually (might have to wait because I'm about to head off to uni again). If you give me an email address though I can send you some source code :)

Sep 08, 2011 at 01:59 PM Sydan

Actually don't worry, I posted the solution above ^

Sep 08, 2011 at 02:08 PM Sydan
(comments are locked)
10|3000 characters needed characters left

@Max Kaufmann: Sorry, I'm new to unity scripting. Do you apply this script to the character object and then create a sphere named 'planet'?

more ▼

answered Dec 28, 2010 at 04:13 PM

Mark 8 gravatar image

Mark 8
1

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x787
x164
x148
x107

asked: Aug 20, 2010 at 04:56 PM

Seen: 5580 times

Last Updated: Sep 17, 2011 at 10:44 PM