Download

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);
		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 :slight_smile:
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()

	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.
WCode