Combat

Key Features

  • Manages Player Combat: Tracks player's attackers (added, removed, killed), auto engagements and finding enemies.

  • Attack & Health: Combat is driven by 2 components, attacker and health.

  • Realtime combat: Handled by moving and stationary attack tasks.

  • Melee & Ranged: Simple attack in proximity to enemy or firing ranged projectiles.

  • Line of Sight: Use line of sight for obstacles on module for all units or per-unit.

  • Event-Driven Updates: Global events for tracking health changes. Per unit events for tracking health and attack status changes.


Structure

  • Combat Module - Easy access to player's attackers, finding enemies, detecting attack range and retrieving attack positions for initial movement.

  • Attack Capability - Defines unit stance (no attack, defensive, aggressive and stand ground), range of attack, reload speed, default damage, line of sight range, damage based on unit type, specify invalid targets, etc.

  • Unit Attack - Management of attacker's state; reloading, moving, entering/exiting combat, etc. Currently it has 4 built-in options for Stance with UnitAttack default implementation.

    • No Attack: Never engages on its own. Must be commanded to attack.

    • Defensive: Uses last commanded target position as defensive point; unless manually specified. Configuration includes defend range.

    • Stand Ground: Does not move, attacks only when enemy is within the attack range.

    • Aggressive: Typical behaviour, looks for targets nearby and engages. Switches targets only if another is very close (depends on attack task configuration) and at the same time closer than the target.

  • Attack LOS - Attacker specific LOS used before attacking and finding its target.

  • Projectile Launcher - Responsible for firing and managing projectiles of UnitAttack.

  • Projectile - Use existing or create your own projectile behaviours. Provides basic projectile, proximity projectile, impact projectile (AOE) and collision projectile.

  • Health Capability - Defines health points, auto regeneration, and if health can increase or decrease current hit points (heal or damage).

  • Health - Management of health's state.

  • HealthFinder - Spatial grid finder, optimised for larger number of units.

  • Tasks - Provides abstract task for customisation of attack behaviour, stationary attack task, mobile (movement) attack task and move and attack task with position as the final target.

  • Combat Events - Global events for tracking health changes and firing projectiles.


Usage Examples

Control Attackers

To disable or enable automatic detection of nearby enemies in runtime use the following method:

if (!player.TryGetModule(out CombatModule combatModule)) return;

if (enableDetection) combatModule.EnableAutomaticDetection();
else combatModule.DisableAutomaticDetection();

When disabling this none of the units will automatically engage and you have full control over engagement process by starting tasks/sending attackers to health targets.

Find Nearby Enemies

When you wish to find nearby enemies for the attacker:

if (!player.TryGetModule(out CombatModule combatModule)) return;

IUnitAttack attack = // Get attack reference

if (combatModule.FindNearestEnemy(attack, attack.LineOfSight, out IHealth target))
{
    // Do something with the enemy target health
}

// OR get multiple enemy health components
foreach (var nearbyHealth in combatModule.FindNearbyEnemies(attack)) 
{
    // Do something with the enemy target health
}

Damage Health

When you wish to deal damage instantly to the target.

IUnitAttack attacker = // Retrieve attacker reference
IHealth target = // Set target

// Use damage defined by data or custom damage
float damage = attacker.GetDamage(target);
// Attack may be 'null' if it was hit by some effect coming directly from the player.
target.Damage(attacker, damage);

Move and Attack command

When you wish for movable unit with attack capability to move to a specific position while picking up enemies and engaging on the way.

private void MoveAndAttack(Vector3 targetPosition)
{
    IUnit unit = // Get unit reference.
    unit.ScheduleTask(
        new PositionContext(targetPosition),
        new AttackTaskInput(attack),
        attackTask);
}

This schedules a specific task with input & context, with no additional validation. Be careful when using this if not used on valid units; starting tasks on invalid units might throw exceptions, depending on the task.

Change Stance

When attack unit needs to change it's stance/behaviour:

IUnit unit = // Retrieve the unit or IUnitAttack reference directly.

// Change stance to the desired one. 
unit.UnitAttack.SetStance(AttackStance.Aggressive);

Manual Health Tracking

To track health state changes, hook your scripts to any of the events available in CombatEvents .

// Add listener
CombatEvents.Instance.OnHealthDepleted.AddListener(HandleUnitKilled);

// Define method for observing the event
private void HandleUnitKilled(IHealth health, APlayer owner, IUnitComponent attacker)
{
    // Check if player is the owner
    if (owner != player) return;

    AppendText($"Lost {health.Entity.Data.Name}");
}

Healing

When you wish to heal entity manually.

IHealth targetHealth = // Set target
IEntity healer = // Optional reference to healer entity

// Healer entity may be 'null' if healing was not performed by an entity.
targetHealth.Heal(healer, 10);

Last updated