Flip gravity (Walk and jump on ceiling)

Hello! :slight_smile:

I’m working on a school project with unity, and I’m kinda stuck.
I want my character to be able to press a button, then the gravity is flipped, and he will be able to walk and jump from the ceiling.

I am using the first person controller that is in unity already so flipping the gravity is easy, but the part I cant get my head around is how can I make the character jump? I’m able to make him walk etc on the ceiling, but not jump.

How can I modify the script that is already in unity (Fps input controller and character motor) to make this happen?
If anyone have dont this before, I would love some help! (I’m scripting in javascript btw)

Thanks in advance!

4 Answers

4

The standard CC/CM/FPS does not handle arbitrary gravity well. There are other solutions including some in the Unity Wiki, but maybe you should look at your problem in a different way. Instead of rotating the character, consider rotating your world. Visually, you can make it appear that the character is rotating. That way your movement code does not need to change.

Sorry for late answer. I forgot to mention that I'm making a 2d game. So flipping the world would not work. I want the character to walk in the top side of the window if the gravity is flipped.

Rotating the world would work in 2D. I'd only do it if you have a 2D Character Controller that you don't want to modify and that doesn't handle gravity flipping.

Using the code from here:

Wouldn’t you be able to change the

moveDirection.y -= gravity * Time.deltaTime;

to

moveDirection.y += gravity * Time.deltaTime;

Note: I haven’t worked in 2D yet, so I might be totally wrong. I am not sure what to use as character controller in 2D or if the controller is coded from start.

And this would allow jumping on the roof? If so, I will look into it! :)

For the jumping you try this: moveDirection.y = -jumpSpeed;

You sir, are a genius! I'm new to this, so I might be asking a stupid question. But the if (controller.isGrounded) thing makes so the movement doesnt work when he is not groundend. I get that. I tried to add an else with the same info as in that if, and I got the player to move. But the player moved very slow. Except jumping, he would jump at the same speed. I have no idea what is causing the player to move slow. What do you think is doing that? And how can i fix it? EDIT: I figured it out, thanks! :)

Everyone has to make some of the stuff extremely harder than what it should be lol.

Have a script do something like

Void OnTriggerEnter (Collider col){
if(col.gameObject.tag == "Player")}
Physics.gravity = new Vector3(0,9.81f,0)
}
}

That should in theory reverse Gravity, you may have to do 18 or whatever as -9.81 + 9.81 = 0.

Then have the script access your player

Have a bool on your player called

public bool ReverseGrav = false; // This is if we are upsidedown.

Lets say your Player script is called Controller (just to simplfy it for me lol)

Go back to your OnTriggerEnter script that you made first.

Make another variable called

Public Controller controller; // The first Controller is the //name of your script the second is the Variable name.

Now have this bool under your Physics and put

controller.ReverseGrav = true;

DO A SAVE AND ADD THE TRIGGER SCRIPT TO THE AREA YOU WANT TO FLIP GRAVITY AND ADD CONTROLLER TO YOUR PLAYER, NOW GO TO THE TRIGGER ZONE AND ADD YOUR PLAYER INTO THE INSPECTOR FOR THE CONTROLLER SPOT.

Now lets finish the last little bit of code.

Go to your CONTROLLER script that we made.

Now in UPDATE put

if(ReverseGrav){
transform.rotate(180.0.0);
}

That should in theory work, because we Reversed Gravity and rotated the player to from now on be flipped over, shouldn’t be too too hard to finish the rest to make him flip back…

(CODE IS UNTESTED) But should work.

Hoppe that helps!

Just realized this was for 2d, well just work with the 2D rotations then there you go.

I know this is very old but since I was working on this, it might help somebody else. I needed to use the Character Controller and still allow walking on ceilings with inverted gravity, and it is possible with a workaround:

  • Character Controller doesn’t support actual rotation and will still return not grounded even if grounded on the ceiling and rotated appropriately
  • Simply write a custom IsCustomGrounded() function and make sure it returns character.isGrounded when normal gravity
  • When in inverted gravity, rotate the Character Controller, inverse your gravity code to make sure everything is inverted (vertical movement, jump, gravity, etc.)
  • Make sure IsCustomGrounded() does not return character.isGrounded when gravity is inverted, but rather return (character.collisionFlags & CollisionFlags.Above) != 0; to check if there is a contact above the character instead of checking the Below flag, and it will work fine!

Cheers