View Full Version : Tutorial Detecting Slope of ground
Bob_Gneu
09-09-2011, 01:48 AM
Below is a sample of how you can detect whether you are walking up hill or down. You can use this to modify your speed (for example).
I don't think it is necessarily finished (I'd like to get rid of the magic constants and figure out scaling the speed with the angle), but it has been tested and seems to work.
inside your PlayerController
state PlayerWalking
{
function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
{
local Vector HitLocation, HitNormal, StartLocation, Diff;
StartLocation = Pawn.Location + vector(Pawn.Rotation) * 32;
Trace( HitLocation, HitNormal, StartLocation + (vect(0, 0, -11) * 16), StartLocation, true);
Diff = Pawn.Location - HitLocation;
// `log("Diff: " @ Diff.X @ Diff.Y @ Diff.Z);
if ( Diff.Z < 47.0 && Diff.Z > 45.0 )
{
Pawn.MovementSpeedModifier = 1.0;
}
else if ( Diff.Z <= 45.0 )
{
// `log("Uphill");
Pawn.MovementSpeedModifier = 0.325;
}
else if ( Diff.Z >= 47.0 )
{
// `log("Downhill");
Pawn.MovementSpeedModifier = 1.325;
}
Super.ProcessMove(DeltaTime, NewAccel, DoubleClickMove, DeltaRot);
}
}
Mougli
09-09-2011, 03:06 AM
Funny, I needed that detection a few months ago. I'm doing it like this (in the Pawn's Tick, but could be moved easily):
dir = Normal(Velocity);
direction = dir dot Floor;
//Floor is a pawn variable that returns the normal of the surface the pawn is standing on.
//Positive dot product means I'm going down the slope. Negative means I'm going up.
if (direction!= 0)
{
direction = direction / Abs(direction);
}
ctrl.slope = (1-Floor.Z)*direction; //ctrl is the reference to the PlayerController
Bob_Gneu
09-09-2011, 11:03 AM
Mons and i were playing with it last night, and while putting it in the pawn works out, i wanted to move it to processmove. My first attempt was to use the acceleration cross the floor normal, which works in some situations, but it provides odd situations with different faces.
Mougli
09-09-2011, 11:16 AM
Probably because you should be using the velocity rather than the acceleration?
(also, it's the dot product you want to use, the cross product is a different mathematical tool ;) )
Bob_Gneu
09-09-2011, 11:21 AM
I am aware, but i was not really worried about magnitudes. Crossing them allows for different signs when going up and down hill. I will approach it again, but our testing last night lead to odd situations going up or down the same face and using the Floor vector.
MonsOlympus
09-09-2011, 06:25 PM
As Bob_Gneu mentioned I was working on this as well, I was heading towards using floor dot normal(velocity) working from Pawn similar to Mougli. My investigation lead me to wondering if we could perhaps move the Pawn in the direction of the slope if rotated to face that direction. The velocity does work but only if the Pawn has one which is why I started thinking about this.
Bob_Gneu
09-09-2011, 06:47 PM
I have to fold! Looks like mougli's code works out quite well. Bravo =)
MonsOlympus
09-09-2011, 08:01 PM
event TickSpecial(float DeltaTime)
{
local vector2d Slope;
if(Floor.Z < 1.0 && Floor.Z > 0.15)
{
Slope.X = Floor.X > 0 ? Floor.X +1 : abs(Floor.X);
Slope.Y = Floor.Y > 0 ? Floor.Y +1 : abs(Floor.Y);
Velocity.X += Slope.X;
Velocity.Y += Slope.Y;
}
}
This is what I had but I needed to know the direction of the slope to change groundspeed :cool:
slowJusko
09-09-2011, 10:38 PM
Wouldn't this be better on the pawn so it affects bots, players and scripted pawns rather than just players?
Mougli
09-10-2011, 03:39 AM
As Bob_Gneu mentioned I was working on this as well, I was heading towards using floor dot normal(velocity) working from Pawn similar to Mougli. My investigation lead me to wondering if we could perhaps move the Pawn in the direction of the slope if rotated to face that direction. The velocity does work but only if the Pawn has one which is why I started thinking about this.
To force the player to move down the slope, I do this in PlayerMove:
// Update acceleration.
NewAccel = Pawn.Floor;
NewAccel.Z = 0;
NewAccel = Pawn.AccelRate * Normal(NewAccel);
where no velocity is involved.
Now I understand you want to apply this if the pawn is still and facing the downward slope, but actually, the concept of slope doesn't make any sense for an object that is not moving (since by definition, slope is a difference of height)
Wouldn't this be better on the pawn so it affects bots, players and scripted pawns rather than just players?
Depends on the game you're making, as usual :).
axelzellalex
09-10-2011, 11:31 AM
this is awesome, out of curiousity in regards to the first post of code, could "Diff.Z" be used to rotate the players mesh?
ie:
Diff=Pawn.Location - HitLocation;
Pawn.mesh.Pitch += Diff.Z;
? or is Diff.Z not an angle that could be applied?
- im not at my computer at the moment
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.