Determining a Player is airborne.
by Kuju Manila · in Torque Game Engine · 05/02/2007 (7:18 pm) · 12 replies
Is there a way to determine whether a player object is airborne? For instances like players that fall of a cliff.
#2
05/04/2007 (12:43 am)
Z velocity won't help you if he isn't moving in Z direction. I've wondered about this too-- a way to tell if the player is in contact with the ground.
#3
05/04/2007 (1:01 am)
Well you could use this:// Get distance from bottom of controlled object to terrain getControlObjectAltitude()Or cast a simple ray from the player's feet.
#4
%unbla = %actualZ
Have you tried doing something to the extent of VectorDist(%bla, %unbla);
I know that is not exactly correct code, but the general idea...i'm tired, it's 3...Spider Man premier....
05/04/2007 (1:07 am)
%bla = %z.getTerrainHeigh();%unbla = %actualZ
Have you tried doing something to the extent of VectorDist(%bla, %unbla);
I know that is not exactly correct code, but the general idea...i'm tired, it's 3...Spider Man premier....
#5
I shall have to do so! :-)
05/04/2007 (1:08 am)
Ah, raycasting. Yes...I've read a lot about it but haven't tried it. I shall have to do so! :-)
#6
I use that code in player.cc and player.h respectively to check if a player is in the air. The other built-in code methods only check for the terrain and not interiors.
The same thing can be done in script using ContainerRayCast(start, end, masks, ignoreobject);
The end position will be the same as the player position plus a few to the z axis, and if it returns anything then you are not airborne. You'll also want to set the player object as the ignore object or you will always be touching something (i.e. you).
05/04/2007 (1:54 am)
bool Player::isAirborne(F32 fudgefactor)
{
U32 mask = InteriorObjectType | TerrainObjectType | ForceFieldObjectType;
Point3F start = getPosition();
Point3F end = start + VectorF(0,0,-1) * fudgefactor;
RayInfo rInfo;
disableCollision();
bool los = getContainer()->castRay(start, end, mask, &rInfo);
enableCollision();
return los;
}
ConsoleMethod(Player,isAirborne,bool,3,3,"obj.isAirborne(fudgefactor)")
{
return object->isAirborne(dAtof(argv[2]));
}bool isAirborne(F32 fudgefactor);
I use that code in player.cc and player.h respectively to check if a player is in the air. The other built-in code methods only check for the terrain and not interiors.
The same thing can be done in script using ContainerRayCast(start, end, masks, ignoreobject);
The end position will be the same as the player position plus a few to the z axis, and if it returns anything then you are not airborne. You'll also want to set the player object as the ignore object or you will always be touching something (i.e. you).
#7
Place this function in server/scripts/player.cs
Done.
The function continues to loop and checks if there's anything beneath the player's feet whilst they are alive. The function stops on death.
05/04/2007 (2:36 am)
Here's an easy scripted solution:Place this function in server/scripts/player.cs
//-----------------------------------------------------------------------------
// Determine if player is falling (Server)
// %player = player server ID
//-----------------------------------------------------------------------------
function Player::checkPlayerFalling(%player)
{
%mask = $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType;
%rayStart = %player.getWorldBoxCenter();
%rayEnd = getWord(%rayStart, 0) SPC getWord(%rayStart, 1) SPC getWord(%rayStart, 2) - 2;
%foundObject = ContainerRayCast(%rayStart, %rayEnd, %mask, 0);
if (!%foundObject)
{
echo("--> Player is falling!");
messageAll("","player is falling!");
}
if(%player.isEnabled())
%player.schedule(100, checkPlayerFalling);
}
//-----------------------------------------------------------------------------Add this to the Armor::onAdd method:function Armor::onAdd(%this,%obj)
{
...
...
// Determine if player is falling
%obj.checkPlayerFalling(%obj);
// Determine if player is falling
}Done.
The function continues to loop and checks if there's anything beneath the player's feet whilst they are alive. The function stops on death.
#8
As Paul points out, "getControlObjectAltitude()" only checks for terrain which is why I presented my scripted alternative above.
05/04/2007 (3:02 am)
Quote:Well if the player is falling they will be moving in the Z direction.
Z velocity won't help you if he isn't moving in Z direction
As Paul points out, "getControlObjectAltitude()" only checks for terrain which is why I presented my scripted alternative above.
#9
05/04/2007 (3:17 am)
Hmm, Tim, do you not hit your own player container when searching without setting the search to ignore the player?
#10
If I wanted to include players in the search, I would use $TypeMasks::PlayerObjectType.
05/04/2007 (8:00 am)
No, the player isn't detected as I haven't included it in the search masks. I have only included terrain, interiors and static shapes.If I wanted to include players in the search, I would use $TypeMasks::PlayerObjectType.
#11
05/04/2007 (9:29 am)
Ah, silly me, should have known that. Having a brain-fart of a day :)
#12
Another thread to bookmark...
05/04/2007 (1:09 pm)
@Tim: I hear ya. I just have a tendency to have gravity-defying elements in my game ideas :-)Another thread to bookmark...
Torque Owner Tim Heldna