Messing with Gravity in UDK

As this is my first post in 2012, I just want to start by wishing you all a happy new year!

For the past few weeks I have been tackling a whole bunch of really weird and interesting problems in UDK, and one of the most interesting has been how Epic handles gravity. Anyone who’s tried to change how gravity works in the Unreal Engine will know that this is near-impossible without access to native code. The reason is that physics, for the most part, isn’t handled by UnrealScript; it’s hard-coded and untouchable. Gravity will ALWAYS point straight down with a force of about 400.0 (whatever that happens to translate to in the real world).

Nevertheless, I did a lot of research, watched a lot of YouTube videos, and waded through tons of old forum posts for a few days trying to figure out a way to make it work. Many of the solutions I saw involved either changing the Pawn’s physics to PHYS_Flying or PHYS_Spider or making custom ladder volumes. In each case the aim was not to control gravity but to cheat it — with gravity turned off and the Pawn free-floating, one could simulate gravity’s pull with a quick nudge in one direction.

The problem? These solutions involve a whole bunch of manual positioning, rotation, and collision detection. To give you an idea of the complexity, consider a game in which it’s possible to walk sideways on a wall. You’d have to make sure the Pawn was free-floating the moment it touched the wall. You’d have to rotate the skeletal mesh to face the wall and position it normal to whatever surface it was standing on. If it hit something, you would have to handle how the Pawn responded to the hit (with the new “gravity” direction in mind). Most of the example sources I found online didn’t work at all.

Enter this:

Although you can’t tell from the picture, in this game you can change the direction of gravity. Hit ‘W’ and the whole map flips 90 degrees clockwise and the ball is sent falling in another direction. Hit ‘S’ and the map flips 90 degrees counterclockwise. It’s not perfect yet, but collision is a breeze and moreover the system is simple.

So…how? The answer is that the ball is not a Pawn at all, but a KActor. Pawns are cool because they streamline a lot of the things that you’d expect a sentient, controllable actor to do (such as move, handle weapons, etc.). But one thing a Pawn is lacking in is physics. By completely getting rid of Pawn and dumping in a Karma Actor, I was able to control gravity easily. Want the ball to float up? Easy, just AddForce(vect(0,0,400.0));

I’ll have a video of this game in action up on my YouTube channel soon enough. But for now, go mess around with KActors! It’s amazing just how much they can do 🙂


5 thoughts on “Messing with Gravity in UDK

  1. So this entire post was just for the AddForce function? lol.. 400 is not sure to be working to begin with since it depends on the KActor’s actual mass..Secondly it doesnt work well when the ball touches the ceiling cause it causes it to tremble.

    • Pretty much. 400 is the value for the ball in particular. Of course depending on the object the number may be different, although their is a way to get a universal number through script.

      And I have absolutely no issues with trembling on any surface. That may be a collision problem, certainly has nothing to do with AddForce().

      • Okay maybe i did something wrong with my testing but when i made a floating balloon, whenever it stayed on the ceiling there was some small slow trembling (or maybe you missed it cause it is not very obvious, especially when the object is moving), you made me curious though, how can i make a “universal number” ? i think there is a function to ge the mass of the mesh but i do not know exactly how addforce calculates the forces anyway.

    • Hmm…did you disable gravity by adding a rigid body constraint? It might be that the gravity in the game is pulling down still so that causes the tremble.

      The way I have it now is I base it off a mesh that has “perfect” fall, in other words I want every other mesh to fall at the same rate (in this case a ball). Then I do:

      BaseFallRate = 400/myBall.StaticMeshComponent.BodyInstance.GetBodyMass();

      in a place where I can easily reference the value, and in all other kactors I do:

      AddForce(vect(0,0,BaseFallRate * StaticMeshComponent.BodyInstance.GetBodyMass()));

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s