Melee attacks involve a character playing an animation during which Hit Triggers are activated to detect objects that can be hit within a specific area.
In general, each frame of the animation has its own hit data so that the shape can change to match the visual appearance of the Sprite
.
This system is based around the AttackTransition
class which is a Transition that inherits from the regular ClipTransition
to add details about each of its hit boxes:
[Serializable]
public partial class AttackTransition : ClipTransition
{
[SerializeField]
private HitData[] _Hits;
public HitData[] Hits
{
get => _Hits;
set
{
if (_HasInitializedEvents)
throw new InvalidOperationException(
$"Modifying the {nameof(AttackTransition)}.{nameof(Hits)} after the transition has already been used" +
$" is not supported because its initialisation modifies the underlying" +
$" {nameof(AnimancerEvent)}.{nameof(AnimancerEvent.Sequence)} in a way that can't be easily undone.");
_Hits = value;
}
}
When first played, it initializes its Animancer Events to activate and deactivate each of those hit boxes at the appropriate time:
private bool _HasInitializedEvents;
public override void Apply(AnimancerState state)
{
if (!_HasInitializedEvents)
{
_HasInitializedEvents = true;
HitData.InitializeEvents(Hits, SerializedEvents.Events, Clip.length);
}
base.Apply(state);
}
}
Drawer
AttackTransition
implements the ITransitionGUI
interface so that it can draw additional GUI elements in the Inspector and Transition Preview Window:
Hit Triggers
The HitTrigger
script stores the details of an active hit and manages the shape of its PolygonCollider2D
(with Is Trigger
enabled) so that when it receives an OnTriggerEnter2D
or OnTriggerStay2D
message it can attempt to Hit the triggering object.
HitTrigger
objects are instantiated as copied of a prefab located in Assets/Plugins/Platformer Game Kit/Prefabs/Resources and are managed as an object pool so HitTrigger.Activate
gets a spare instance or creates a new one if there weren't any and HitTrigger.Deactivate
returns it to the pool so it can be reused.