Game Development Community

Question: Falling Impact Angle?

by Kevin Rogers · in General Discussion · 07/30/2012 (1:17 pm) · 11 replies

Posted this in the T3D private forum recently; got no responses, so re-posting here.

The issue I need to fix is that when the player falls onto any sloped surface he just skis down instead of taking damage. Seems like the falling impact damage is only applied when the player falls onto a level surface. Additional note: This seems to only apply if the player has some lateral momentum; if just dropped straight down from the camera position, the player does take falling damage.

So, is there a way to set a minimum slope angle where the player will always take damage from falling? The only thing I'm seeing is "groundImpactMinSpeed"...

Also, while we're on the subject: I'd ultimately like to implement more realistic falling impacts for slopes; i.e. tumbling or rolling after an impact. Has anyone tried hooking up the player falling collisions to physics and what are your thoughts/ideas on that?

Thanks!

#1
07/30/2012 (1:30 pm)
Hmm i believe someone fixed this, maybe there is a resource about it or something. I did see another thread discussing it! But i didn't bookmark it, try searching a little about it ;)
#2
07/30/2012 (2:16 pm)
Of course I tried searching first; did not spot anything that seemed applicable.

For example, www.garagegames.com/community/forums/viewthread/110803, which claims to have fixed a problem with falling damage, but that's not the problem I'm dealing with...





#3
07/30/2012 (2:29 pm)
Oh well but one thing you could do is:
if(jumping)
cast ray from player and down to just beneath his feet.
If ray hits terrain:
impact angle = raycollision.angle

Something like that
And just put it in processTick that would give you the impact angle just apply the damage there and begin tumbling down hill.
When the real impact comes (the one that stops the player from looking like he is flying down the hill) stop tumbling.
Edit: raycollision.angle should probably be raycollision.normal
#4
07/30/2012 (3:21 pm)
Thanks... Yeah, I'll probably have to try something like that (I assume you're talking script-side?), but it feels kinda kludgy. I mean, this seems like a fundamental issue (read: "bug") with the player collision code in the engine -- you shouldn't be able to drop off a 100 m cliff without so much as a sprained toe just because the landing is on a bit of a slope! =)

What I was hoping for -- what makes sense -- is a setting, e.g. "groundImpactMinAngle", that would be exposed along with "groundImpactMinSpeed", so we have better control over when the player takes falling damage. Thoughts/ideas?

#5
07/30/2012 (3:39 pm)
I was actually talking code side.
You can make that groundImpactMinAngle by adding float field to the player class and in processTick if the object is in the air, check the slope below him, and if the angle between the normal of the raycast from the player to the slope and the vector (0,0,1) is bigger than groundImpactMinAngle, the player has now hit the ground.
However you can, as mentioned before, instead of triggering an impact make the player tumble down the hill and wait for the slope below the player to reach a certain angle so he can get up on his feet again.
#6
08/01/2012 (6:35 am)
I imagine you could use the maximum movement speeds in the Player datablock to help out with this. These speeds represent the Player running flat-out, right? So if at any point your Player is moving over ground faster than their maximum speed, then they should eat the dirt, because their body would be moving faster than their legs could carry it.
#7
08/08/2012 (10:27 am)
Thanks Daniel... that's a good way of looking at it that I had not considered; I should definitely factor that in.

I still would like to set/check the terrain angle, but I haven't had much success with that so far. I've looked through the Player::updateMove() (which is called from processTick() ) but... lack of time and weak math skills. =(
#8
08/09/2012 (5:50 am)
Check terrain angle:
RayInfo rInfo;
Point3F position = getPosition();
Point3F velocity = getVelocity(); // ?? Not sure how to get the velocity, shouldn't be too hard tho.
if(gClientContainer.castRay(position, position + velocity * deltaTime, TerrainObjectType, &rInfo))
{
	Point3F normal = rInfo.normal;
}
This is is basically the same code I use in my IPS Lite resource to check if the particles collide with objects and/or terrain, and then bounce the particles off.
The normal is a normalvector which is the easiest way to handle the angle. To find the actual angle, just find the angle between the normal vector and the horizontal plane.
#9
08/09/2012 (2:40 pm)
Quote:between the normal vector and the horizontal plane.
You'll probably want the angle from the normal to vertical, actually. Consider horizontal ground: the normal will be (0, 0, 1). Its angle to horizontal is 90 degrees, its angle to vertical is 0 degrees. The plane of the ground is at 0 degrees to horizontal.

To get the angle, you'll need to do an inverse cos of the dot product of your two vectors. Protip: if you dot a vector with (0, 0, 1) (i.e. vertical), it's the same as extracting the z component. So you can say angle = acos(vector.z);
#10
08/09/2012 (2:42 pm)
Oh yeah, note to myself: "The player is not floating on his stomach all the time"
#11
08/14/2012 (9:26 am)
Excellent, thanks to both of you! I'll see if I can find some time tonight to try out that code and see what I come up with...