player 'down' - changing gravity

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

pospi

New Member
Jun 30, 2003
298
0
0
www.pospi.cjb.net
This is partly a how-to, partly a request for help.

I've been working on this problem for a few days/weeks now, and it's at the stage now where I can make anyone fall in any direction. What I am hoping to do in the future is have them also rotate properly like in spider mode, and be able to jump off walls. That half-works, but more on that later.


The most annoying part i found about trying to fiddle with gravity is the damn engine's limitations. It wants any falling acceleration to be on the Z axis only, and handles it natively that way. What you end up having to do is let it go to town on the Z axis, and come up with your own code for X and Y which hopefully provides the same acceleration. Turns out this isn't that hard to do.

Keep in mind from hereon in that this is only *one* way of doing this... Now on with it!
========================================================

The first thing you need to do is make a new state under your playerController class - I chose to extend from playerFlying but you may find others as effective. You'll also want to set up a global vector to hold the direction to fall in. When you want someone to fall in a different 'down' direction, set up that vector and put them in the new state (i called it playerSpecFalling).

Copy the PlayerMove() function out of playerWalking (in playerController class) and paste it in here. This means that air control will apply properly to our falling state (i think). You'll need to cut out the 'DoubleClickMove = ...' line since you can't access that stuff from a parent class. It doesnt really matter anyway, since you probably wont be wanting people to dodge while falling. Actually come to think of it you can probably cut a lot of the double jump code out as well, but you dont need to bother if you cant be arsed.

Now basically you play with the pawn's constantAcceleration variable and the addVelocity() function. My implementation assumes that the global 'down' vector discussed above is a unit vector, so you need to do the following in beginState():

Code:
        Pawn.Move(Pawn.Floor);  //move it off the ground
        Pawn.SetPhysics(PHYS_Falling);
        initGravity *= 950;
        Pawn.constantAcceleration = vect(0,0,950) + initGravity; //negate gravity
        Pawn.constantAcceleration.X = 0;
        Pawn.constantAcceleration.Y = 0;
        initGravity /= 950;
        initGravity *= 13.952;		//this is the exact Z acceleration value UT uses.
        initGravity.Z = 0;
        setTimer(0.01, true);

stepping through this, basically you first move the pawn 1 unit up off the ground (stops them sticking and isn't really noticeable), then set their physics to falling. You multiply that unit 'down' direction vector by 950 (since this is the amount required to negate all gravity effects. Also note that the 'down' vector should be the opposite of the pawn's floor if you want them falling normally).
You then set their constantAcceleration to 0,0,950 (this takes out all the gravity) and add the gravity you have multiplied from your direction vector (this gives the exact correct amount of 'down' or 'up' to the pawn's falling).
Now set the constantAcceleration back to 0 in the X and Y coordinates. This is because the native acceleration won't actually accelerate in these directions, so if you leave it like this you end up with some random parabolic flight path. God only knows why the game is hardcoded like this.

Anyway, next we make the 'down' vector equal to exactly 13.952 times the normal. I have no idea why UT uses this as an acceleration value rather than -9.8m/s², but there you have it. That's the exact right constant by the way, worked out from a bunch of integrals of various falling tests. Set the Z of your global 'down' vector to 0 - we wont be needing it again.
Now start a timer of 0.01 seconds which handles adding the acceleration to the pawn. It's a really simple timer:

Code:
    simulated function timer()
    {
    	Pawn.addVelocity(initGravity);
    }

And that's it! Youve got all you need to have some basic alternative-down-direction falling going on.

You'll probably want to add this endState() too, which essentially sets everything back:

Code:
    function EndState()
    {
    	Pawn.constantAcceleration = vect(0,0,0);
    	setTimer(0, false);
    }

My custom state also has these alternative hit methods to bring the player out of the state when they hit some geometry. You mightn't want that to happen so what you put in here is very much up to you.

Code:
function bool NotifyLanded(vector HitNormal)
    {
        gotoState('PlayerWalking');
        return bUpdating;
    }
    
    event bool NotifyHitWall(vector HitNormal, actor HitActor)
    {
        Pawn.HitWall(HitNormal, HitActor);
        return true;
    }

My HitWall() in the pawn class basically calls some additional functions to apply falling damage on wall hits and other things. Once again what you do here is very much a matter of what exactly you are doing.




Now, I *have* successfully had players landing on walls and being able to jump out from them (take a look in the doJump() function, it's really easy to change). The problem lies in keeping them constantly attached to the wall. You can't put them in PHYS_Spider, cos then you are stuck with them walking every which way around surfaces. I've tried a few things - varying states and the like - but the best i can get it players flickering incessantly between PHYS_Walking and PHYS_Falling. By the way, PHYS_Walking works fine for movement on walls (you just need to rotate the view appropriately).

So if anyone has some ideas on how to get around this final problem it'd be great to hear them. Otherwise I hope this is useful for some as a basis for gravity-modding type stuff.

cheers!