Skip to content

Hitboxes

namespace Griff.Modules.Fighting;
public sealed class Hitboxes : Component, IPlaytestReport, ITeamMember

Hitboxes and hurtboxes for each frame of the entity’s animation, with no code: a fighter’s punch hits only on the frames its fist is out, and its head takes more than its legs. Each of its Boxes is on one frame of one clip: a hitbox (it deals damage, knockback and hitstun) or a hurtbox (where it can be hit, with a multiplier). Draw them over the frames in the Clip Editor (Art > Animation Clips). While the entity plays a frame, it has that frame’s boxes, mirrored as its sprite is flipped, and one of its hitboxes touching another’s hurtbox is a hit: the hurtbox’s Health takes the damage, its body flies off with the knockback, it’s in hitstun for the stun’s steps, and both send their messages. A swing hits each thing once per group, however many frames touch it.

Things on its Layers with a Health but no boxes of their own are hit through their colliders, so a hero’s sword drawn on the frames of its swing hits a platformer’s slimes too. With an Attack (no Hitbox needed), the Attack action plays its Attack clip, whose frames hit. Hits are worked out after physics each step, frame by frame as the game steps, where the game is run (offline, or the host), so the same input always lands the same hits. Its outputs (Hit and Got Hit on the step it lands or takes one, its Hits, its Hitstun) are for a wire, a Counter or a Bar.

This is a component: its saved properties are on its component page.

public IReadOnlyList<FrameBox> BoxList { get; }

Its Boxes read, those that make sense.

public IReadOnlyList<string> Boxes { get; set; }

Its boxes, a line each: the clip and its frame (counting from 0; * for the animation’s own frames, or with no animation), hit or hurt, where it is and how big from the entity’s middle facing right, and what it does, e.g. Punch 2 hit at 0.6,0.3 size 0.5x0.25 damage 3 knockback 4,2 stun 12 or Idle 0 hurt at 0,0.7 radius 0.3 multiplier 1.5. Draw them in the Clip Editor rather than typing them.

public string? Effect { get; set; }

A prefab spawned where a hit lands, e.g. “Sparkle”: a burst of particles, a damage number.

public string? GotHitMessage { get; set; }

A message sent as one of its hurtboxes is hit, with the damage it took as its data.

public string? HitMessage { get; set; }

A message sent with Game.Send as one of its hitboxes lands, with the damage it dealt as its data.

public string? HitSound { get; set; }

A sound played as one of its hitboxes lands, e.g. “Sounds/punch.wav”.

public float HitStop { get; set; }

Freezes the game for this many seconds when one of its hitboxes lands, so it hits hard. 0 for none.

public int Hits { get; set; }

How many hits its hitboxes have landed. Set by the game.

public int Hitstun { get; set; }

Steps of hitstun it has left (frames, at 60 a second): set by the stun of a hit it takes, counting down one a step. What a fighter can’t act through. Set by the game.

public bool JustGotHit { get; set; }

True on the step one of its hurtboxes is hit. Set by the game.

public bool JustHit { get; set; }

True on the step one of its hitboxes lands (for a wire into an action, which does it once). Set by the game.

public string? Layers { get; set; }

The collision layers of things it hits through their colliders, when they have a Health but no boxes of their own, e.g. “Enemy” for a hero’s sword. Empty hits only hurtboxes.

public IReadOnlyList<string> Struck { get; set; }

What the swing under way has hit, by group, a line each (“1 id”): it hits each thing once per group. Set by the game.

public bool Stunned { get; }

True while it’s in hitstun.

public string? SwingClip { get; set; }

The clip of the swing under way (what Struck is for). Set by the game.

public int SwingLoop { get; set; }

How many times a looping clip has gone round in the swing under way: each time round is a new swing. Set by the game.

public float SwingTime { get; set; }

How far into its clip the swing under way was last step, in seconds: a clip starting over is a new swing. Set by the game.

public string? Team { get; set; }

Its team, the one every genre shares (see Teams): its hitboxes hit only what isn’t on its team, so teammates don’t hit each other. Empty takes the team of whatever else puts it on one (a Team, a turn taker), or with none hits anyone else.

public ReadOnlySpan<FrameBox> Now()

The boxes of the frame the entity is showing (see Showing).

public ReadOnlySpan<FrameBox> On(string? clip, int frame)

The boxes on frame frame of clip (OwnFrames for the animation’s own frames), in order.

public void Recover()

Ends its hitstun now.

public override string? SetupNote()
public ValueTuple<string, int, int> Showing()

The clip and frame the entity is showing, as its boxes are listed by: its animation’s clip (or OwnFrames) and which of that clip’s frames it’s on; with no animation, its own frame 0.

public void Stun(float frames)

Puts it in hitstun for frames steps, as a hit with that stun would.

public override bool Uses(string property)
public event Action<HitInfo>? GotHit

Raised as one of its hurtboxes is hit, with the hit.

public event Action<HitInfo>? Hit

Raised as one of its hitboxes lands, with the hit.