CombatCombo Ability
Last modified: 04 November 2024Uses State Trees to manage combo states.
Orchestrates Attack or Cast abilities that can be chained together.
Keeps track of actors hit by the current attack, which can be used to allow the combo to continue.
The Combo Ability is responsible for orchestrating abilities based on its own activation and also gameplay events. Any Gameplay Ability can be added to a combo.
You can find information about all participants of the Combo System in its design page. As for the Combo Ability, including the required State Tree.
Ability Properties
The following attributes adjust the behavior of the Combo Ability.
Property | Description |
---|---|
Combo Tree | The State Tree Asset containing all attacks and their transitions. |
Ability Classes | Additional Abilities required by the combo. They are automatically added and removed, with the Combo Ability itself. |
Event Mode | How events are transferred to the combo. You can choose between a direct transfer, or a mapping of inputs. |
Combo Window Effect Class | Gameplay Effect applied to the owner, when the Combo Window is open. |
Input
This ability expects two types of input: the usual activation action and a gameplay event to advance the combo.
void UComboInputHandler::HandleInputAction(const UInputAction* Action)
{
UAbilitySystemComponent* AbilityComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetOwner());
if (!IsValid(AbilityComponent))
{
return;
}
if (AbilityComponent->HasMatchingGameplayTag(Tag_Combat_State_ComboWindow))
{
AdvanceCombo(Action);
}
else
{
StartCombo();
}
}
void UComboInputHandler::StartCombo()
{
UAbilitySystemComponent* AbilityComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetOwner());
if (!IsValid(AbilityComponent))
{
return;
}
// "ActivateComboTags" is a tag container used to activate the Combo Ability.
// It should match the "Ability Activation" tags container in the Gameplay Ability.
//
AbilityComponent->TryActivateAbilitiesByTag(ActivateComboTags);
}
void UComboInputHandler::AdvanceCombo(const UInputAction* Action)
{
UAbilitySystemComponent* AbilityComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetOwner());
if (!IsValid(AbilityComponent))
{
return;
}
FGameplayEventData* Payload = new FGameplayEventData();
Payload->Instigator = GetOwner();
Payload->Target = GetOwner();
Payload->EventTag = AdvanceComboTags;
Payload->OptionalObject = Action;
// "AdvanceComboTags" is a tag container used to advance the combo to the
// next attack. It should match the event configuration in the combo ability and
// indicate a valid event in the Combo State Tree.
//
AbilityComponent->HandleGameplayEvent(AdvanceComboTags, Payload);
}
In the image you will find the following:
The input checks if the combo window is open, via the appropriate Gameplay Tag.
If it is, then it has to advance the combo, by sending a Gameplay Event with the appropriate Event Tag.
The Event Payload sends the Input Action as an optional object.
If the combo window is not open, then it activates the Combo Ability as usual.
The Event Tag has to map one of two things, depending on your design. If your Combo Ability is set to use Gameplay Tags as the Event Mode, then the event has to match the Gameplay Tags in your State Tree. In this case, you do not need to send the Input Action in the Event Payload.
If your Combo Ability is set to use Input Actions as the Event Mode, then your Gameplay Event should always be set to Combat.Event.Combo.Attack
and you need to provide the Input Action to map to specific triggers in the State Tree.