Hi there, I’m working on a game in Unity. In one part of the game, the player finds himself in a unique area where he has control over his personal gravity.
By pressing a certain key, the player can invert gravity so that the ground becomes the sky and vice versa.
Here’s my code so far:
var speed = 6.0;
var jumpSpeed = 8.0;
var gravity = 20.0;
var inversiongravity = 0;
private var moveDirection = Vector3.zero;
private var grounded : boolean = false;
function FixedUpdate() {
if (grounded) {
// We are grounded, so recalculate movedirection directly from axes
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
}
}
if (Input.GetButtonDown ("Fire1")) {
if(inversiongravity == 0){
inversiongravity = 1;
Physics.gravity = Vector3(0, -1.0, 0);
}
else{
inversiongravity = 0;
Physics.gravity = Vector3(0, 1.0, 0);
}
}
// Apply gravity
if(inversiongravity == 0)
{
moveDirection.y -= gravity * Time.deltaTime;
}
else
{
moveDirection.y += gravity * Time.deltaTime;
}
// Move the controller
var controller : CharacterController = GetComponent(CharacterController);
var flags = controller.Move(moveDirection * Time.deltaTime);
grounded = (flags CollisionFlags.CollidedBelow) != 0;
}
@script RequireComponent(CharacterController)
So far it works okay, but there’s one or two things I’m not sure about:
Despite the fact that I can change gravity, the character won’t walk on the ceiling, instead being stuck in a constant ‘falling’ state. How do I make it so that the character is turned 180 degrees and treats the ceiling as the floor and vice versa?
To prevent abuse, and to encourage players to look up to see where they will be landing, I want it so that the player cannot invert gravity unless they have touched the ground. For example, if the player inverts gravity, they’ll fall upwards, and can’t re-invert gravity until they touch the ground. However once they have touched it, they can invert it again, even if they’re in the air. They just can’t invert it more than once in the air. Hope that’s clear.
I’m not sure how to do either of these, yet I can’t help but think it would be a simple matter. Can anyone help me out here?
I think you will have to rotate the character from the script. Reversing gravity will make an object “fall” upward, but there’s no particular reason why it would spin around so that its feet point towards the floor.
As for the other question, you’ll notice that the CharacterController has a variable called isGrounded. This can be used to detect if the character is touching the floor. Once the object has left the floor (when gravity is reversed), set a boolean value. This denotes that gravity can’t be reversed again until the object has touched down. When the object lands (as detected by CharacterController.isGrounded), clear this boolean value.
Hi, thanks for posting, that clears up some matters.
I’m not entirely sure how to flip the player upside down, though - the scripting manual mentions something about a “Transform.Rotate”, but it seems to be only by Time.deltaTime, as far as I know, instead of choosing a certain number of degrees to be rotated by. Ideally it should be 180, but my modifications aren’t making a difference.
What you want do to is to make a boolean which you set to true when you invert gravity. At the same time you create a new rotation which will be the wanted rotation. I am sorry about my poor explanation, but maybe some code is easier.
Just my 2 cents, wouldn’t it be easier just to rotate the scene by 180 degrees instead of trying to re-simulate gravity on the player character ? It would mean that all the other objects in the scene would fall from the ground to the ceil, but that’d make sense if the gravity is really inverted
I don’t think it’d work quite like that; you’re assuming that the level would rotate perfectly, but it would just dump the player in a different location rather than inverting gravity.
Besides, people have managed to make gravity act like Super Mario Galaxy; I doubt that this is much harder.
Slightly offtopic question, but how do you turn on Gravity of the rigidbody by javascript?
I have airplanes that need to go down quick before getting destroyed. I know it’s wrong down here
function Kill () {
rigidbody.gravity= true;
// Destroy the projectile
Destroy(gameObject, 3);
}
With a CharacterController, I don’t think your solution will be workable. I couldn’t get the CharacterController to actually flip due to lack of access to it’s internals and I posted a week or so ago and it was deemed not possible.
I’m yrying to do something similair, but can’t really get it to work, can someone please confirm if this is doable with the standard character controller?
I’m flipping the controller and inversing gravity but as stated above this isn’t seen as isGrounded and is write only, am i missing something here? Does it matter how the rotation is done?
For example i just use this
player_01.transform.Rotate(Vector3.forward*-180);