Hi, is there a way to apply melee damage in C++? I read this: https://wiki.unrealengine.com/Melee but I need that the damage is for the players in front of the damage causer, and not for all players near the damage causer.
Announcement
Collapse
No announcement yet.
Melee damage
Collapse
X

Melee damage
Unreal Engine 4 C++ Programmer
My projects:
Ultimate Arena FPS
Our Discord Server:
Ultimate Arena FPS DiscordTags: None

Originally posted by cmartel View PostJust start with that approach and add a dot product check to exclude actors outside whatever frontal angle you want.Unreal Engine 4 C++ Programmer
My projects:
Ultimate Arena FPS
Our Discord Server:
Ultimate Arena FPS Discord
Comment

It's basic linear algebra, you'll have a hard time doing gameplay math without knowing it!
The dot product is one of the two most important operations you can do with vectors, the other being the cross product. Without going into the proofs and theory, one interesting property of the dot product comes from this definition:
With X being the length of X, Y the length of Y and theta the angle between the two vectors. The cosine of a 0 degree angle is 1, the cosine of a 90 degree angle is 0, and the cosine of a 180 degree angle is 1. What this means is that you can use the dot product to compare two vectors and check the resulting sign to see if the vectors are pointing in the same direction, are perpendicular or opposite. As a result:
Code:FVector CharacterDirection = MyCharacter>GetActorRotation().Vector(); FVector DeltaToEnemy = Enemy>GetActorLocation()  MyCharacter>GetActorLocation(); FVector DirectionToEnemy = DeltaToEnemy.SafeNormal(); float DotToEnemy = FVector::DotProduct( CharacterDirection, DirectionToEnemy ); if( DotToEnemy > 0.0f ) { // enemy is in front, do stuff here }
Code:FVector CharacterDirection = MyCharacter>GetActorRotation().Vector(); FVector DeltaToEnemy = Enemy>GetActorLocation()  MyCharacter>GetActorLocation(); FVector DirectionToEnemy = DeltaToEnemy.SafeNormal(); float DotToEnemy = FVector::DotProduct( CharacterDirection, DirectionToEnemy ); const float MaxMeleeAngle = FMath::DegreesToRadians( 45.0f ); const float MaxMeleeCos = FMath::Cos( MaxMeleeAngle ); if( DotToEnemy > MaxMeleeCos ) { // enemy is in melee arc, do stuff here }
The dot product and cross product (and linear algebra in general) are pretty important, I'd recommend reading on it if you want to do game programming.
Camille
Comment

Originally posted by cmartel View PostIt's basic linear algebra, you'll have a hard time doing gameplay math without knowing it!
The dot product is one of the two most important operations you can do with vectors, the other being the cross product. Without going into the proofs and theory, one interesting property of the dot product comes from this definition:
With X being the length of X, Y the length of Y and theta the angle between the two vectors. The cosine of a 0 degree angle is 1, the cosine of a 90 degree angle is 0, and the cosine of a 180 degree angle is 1. What this means is that you can use the dot product to compare two vectors and check the resulting sign to see if the vectors are pointing in the same direction, are perpendicular or opposite. As a result:
Code:FVector CharacterDirection = MyCharacter>GetActorRotation().Vector(); FVector DeltaToEnemy = Enemy>GetActorLocation()  MyCharacter>GetActorLocation(); FVector DirectionToEnemy = DeltaToEnemy.SafeNormal(); float DotToEnemy = FVector::DotProduct( CharacterDirection, DirectionToEnemy ); if( DotToEnemy > 0.0f ) { // enemy is in front, do stuff here }
Code:FVector CharacterDirection = MyCharacter>GetActorRotation().Vector(); FVector DeltaToEnemy = Enemy>GetActorLocation()  MyCharacter>GetActorLocation(); FVector DirectionToEnemy = DeltaToEnemy.SafeNormal(); float DotToEnemy = FVector::DotProduct( CharacterDirection, DirectionToEnemy ); const float MaxMeleeAngle = FMath::DegreesToRadians( 45.0f ); const float MaxMeleeCos = FMath::Cos( MaxMeleeAngle ); if( DotToEnemy > MaxMeleeCos ) { // enemy is in melee arc, do stuff here }
The dot product and cross product (and linear algebra in general) are pretty important, I'd recommend reading on it if you want to do game programming.
Camille
But the problem is that the shot doesn't match the crosshair, as you can see here:
The code is this:
Code:FHitResult MeleeHitResult; FCollisionQueryParams TraceParams; TraceParams.bTraceComplex = false; TraceParams.bReturnPhysicalMaterial = true; TraceParams.bTraceAsyncScene = true; TraceParams.AddIgnoredActor(this); GetWorld()>LineTraceSingle(MeleeHitResult, FirstPersonCameraComponent>GetComponentLocation(), (FirstPersonCameraComponent>GetForwardVector() * 50000) + FirstPersonCameraComponent>GetComponentLocation(), ECC_Visibility, TraceParams); DrawDebugLine(GetWorld(), FirstPersonCameraComponent>GetComponentLocation(), (FirstPersonCameraComponent>GetForwardVector() * 50000) + FirstPersonCameraComponent>GetComponentLocation(), FColor::Blue, false, 5.f, 0, 0.f); DrawDebugSphere(GetWorld(), MeleeHitResult.ImpactPoint, 20, 20, FColor::Blue, false, 5.f);
Unreal Engine 4 C++ Programmer
My projects:
Ultimate Arena FPS
Our Discord Server:
Ultimate Arena FPS Discord
Comment

Ah, yeah, trace based melee attacks are a wholly different bag. It is more finnicky and complicated than generic overlaps like the original approach, but it definitely gives better results. For instance, swinging a sword will have hits actually occur when they collide with something rather than just a single moment when the attack "connects".
In any event, your problem's pretty simple. Here is your screenshot in Photoshop with guides placed at the exact centre of the viewport:
The trace is actually correct, it's the crosshairs that's not centered correctly. Remember that the position of UI elements is normally on their top left corner. So when centering a UI element, you have to factor in the element's own size when setting its location.
If you're using a UMG/Slate canvas, it's as simple as setting the alignment to (0.5, 0.5), which will treat the crosshairs's "origin" as being in the middle rather than the default top left (0.0, 0.0 alignment). If you're using a FCanvas HUD, then do the math manually:
Code:const FVector2D Center( Canvas>ClipX * 0.5f, Canvas>ClipY * 0.5f ); const FVector2D Position = Center  CrosshairsSize * 0.5f;
Comment

Originally posted by cmartel View PostAh, yeah, trace based melee attacks are a wholly different bag. It is more finnicky and complicated than generic overlaps like the original approach, but it definitely gives better results. For instance, swinging a sword will have hits actually occur when they collide with something rather than just a single moment when the attack "connects".
In any event, your problem's pretty simple. Here is your screenshot in Photoshop with guides placed at the exact centre of the viewport:
The trace is actually correct, it's the crosshairs that's not centered correctly. Remember that the position of UI elements is normally on their top left corner. So when centering a UI element, you have to factor in the element's own size when setting its location.
If you're using a UMG/Slate canvas, it's as simple as setting the alignment to (0.5, 0.5), which will treat the crosshairs's "origin" as being in the middle rather than the default top left (0.0, 0.0 alignment). If you're using a FCanvas HUD, then do the math manually:
Code:const FVector2D Center( Canvas>ClipX * 0.5f, Canvas>ClipY * 0.5f ); const FVector2D Position = Center  CrosshairsSize * 0.5f;
Unreal Engine 4 C++ Programmer
My projects:
Ultimate Arena FPS
Our Discord Server:
Ultimate Arena FPS Discord
Comment
Comment