Input Action and Melee attack problem c++

Hi, I’m using c++ for Unreal Engine 4.10.4
I’m creating a base melee attack system for character (it’s the default third person character class).
In input action for simple attack I’ve done it:

And in c++ class (FinalWardCharacter.cpp) I’ve added this:

InputComponent->BindAction(“SimpleAttack”, IE_Pressed, this, &AFinalWardCharacter::AttackSimple);
InputComponent->BindAction(“SimpleAttack”, IE_Released, this, &AFinalWardCharacter::StopAttackSimple);

Sword->OnComponentHit.AddDynamic(this, &AFinalWardCharacter::OnHit);

void AFinalWardCharacter::AttackSimple()
{
isAttacking = true;
UE_LOG(LogTemp, Warning, TEXT(“start attack”));

}

void AFinalWardCharacter::StopAttackSimple()
{
isAttacking = false;
UE_LOG(LogTemp, Warning, TEXT(“finish attack”));
}

void AFinalWardCharacter::OnHit(AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
if (OtherActor != this && isAttacking)
{
OtherActor->TakeDamage(AttackDamage, FDamageEvent(), NULL, this);
UE_LOG(LogTemp, Warning, TEXT(“collision!”));
}

}

But there is a problem:

if I press left mouse and I don’t release it, character continues to inflict damage to other entity…I need he does it only one time.
How can I resolve it?

As you have it now, the duration of the “attack” (the time isAttacking is true) is based on how long the button is held.

It sounds like what you want is a fixed attack duration. You could use a timer, or better yet, use an animation notify (assuming you are using Persona).

For those kinds of sequences a state machine could work, like in animations there are several states an animation is into and there are one or more ways to go out of that state into another, means all state requests which are no output from the current one will be ignored. For example you jump and press “Lie down” usually makes no sense (and if so implement that edge :), so from Jumping State is no output to a state LieDown hence its not possible.

As you may have noticed state machines works mostly on boolean values, so your intention with isAttacking is the way you would go. When you click Left once you go inside AttackSimple and you are asking the current attacking state which could be “Idle” for the initial state describing its possible to attack -> then you say isAttacking = true which could be your second state. Then you could use a little timer since somtimes it could be that your button press over a specific time results in a “Heavy Attack” or something. So before you go to the light attack function (you only pressed once and shortly) start the timer and see if you need to call the “Heavy Attack”. After the countdown you call once of the function and the animation will start. In a specific animation state you would enable the HitDetection of your sword, maybe you dont want your sword to collide with something in a specific state which is not kind of “swinging”. Then there is one day the end of your animation coming and you would set your attack state back to “Idle” or even “Sheathed”
(Think of a cool one strike samurai attack, with a speed light attack and the final cool state, where he sheathes his katana and the enemy fell down :wink: )

My first guess is that you’re getting multiple collisions, since TakeDamage should only be running once per OnComponentHit and isAttacking stays true as long as the mouse button is still pressed. Is your UE_LOG collision warning popping up multiple times per attack?

If that’s what’s going on, the REALLY quick and dirty solution there would be to set isAttacking to false after calling TakeDamage in OnHit, but you’d probably want something better-practice than that like the state machine mentions.

How can I use Animation notify in c++?

You have several options… here is one:

If you are using Montage, you can add the notify(s) to the Montage timeline. If you are using just an animation Sequence, you can add notifies in the sequence timeline.

For example, add an “AttackOn” and “AttackOff” notify during the appropriate part of the animation.
You can then create these events in the Animation Blueprint Event Graph.

One benefit of this approach is it is fairly well timed with your specific animation.

(If using montage, set the notify as a branching point for higher resolution)

From these blueprint events, you can get the owning character blueprint and call function or set properties that you have exposed from c++.

As far as triggering damage, and limiting attack to single enemy - there are other considerations depending on your game.

One approach is to use raycasts between the frame-by-frame socket positions on your weapon. I have found this to be more reliable than adding a collision object to your weapon.

Happy Coding :slight_smile:

ok I’ve done it…but how can I set a boolean in C++ class from Animation notify?