• News

• Industries

• Learning & Support

• Community

• Marketplace

# Math Speed, Impact and Distance. (Feedback wanted.)

Hey I was hoping I could get some feedback on how I am calculating the damage of my fall damage.
Any tips on API Methods I can use to calculate this or any errors I might have done is greatly appreciated.

``````

void AMyProjectPlayerClass::Landed(const FHitResult & Hit)
{
OnLanded(Hit);

FPointDamageEvent FallDamage;
FString TmpMsg = "Fall Damage: ";

FVector DistanceVec = Hit.TraceEnd - Hit.TraceStart;

const float Distance = DistanceVec.Size();

float Speed = Distance / Hit.Time;
FallDamage.HitInfo = Hit;

if (CharacterMovement)
FallDamage.Damage = CharacterMovement->Mass * Speed;

if (GEngine)
{
FString TmpStr = "Distance: ";
TmpStr.AppendInt(Distance);

TmpStr = "Speed: ";
TmpStr.AppendInt(Speed);

TmpStr = "Damage: ";
TmpStr.AppendInt(FallDamage.Damage);
}
}

``````

Not how I normally do it, but it looks like it should work. I just check the acceleration in Tick and if it exceeds a threshold I apply damage based on that. Mine is more of a G-force damage then fall damage, so it applies to a broader set of situations. If you are just wanting fall damage then what you are doing should work great.

Thank you for the reply sometimes its just good with a extra set of eyes.
If you have time for it I love to see a example on how you do it.
Always hunting that knowledge
Cheers!

I agree…this seems like a very good way to do it, as it seems to adjust to how far/quickly the player falls and isn’t just a constant. If you wanted, you could actually remove the “mass” part and add a constant that you can set yourself. This is useful if you find that the damage dealt every fall is too low or too high:

``````
FallDamage.Damage = Speed * dmgMultiplier;

``````

UDK’s TakeFallingDamage looks like this in Pawn.uc and is called from the Pawns Landed event (and a few others).

MaxFallSpeed is either 1200 or 1250 and JumpZ either 420 or 322 depending on the Pawn class used (first value Pawn, second UTPawn)

``````
function TakeFallingDamage()
{
local float EffectiveSpeed;

if (Velocity.Z < -0.5 * MaxFallSpeed)
{
if ( Role == ROLE_Authority )
{
MakeNoise(1.0);
if (Velocity.Z < -1 * MaxFallSpeed)
{
EffectiveSpeed = Velocity.Z;
if (TouchingWaterVolume())
{
EffectiveSpeed += 100;
}
if (EffectiveSpeed < -1 * MaxFallSpeed)
{
TakeDamage(-100 * (EffectiveSpeed + MaxFallSpeed)/MaxFallSpeed, None, Location, vect(0,0,0), class'DmgType_Fell');
}
}
}
}
else if (Velocity.Z < -1.4 * JumpZ)
MakeNoise(0.5);
else if ( Velocity.Z < -0.8 * JumpZ )
MakeNoise(0.2);
}

``````

Hey thank you all for the feedback it realy helps, and i think i will go for your sugestion Borzi.
Damage seem to be very high from 1000 - 4000 from small heights.

Edit: Here is how i ended up doing it.
in MyProjectTypes.h

``````

USTRUCT(Blueprintable, Category="Fall Damage Type")
struct FMyFallDamageEvent : public FPointDamageEvent
{
GENERATED_USTRUCT_BODY()

FVector DistenceVector;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fall Damage Property")
float DamageMultiplier;

UPROPERTY(BlueprintReadOnly, Category = "Fall Damage Property")
float Distance;

UPROPERTY(BlueprintReadOnly, Category = "Fall Damage Property")
float Speed;

FMyFallDamageEvent ()
{
}

FMyFallDamageEvent (FHitResult InHitInfo)
{
DamageMultiplier = 2.0f;

HitInfo = InHitInfo;
HitInfo.TraceStart.X = 0; HitInfo.TraceStart.Y = 0; // Zero out the cordinats as we only want Z Axes
HitInfo.TraceEnd.X = 0; HitInfo.TraceEnd.Y = 0; // Zero out the cordinats as we only Z Axes

DistenceVector = HitInfo.TraceEnd - HitInfo.TraceStart;
Distance = DistenceVector.Size();
Speed = Distance / HitInfo.Time;
Damage = (Speed * DamageMultiplier);

if (Damage > PLAYER_MAX_HEALTH)
{
Damage = PLAYER_MAX_HEALTH;
}
else if (Damage <= 0)
{
Damage = 0;
}
}

void ReCalculateDamage(float NewDamageMultiplier)
{
DamageMultiplier = NewDamageMultiplier;
Damage = (Speed * DamageMultiplier);
}

};

``````

And in the TakeDamage(…) method.

``````
FMyFallDamageEvent FallDamage(Hit);
if (FallDamage.Distance > 10.0f && FallDamage.Damage > 0 && FallDamage.HitInfo.Time > 0.0f)
TakeDamage(FallDamage.Damage, FallDamage, Controller, NULL);

``````