tennis-ballProjectiles System Structure

Projectiles Manager

The Projectiles Manager is a simple manager class responsible for storing and managing pooled projectiles. It keeps an internal dictionary where each key is a projectile prefab and each value is a pool of instances for that prefab.

The Projectiles Manager is located in the Game scene under the Stage Controller GameObject. You can access it in code via: StageController.ProjectilesManager

Whenever a hero or an enemy uses an attack that fires a projectile, that projectile must be registered during the object's Start method:

[SerializedField] protected GameObject projectilePrefab;

protected override void Start()
{
    base.Start();
    
    StageController.ProjectilesManager.RegisterProjectile(projectilePrefab);
}

To launch a projectile, simply request an instance from the manager using the same prefab:

public void Attack()
{
    var projectile = StageController.ProjectilesManager
        .GetProjectile<SimpleProjectile>(projectilePrefab);
        
    projectile.transform.position = transform.position + Vector3.up + Vector3.forward;
    projectile.transform.forward = transform.forward;
    
    projectile.Launch(damage);
}

IProjectileTarger

Any object that can be hit by a projectile must implement the IProjectileTarget interface. It provides useful methods such as:

  • TakeDamage()

  • ApplyStatusEffect()

  • ShowHitEffect()

  • and others.

IProjectileTarget itself inherits from IDefeatable, which provides:

  • SubscribeOnDefeat()

  • UnsubscribeOnDefeat()

Projectiles do not distinguish between heroes and enemies in code—this is instead handled by layers:

  • Player Projectile

    • Collides with Enemy

    • Ignores Player

  • Enemy Projectile

    • Collides with Player

    • Ignores Enemy

All projectiles also collide with Obstacle and Ground layers.

Simple Projectile Behavior

SimpleProjectileBehavior is a versatile, feature-rich projectile class that covers most common projectile mechanics. It supports bouncing, ricochets, splitting, status effects, magnetic homing, and distance-based damage scaling.

Component Fields:

  • Lifetime - How long the projectile exists before despawning if it hits nothing.

  • Speed - Projectile travel speed.

  • Ignore Ground - If enabled, the projectile will not despawn when hitting the ground.

  • Use Y Axis in Calculations - If disabled, projectile movement is restricted to the XZ plane.

  • Magnetism - Strength of the homing force toward the target.

  • Magnetism Strongest Distance - Distance at which full magnetism is applied.

  • Magnetism Weakest Distance - Distance beyond which magnetism is zero; values between the two distances are lerped.

  • On Death Particle Prefab - Particle prefab to spawn on hit (must be a reference to a particle prefab, not a ParticleSystem component).

  • Split Projectile Prefab - Projectile prefab to spawn if this projectile splits on hit.

  • Trails To Disable On Hit - Trails to reset when the projectile despawns or hits a target.

  • Block Target Hit Sound - If true, the target will not play its default hit sound.

  • Projectile Hit Target Sound - Sound played when hitting a target (optional).

  • Projectile Hit Obstacle Sound - Sound played when hitting an obstacle or ground (optional).

Tips for creating a new projectile

  • For most cases, you can reuse or extend SimpleProjectileBehavior through inheritance.

  • If your projectile requires behavior that cannot be achieved by adjusting its parameters, create a new class that inherits from AbstractProjectile.

    • This base class contains minimal required functionality: status effects storage, bounce/ricochet logic, and integration with the Projectiles Manager.

Last updated