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);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TmpStr);
TmpStr = "Speed: ";
TmpStr.AppendInt(Speed);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TmpStr);
TmpStr = "Damage: ";
TmpStr.AppendInt(FallDamage.Damage);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TmpStr);
}
}
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: is how i ended up doing it.
in MyProjectTypes.h
USTRUCT(Blueprintable, Category="Fall Damage Type")
struct FMyFallDamageEvent : public FPointDamageEvent
{
GENERATED_USTRUCT_BODY()
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Fall Damage Property")
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);
Hope it can be helpfull.