Melee Combat
The Melee Combat functionality is an animation-centric, data-driven layer that allows you to configure how melee targets are acquired and processed. There are few different objects participating in this module.
Summary: Melee Combat
- Attacks are represented by abilities created from
UCombatAbility_Attack
. - For Melee Combat, the Attack Ability must have the property
bIsMeleeAttack
set totrue
. - Animations can be configured using the Animation Provider. This can be further modified for other use-cases, not based on Animation Montages.
- Optionally, you can configure a Warp Target provider, which is used to warp the animation that will play.
- Implement the
ICombatMeleeInterface
in the owner, or tag the correct mesh component withCombat.Component.MeleeScanSource
. - In the selected animation, add a
Melee Scan
Notify State. It must correctly define the scan source, either as the owner of a weapon represented by a query. - Still in the selected animation, add a 'Motion Warping' state, with a warp name set to
Combat Warp
. Only necessary if you have configured a Warp Provider.
Participants for Melee Combat
Multiple participants are involved to perform a melee scan. Here's a diagram to show you each step. Participants are listed and the table after, but fully described along this page.
sequenceDiagram
AbilitySystemComponent->>AttackAbility: activate
activate AttackAbility
AttackAbility->>AttackAbility: listen for events
AttackAbility->>AnimationMontage: play
activate AnimationMontage
AnimationMontage->>MeleeScanNotifyState: begin
activate MeleeScanNotifyState
MeleeScanNotifyState->>MeleeScanInstance: initialize
activate MeleeScanInstance
MeleeScanInstance-->>MeleeScanNotifyState: instance
deactivate MeleeScanInstance
MeleeScanNotifyState->>AttackAbility: gameplay event
AnimationMontage->>MeleeScanNotifyState: end
deactivate AnimationMontage
deactivate MeleeScanNotifyState
AttackAbility->>ScanMeleeTargetTask: initialize
activate ScanMeleeTargetTask
ScanMeleeTargetTask-->>AttackAbility: instance
deactivate ScanMeleeTargetTask
AttackAbility->>ScanMeleeTargetTask: activate
activate ScanMeleeTargetTask
ScanMeleeTargetTask->>MeleeScanInstance: scan
activate MeleeScanInstance
MeleeScanInstance->>MeleeScan: scan
MeleeScanInstance-->>ScanMeleeTargetTask: targets
deactivate MeleeScanInstance
ScanMeleeTargetTask-->>AttackAbility: targets
deactivate ScanMeleeTargetTask
loop each Target
AttackAbility->>Target: apply GE
end
deactivate AttackAbility
Participant | Description |
---|---|
Attack Ability | Gameplay Ability handling the melee attack. Plays animation and waits for targets. |
Animation Montage | The animation representing the attack. It denotes the scan area. |
Melee Scan Notify | Notify State that determines when the scan should begin and end. |
Melee Scan Instance | An instance that contains the scan request and the logic for how it should be performed. |
Melee Scan Task | Ability task executing scans. One task can handle many scans. |
Attack Gameplay Ability
The UCombatAbility_Attack
is the default Gameplay Ability to handle melee combat.
If configured to handle Melee Attacks when bIsMeleeAttack
set to true
. It will listen for Gameplay Events
to the Melee Scan. You can also define the Gameplay Effect applied to targets hit during the Melee Scan.
You should subclass this ability for each specific attack, properly adjust is values as needed and then grant the ability to your character.
The Attack Ability is very flexible
The Attack Ability play animations and can handle both Melee and Ranged attacks from the same montage. This means that you can have very elaborate attacks, merging both combat styles, handled by the same backing ability.
You will notice that there are two specific sub-objects assigned to this ability: the AnimationProvider
and the
WarpTargetProvider
. These are used to provide the Montage to Play and the Warp Target used for the movement. You
can use the objects provided by the system or even create your own if you'd like.
Once the Ability activates, it will play the animation and wait for the Scan Event. Once triggered, it will receive
a UNinjaCombatMeleeScan
instance in the event's payload, which is used to retrieve details about the desired scan.
From there, a UAbilityTask_ScanMeleeTarget
will be instantiated or, if an active task is executing, reused to
perform the melee scan request. Targets acquired will receive the Gameplay Effect configured in the ability.
The Hit Effect can be overriden
In a scenario where you have multiple possible hits from the same Animation Montage, such as "dual wielding"
attack, and each weapon should have different gameplay effects, then you can look into GetHitEffectClass
function from the ICombatMeleeInterface
, which overrides the effect set in the Attack Ability.
Melee Scan Task
The UAbilityTask_ScanMeleeTarget
is an internal object used by the Attack Ability to perform Melee Scans in
a separate thread. There's virtually no reason for you to worry about this task since it's only an orchestrator
task.
The Melee Scan itself actually happens in the UNinjaCombatMeleeScan
so if you ever need to change the scan logic,
that's the class that you'll actually should consider extending.
Melee Scan Instance
The UNinjaCombatMeleeScan
contains the directives for the scan, and the logic to execute it.
Usually, you wouldn't directly work with these instances, unless you need to customize its logic. For that, you can extend the base class and modify any methods to fit your design. Then, simply provide your new class to the Notify State responsible for instantiating it.
These are the two methods used to customize the scan functionality. Both can be extended in Blueprint or C++.
Function | Description |
---|---|
ScanForTargets |
The method actually responsible for performing a scan. |
GetIgnoredActors |
Collects ignored actors for the scan. |
However, if you want to create a Melee Scan Instance directly, you can use static methods to do so, either in C++ or Blueprints.
// ----------
// .cpp
#include "GameFramework/NinjaCombatMeleeScan.cpp"
UNinjaCombatMeleeScan* Scan = UNinjaCombatMeleeScan::NewInstance(ScanClass, this, this, this, Mesh, SocketNames,
ECC_Visiblity, EMeleeScanMode::LineTrace);
Melee Scan Notify State
The Melee Scan state determines when a scan should start and stop. You'll want to add this to the frames in your attack animation, where hits should connect to targets.
Property | Description |
---|---|
Scan Source | Source of the scan mesh. Owner or a Weapon. |
Weapon Query | For a weapon source, provide the query used to retrieve the weapon. |
Scan Socket Names | Sockets in the mesh used for the scan. |
Scan Channel | Channel used to perform the scan. |
Scan Mode | How to perform the scan. Line Trace or Collision Sweeps. |
SphereRadius | In case of a Sphere Sweep, the sphere radius. |
BoxHalfExtent | In case of a Box Sweep, the box half extent. |
CapsuleDimensions | In case of a Capsule Sweep, the Vector containing the capsule's extent. |
StartScanTag | The Gameplay Event used to start the scan. |
StopScanTag | The Gameplay Event used to start the scan. |
MeleeScanClass | Melee Scan class used to transfer the data to the backing ability. |
The Owner or Weapon obtained by the query must be a valid implementation of CombatMeleeInterface
, which is used to retrieve
the proper Mesh to use for the scan. If you prefer an easier approach, albeit slower in execution, you can also tag the appropriate
Mesh Component with Combat.Component.MeleeScanSource
.
Melee Scan collision channel
It's highly recommended that you create a proper Melee Scan collision channel in your project!
Handling multiple Melee Scans
You can add multiple scans in the same animation. They can be related to the same weapon or even different ones, just make sure to provide the proper Gameplay Tag Query for them!
Be careful changing the Event Tags
Unless there's a very good reason to change the Event Tags, you shouldn't change them. But if you must, then make sure to also change the tags in the backend Ability that will be listening to these events!
Motion Warping
Motion Warping is very common for melee abilities, making sure that the attacker's root component is moved and rotated properly to meet an expected target, usually the victim. This creates a certain "stickiness" to combat, which may be desirable or not for your project.
If you want to use Motion Warping, you must ensure that:
- A Motion Warping implementation is provided. For more information about this, please go check the Components page.
- The Attack Ability is configured to detect Warp Targets.
- Your Animation Montage has a Motion Warping Notify State, with its Warp Target Name set to
CombatWarp
, or anything else matching the propertyWarpName
from the Attack Ability.
Core engine functionality
This Anim Notify State and the backing Motion Warping Component used as a default implementation for Motion Warping are provided by the Unreal Engine's Motion Warping plugin.
Whenever you are using the Motion Warping for animation-based abilities, you can also choose how to collect the appropriate
target for the warping. The system provides a dedicated provider object for that purpose, the UNinjaCombatMotionWarpingTargetProvider
.
You can use the ones provided by the system, or create your own provider. Their goal is to collect an actor that will be used as a target for the Motion Warping system. For more information about this, please check the Combat Targeting page.