Connect the Tactical Pack to your game’s combat system by implementing IAttackAgent on attackers and IDamagable on targets. The tactical tasks decide when and where to engage; these interfaces decide what an attack does and how damage affects a target.

The demo includes simple implementations that spawn a projectile and apply damage when it hits. Treat those scripts as examples and replace them with implementations that use your own weapons, health, animation, and effects systems.

IAttackAgent

Implement these members on a component attached to every agent that can attack:

// Returns the furthest distance from which the agent can attack.
float AttackDistance();

// Returns true when the agent is currently able to attack.
bool CanAttack();

// Returns the maximum angle from which the agent can attack.
float AttackAngle();

// Performs the attack toward the supplied world-space position.
void Attack(Vector3 targetPosition);

Keep CanAttack consistent with cooldown, ammunition, disabled, and animation states in your combat system. The tactical task uses this result to decide whether an attack can begin.

AttackDistance and AttackAngle should describe the currently usable attack, not the theoretical maximum across every weapon the agent could equip. If equipment changes, return values for the active weapon so the tactical task does not stop at a distance or angle from which the implementation will refuse to fire.

Attack receives a world-space position rather than a target interface. Use that position to aim or spawn the attack, then let the project’s normal hit detection decide what was struck. Do not apply damage unconditionally from Attack unless that is the authoritative combat model for the game.

IDamagable

Implement these members on every object that the tactical agents may damage. The interface name is IDamagable.

// Applies the specified amount of damage.
void Damage(float amount);

// Returns true while the object remains a valid living target.
bool IsAlive();

Return false from IsAlive as soon as the target should no longer be attacked, even if its death animation or cleanup continues.

Route Damage through the same health pipeline used by the rest of the game. Team filtering, armor, invulnerability, networking authority, hit reactions, and death events should not be bypassed merely because the request originated in a Tactical Pack demo-style projectile.

Place the implementations

Attach the IAttackAgent implementation where the tactical agent can discover it consistently, and attach IDamagable to the GameObject targeted by the task or to the location expected by the project’s adapter. A visible model child and its root actor may be different GameObjects; make the target reference and interface location agree.

Handle attack timing

CanAttack may remain false during cooldown, reload, stun, or an animation lock. It should become true only when calling Attack would be accepted. The Tactical Pack can continue to position the agent while it waits, so avoid implementing a second movement controller inside the attack adapter.

If the attack has delayed impact, recheck target validity through the project’s hit or damage pipeline. IsAlive can change between the request and the projectile contact.

Verify the integration

  1. Place one attacker and one damageable target within attack range.
  2. Confirm that CanAttack becomes true and that the target is inside AttackDistance and AttackAngle.
  3. Run an Attack task and verify that your Attack method is called with the target position.
  4. Confirm that the hit calls Damage and that IsAlive becomes false at the intended health threshold.
  5. Repeat with a cooldown, empty weapon, dead target, and target outside the allowed angle.

Also replace the active weapon at runtime, interrupt an attack animation, and destroy or pool the target before a delayed projectile arrives. These cases verify that the adapter reports current combat state rather than caching demo assumptions.