Where to change the characteristics of swimming physics?

I’d like to make some changes to the characteristics of swimming physics.

I can only see the (very limited) options in PhysicsVolume,uc. Is there some other place I can look to change this behavior?


I traced it down to the playerController Swimming state.

In ProcessMove() it is applying the new acceleration to the pawn:

function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
        Pawn.Acceleration = NewAccel;

I can access the Pawn.Floor which gives me the normal (slope) of the ground directly beneath the pawns feet. I’m just have trouble with the math to apply the ground slope to NewAccel, so that the pawn will move smoothly up the slope.

Any help would be much appreciated.

local vector DotProduct;

DotProduct = FloorNormal dot  vector(Pawn.Rotation);

if(DotProduct == -1)
    // The floor is directly in front of you.
else if(DotProduct < 0 && DotProduct > -1)
    // You're on an uphill slope.  This might be where you want to give your pawn some upward acceleration to get out of the water.
else if(DotProduct == 0)
    // If the dot product is exactly 0, you're on flat ground.
else if(DotProduct > 0 && DotProduct < 1)
    // You're on a downhill slope.
else if(DotProduct == 1)
    // The floor is directly to your back.

Unless your pawn can flip upside down or something, this should be how it all works… But it doesn’t take into account water depth, so if you can dive under the water and touch ground, that could activate your “try to get out of the water” code. You might also want to tweak how vertical the ground can get before you decide it’s too steep to walk out of the water on. Maybe -0.1 to -0.5 would be a good range to start with.

Thanks for the help @Nathaniel3W

It’s how to apply the direction of the acceleration, based on the floor normal and player direction that I’m struggling with.

So long as (FloorNormal dot PlayerDirection < 0) and (FloorNormal dot vector(0,0,1) > 0), you should just be able to apply additional acceleration in the +Z direction, or maybe in the direction of velocity. Am I simplifying it too much and missing something?

Thanks @Nathaniel3W I’ll have a play around and see if I can get something working.

So your logic works at determining the slope based on the player’s rotation.

However it appears that upward velocity is ignored while the pawn is touching it’s collision cylinder on the upward slope (while moving towards the slope).

It’s like the pawn gets locked on to the ground and starts moving very slowly.

This is the default behavior of the UDK swimming physics implementation, so is reproducible by creating a water volume and putting a sloped mesh to exit the water.

I’d welcome any other suggestions as to what is preventing the pawn from rising while moving into a ground slope while in water.

Maybe you could try putting some test code into the PlayerController state PlayerSwimming event NotifyPhysicsVolumeChange to see if everything there is doing what’s expected. Maybe Pawn.OutofWaterZ is too low? Maybe you overrode your Timer event to stop checking on whether to go to land movement? I don’t know, but maybe logging info from NotifyPhysicsVolumeChange could give you some hints.

I know you’ve been working on this issue for a while. I hope you can get it figured out. If you fix it, I’d be interested in hearing how you did it.

I just tested all these events in my Swimming state, and none of them are firing when i hit the ground slope:

event HitWall( vector HitNormal, actor Wall, PrimitiveComponent WallComp );
event Falling();
event Landed( vector HitNormal, actor FloorActor );
event PhysicsVolumeChange( PhysicsVolume NewVolume );
event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal );
event PostTouch( Actor Other ); // called for PendingTouch actor after physics completes
event UnTouch( Actor Other );
event Bump( Actor Other, PrimitiveComponent OtherComp, Vector HitNormal );
event BaseChange();
event Attach( Actor Other );
event Detach( Actor Other );
event Actor SpecialHandling(Pawn Other);
event CollisionChanged();
event bool EncroachingOn(Actor Other);
event EncroachedBy( actor Other );
event RanInto( Actor Other );    // called for encroaching actors which successfully moved the other actor out of the way
event OnWakeRBPhysics();
event OnSleepRBPhysics();

Whenever the pawn is pushing into the ground slope (facing it) while swimming almost all vertical velocity is ignored. I’d love to figure this out.

Many UDK games don’t notice this, as they don’t have gradual slopes coming out of water volumes, instead using the CheckWaterJump() to jump out of water at ledges.