Projectile - alexneargarder/Broforce-Docs GitHub Wiki
Projectile
Table of Contents
- Unity Lifecycle & Setup
- Combat & Damage
- Position & Physics
- Projectile Initialization & Configuration
- Collision Detection & Spawn Validation
- Special Projectile Behaviors
- Helper & Utility
Unity Lifecycle & Setup
Methods
protected virtual void Awake()
Initializes layer masks, barrier layers, and projectile configuration during Unity's Awake phase. Sets up collision layers for ground, fragile objects, and team-specific barriers, initializes z-offset from transform position, and establishes random seed for deterministic effects.
protected virtual void Start()
Initializes damage background counter with a random offset between 0 and 0.2 seconds. This creates variation in when projectiles start damaging background elements.
protected virtual void Update()
Main update loop that drives projectile behavior. Calls RunProjectile and RunLife methods each frame with the current delta time to process movement, collision, and lifetime.
Fields
protected LayerMask barrierLayer
Layer mask for enemy barrier detection. Set during Awake to include "MobileBarriers" and "IndestructibleGround" layers. Used to detect barriers that can reflect player projectiles, changing their ownership and increasing damage.
protected LayerMask fragileLayer
Layer mask for fragile/destructible object detection. Set to "DirtyHippie" layer during Awake. Used to detect breakable objects like doors and crates that projectiles can damage or destroy on contact.
protected LayerMask friendlyBarrierLayer
Layer mask for player-created barrier detection. Set to "FriendlyBarriers" layer during Awake. Used to detect barriers that can reflect enemy projectiles, converting them to player-owned projectiles with increased damage.
protected LayerMask groundLayer
Layer mask for ground and solid object collision detection. Set during Awake to include "Ground", "LargeObjects", and "FLUI" layers. Used in raycast operations to detect walls and terrain that should stop or reflect projectiles.
protected Randomf random
Random number generator instance for deterministic projectile variations. Initialized in Awake with either a random seed (0-10000) or the specified seed value. Used to create small random offsets for damage timing and other projectile behaviors that need to be consistent across clients.
public int seed
Seed value for deterministic random number generation. Set via the SetSeed method to ensure synchronized projectile behavior across networked games. Used to initialize the random field for consistent randomization of effects and variations.
protected float t = 0.011f
Delta time value for frame-independent movement calculations. Initialized to 0.011f and updated each frame with clamped Time.deltaTime (maximum 0.0334f). Used throughout the projectile system for consistent movement and timing regardless of framerate.
public float zOffset
Z-axis rendering offset for visual depth variation. Randomly set between -0.04 and 0.04 in Awake, or can be overridden during Fire method. Applied to transform position to create slight 3D depth effect and prevent z-fighting when multiple projectiles overlap.
Combat & Damage
Methods
protected virtual void Bounce(RaycastHit raycastHit)
Reverses the projectile's Y velocity to create a bounce effect off surfaces. Sets the Y velocity to its absolute value, ensuring upward movement after bounce. Updates projectile rotation to match new trajectory.
Parameters:
- RaycastHit raycastHit: Information about the surface that was hit
public virtual void Damage(int damage, DamageType damageType, float xI, float yI, float damageDelay, int newPlayerNum)
Applies damage to this projectile if it's damageable. Reduces projectile damage by the incoming damage amount and destroys the projectile if damage reaches zero. Only processes damage for projectiles marked with isDamageable flag.
Parameters:
- int damage: Amount of damage to apply to the projectile
- DamageType damageType: Type of damage being applied
- float xI: X force component (unused)
- float yI: Y force component (unused)
- float damageDelay: Delay before damage is applied (unused)
- int newPlayerNum: Player number applying the damage (unused)
protected virtual void HitFragile()
Processes collision with fragile/destructible objects. Uses sphere overlap to detect fragile objects within projectile radius and applies damage to each one found. Called during projectile movement to handle destruction of breakable terrain.
protected virtual void HitGrenades()
Detects and interacts with grenades within projectile radius if canHitGrenades is enabled. Uses Map.KnockAndDamageGrenades to apply knockback force based on projectile velocity. Only processes for projectiles with projectileSize greater than 3.
protected virtual void HitHorizontalWalls()
Specialized collision detection for wide projectiles against horizontal walls. Uses three parallel raycasts (center, up, down) spaced by projectileSize. Only active when horizontalProjectile is set to true.
protected void HitOil()
Checks for oil particles and oily terrain at the projectile's position. Ignites any oil found using EffectsController.IgniteOilParticles within a 24-unit radius. Also ignites oily blocks detected via raycast collision.
protected virtual void HitProjectiles()
Checks for collisions with other projectiles in the vicinity. Uses Map.HitProjectiles to detect and handle projectile-on-projectile interactions within the projectile's radius.
protected virtual void HitUnits()
Detects and damages enemy units within the projectile's area. Uses Map.HitUnits with projectile ownership to find valid targets. Awards deflection achievement if projectile was reflected and kills an enemy. Destroys projectile on successful hit.
protected virtual bool HitWalls()
Performs raycast collision detection against walls in the projectile's path. Handles standard wall impacts by applying damage, creating effects, and destroying the projectile. Special handling for depleted uranium perk creates 24-radius explosions on impact. Returns true if wall was hit.
Returns:
bool
: True if the projectile hit a wall and was destroyed, false otherwise
protected virtual void HitWildLife()
Checks for and damages wildlife units within the projectile's radius. Destroys the projectile with effects if any wildlife is hit. Uses Map.DamageWildLife to apply damage to animals.
protected virtual void MakeSparkShower(float xPos, float yPos, float showerXI, float showerYI)
Creates an intense shower of spark particles at the specified position. Generates 12 sparks with randomized velocities based on the provided shower direction. Each spark has high initial velocity (250+ units) for dramatic visual effect.
Parameters:
- float xPos: X position to create sparks
- float yPos: Y position to create sparks
- float showerXI: Base X velocity for spark shower direction
- float showerYI: Base Y velocity for spark shower direction
protected virtual void ProjectileApplyDamageToBlock(GameObject blockObject, int damage, DamageType type, float forceX, float forceY)
Applies damage to terrain blocks with special handling for depleted uranium perks. Creates a 24-radius explosion for player projectiles with depleted uranium, otherwise applies standard block damage. Handles oil ignition for fire damage types.
Parameters:
- GameObject blockObject: The block GameObject to damage
- int damage: Amount of damage to apply
- DamageType type: Type of damage being applied
- float forceX: X component of impact force
- float forceY: Y component of impact force
protected virtual bool ReflectProjectile(RaycastHit raycastHit)
Reflects the projectile off barriers with complex angle calculations and damage bonuses. Changes projectile ownership, adds +12 damage, plays reflection sound, and calculates reflection angle based on impact normal and projectile direction. Awards achievement for deflection kills. Returns false if canReflect is disabled.
Parameters:
- RaycastHit raycastHit: Raycast hit information containing impact point and surface normal
Returns:
bool
: True if projectile was successfully reflected, false if reflection is disabled
protected virtual void RunDamageBackground(float t)
Periodically damages background doodads along the projectile's path. Uses a timer that triggers every 0.033 seconds, checking and damaging doodads within 3 units of the projectile position. Only processes if affectScenery is enabled.
Parameters:
- float t: Delta time for this frame
Fields
public int damage = 1
Base damage value for the projectile. Default value is 1. This is the initial damage setting that gets copied to damageInternal during initialization and can be modified by SetDamage method. Represents the projectile's intended damage before any modifiers.
public int damageInternal = 1
The actual damage value used in calculations. Initially set from the damage field, but can be modified by fadeDamage mechanics, reflection bonuses (+12), or other gameplay effects. This is the value actually applied when the projectile hits targets.
public DamageType damageType
Specifies the type of damage this projectile inflicts (e.g., Bullet, Fire, Explosion). Passed to all damage application methods to determine appropriate hit reactions, visual effects, and special damage behaviors like oil ignition for fire damage.
public bool fadeDamage
When enabled, causes projectile damage to decrease proportionally with remaining life. Uses the formula damageInternal = fullDamage * (life/fullLife) to create projectiles that weaken over distance. Special interaction with BulletSnakeBroskin weapon type.
public MonoBehaviour firedBy
Reference to the MonoBehaviour (usually a unit) that created this projectile. Used for damage attribution, preventing self-collision at spawn, and special behaviors like inseminator targeting. Can be modified by return zones and reflection mechanics.
protected int fullDamage = 1
Stores the original damage value at projectile initialization. Used with fadeDamage mechanic to calculate damage reduction over time using the formula: damage = fullDamage * (life/fullLife). Preserves the initial damage for percentage calculations.
public int playerNum = -1
Identifies which player fired this projectile. Value of -1 indicates enemy projectile, 0-3 indicates player 1-4, and 5 indicates a reflected projectile. Used for friendly fire checks, material selection, and damage attribution. Modified during reflection.
protected Unit unitHit
Reference to the last unit hit by this projectile. While this field exists in the base Projectile class, it is not actively used and is likely intended for derived classes that need to track specific hit targets.
Position & Physics
Methods
public virtual void Death()
Handles projectile destruction with appropriate effects. Creates visual impact effects at the projectile's position, plays death sound if configured, and destroys the GameObject.
public virtual void IncreaseLife(float m)
Extends the projectile's remaining lifetime by a multiplier. Increases both current life and maximum life values proportionally, allowing projectiles to travel further before expiring.
Parameters:
- float m: Multiplier to apply to the projectile's life (e.g., 2.0 doubles remaining life)
protected virtual void MakeEffects(bool particles, float x, float y, bool useRayCast, Vector3 hitNormal, Vector3 hitPoint)
Creates visual effects when the projectile impacts. Generates sparks with physics-based trajectories, optional puff effects, and plays impact sounds. Supports both raycast-based hit information and position-only effects. Only creates effects once unless canMakeEffectsMoreThanOnce is enabled.
Parameters:
- bool particles: Whether to create particle effects (currently unused)
- float x: X position for the effects
- float y: Y position for the effects
- bool useRayCast: Whether to use raycast hit information for effect direction
- Vector3 hitNormal: Normal vector of the surface hit (used if useRayCast is true)
- Vector3 hitPoint: Exact point of impact (used if useRayCast is true)
protected virtual void MoveProjectile()
Updates the projectile's position based on current velocity and delta time. Applies doubled movement when doubleSpeed is enabled, effectively moving the projectile twice per frame for increased speed. Handles Z-axis positioning for rendering depth.
protected override void OnDestroy()
Cleanup method called when the projectile GameObject is destroyed. Deregisters the projectile from the Map system and calls base class cleanup.
protected virtual void PlayDeathSound()
Plays the projectile's death sound effect if a sound holder is configured. Uses the projectile's position and configured volume, with playback priority of 0.65.
protected virtual void RunLife()
Manages projectile lifetime countdown and destruction. Decrements life by delta time each frame, applying damage fade if enabled. When life reaches zero or damage fades completely, destroys the projectile with appropriate effects.
Parameters:
- float t: Delta time for this frame
protected virtual void RunProjectile(float t)
Core projectile update method that processes movement, collision detection, and damage application. Handles projectile physics, checks for unit/terrain hits, applies damage to background elements, manages return zone interactions, and processes special behaviors like reversing. Updates position based on velocity and delta time.
Parameters:
- float t: Delta time for this frame
public void SetDoubleSpeed()
Activates double speed mode for the projectile. Limits the projectile's life to a maximum of 1 second and enables the doubleSpeed flag which causes MoveProjectile to update position twice per frame.
Properties
public Vector2 Position { get; set; }
Gets or sets the projectile's 2D position. Setting the position updates both the X and Y coordinates and immediately applies the new position to the transform. Getting returns the current X,Y as a Vector2.
public Vector2 Velocity { get; set; }
Gets or sets the projectile's 2D velocity vector. Setting velocity updates both xI and yI components and recalculates the projectile's rotation to match the new direction. Getting returns xI,yI as a Vector2.
Fields
public bool affectScenery = true
Controls whether this projectile can damage background scenery and doodads. Default is true. When disabled, the projectile passes through destructible background elements without affecting them. Checked in RunDamageBackground method.
public bool canHitGrenades = true
Determines if this projectile can interact with grenades. Default is true. When enabled, the projectile will knock back and potentially damage grenades it encounters. Only applies to projectiles with projectileSize greater than 3.
protected bool canMakeEffectsMoreThanOnce
When enabled, allows MakeEffects to create visual effects multiple times during the projectile's lifetime. Works with hasMadeEffects flag to control whether effects can be repeated for projectiles that hit multiple targets or surfaces.
protected float damageBackgroundCounter
Timer controlling periodic background damage checks. Initialized with a small random negative value (-0.2 to 0) and increments by delta time. When positive, triggers background damage check every 0.033 seconds if affectScenery is enabled.
protected bool damagedBackground
Flag tracking whether this projectile has already damaged background elements. Prevents multiple damage applications to scenery during a single projectile's lifetime. Set to true after first background damage event.
public bool doubleSpeed
Speed multiplier flag that doubles projectile movement when enabled. Set via SetDoubleSpeed method which also caps projectile life at 1 second. Applied in MoveProjectile to effectively move the projectile twice per frame.
public FlickerFader flickPuff
Puff effect prefab created when the projectile damages background scenery or doodads. Instantiated by EffectsController.CreateProjectilePuff during background damage checks to provide visual feedback for environmental destruction.
protected float fullLife = 1f
Original lifetime value stored at projectile initialization. Used with fadeDamage to calculate damage reduction over time and preserved for any mechanics that need to reference the projectile's initial lifetime setting.
protected bool hasHit
Flag indicating the projectile has already hit a target. Set to true on successful collision to prevent multiple hit registrations from the same impact. Ensures projectiles only deal damage once per target.
protected bool hasMadeEffects
Tracks whether visual impact effects have been created. Prevents duplicate effect spawning unless canMakeEffectsMoreThanOnce is enabled. Set to true after first effect creation in MakeEffects method.
public bool isDamageable
Indicates whether this projectile can be damaged and destroyed by attacks. While this field exists in the base class, it is not actively used in the base implementation and is likely intended for derived projectile types that can be shot down.
public float life = 4f
Remaining lifetime of the projectile in seconds. Default value is 4 seconds. Decreases by delta time each frame and destroys the projectile when it reaches zero. Can be modified by SetDoubleSpeed (caps at 1 second) and IncreaseLife methods.
public float projectileSize = 8f
Collision radius of the projectile in units. Default value is 8. Used for all sphere-based collision checks, hit detection radii, and raycast distances. Larger values create projectiles that can hit targets more easily and affect wider areas.
public Shrapnel shrapnel
Shrapnel prefab reference for creating debris particles. While not directly used in the base Projectile class, this field is available for derived projectile types to create custom shrapnel effects on impact.
public Shrapnel shrapnelSpark
Spark shrapnel prefab reference for creating spark particles. While not directly used in the base Projectile class, this field is available for derived projectile types to create custom spark effects, particularly for metal impacts.
protected Sound sound
Lazy-initialized Sound instance for playing projectile audio effects. Created on demand in PlayDeathSound when the projectile is destroyed. Cached to avoid creating multiple Sound objects for the same projectile.
public SoundHolder soundHolder
Reference to the SoundHolder component containing this projectile's sound effects. Used in PlayDeathSound to play impact sounds when the projectile is destroyed. Configured per projectile type for unique audio feedback.
public float soundVolume = 0.2f
Volume level for projectile sound effects. Default value is 0.2f (20% volume). Applied when playing death sounds through the sound holder to control audio levels relative to other game sounds.
public int sparkCount = 10
Number of spark particles created on impact. Default value is 10. Used in MakeEffects to determine how many sparks to generate. Different impact contexts use full count or reduced counts for visual variety.
protected float startProjectileSpeed = 400f
Initial speed magnitude of the projectile when fired. Default 400f but set from velocity vector magnitude in Fire method. Used in collision prediction calculations to determine raycast distances based on projectile speed.
public bool whitePopEffect
Determines the type of impact effect created. When true, creates a white pop effect instead of the standard projectile pop effect. Used in MakeEffects to provide visual variety for different projectile types.
public float z
The projectile's Z-axis position used for rendering depth. Updated during movement to maintain proper visual layering with other game objects.
Projectile Initialization & Configuration
Methods
public virtual void Fire(float newX, float newY, float xI, float yI, float _zOffset, int playerNum, MonoBehaviour FiredBy)
Primary initialization method that launches the projectile. Sets position, velocity, player ownership, and performs comprehensive spawn validation including collision checks, unit hits, and barrier reflections. Applies perk-based scaling for player projectiles and sets appropriate team materials.
Parameters:
- float newX: Starting X position of the projectile
- float newY: Starting Y position of the projectile
- float xI: Initial X velocity
- float yI: Initial Y velocity
- float _zOffset: Z-axis offset for rendering depth
- int playerNum: Player number who fired the projectile (0-3 for players, -1 for enemies)
- MonoBehaviour FiredBy: Reference to the unit that fired this projectile
public virtual float GetSuggestedSpeed()
Returns the suggested default speed for projectiles, used as a baseline for velocity calculations. Standard projectiles return 120 units per second.
Returns:
float
: The suggested projectile speed (120f)
public virtual void SetDamage(int d)
Sets the projectile's damage value, updating both the internal damage tracking and the public damage field used for display and calculations.
Parameters:
- int d: The damage value to set
public virtual void SetPosition()
Updates the projectile's transform position using rounded X and Y coordinates with the configured z-offset for proper rendering depth.
protected virtual void SetRotation()
Calculates and applies rotation to the projectile's transform based on its current velocity. Uses atan2 to determine angle from velocity vector and converts to degrees. Applies an additional 180-degree rotation for horizontal projectiles.
public void SetSeed(int newSeed)
Sets the random seed for this projectile, creating a new Randomf instance with the specified seed for deterministic random behavior in effects and variations.
Parameters:
- int newSeed: The seed value for random number generation
public override void SetSpeed(float xI, float yI)
Updates the projectile's velocity vector and recalculates its rotation to match the new direction of travel.
Parameters:
- float xI: New X velocity component
- float yI: New Y velocity component
Fields
public bool canReflect = true
Controls whether this projectile can be reflected by barriers. Default is true. When disabled, projectile ignores barrier collision checks that would normally cause reflection. Used to create projectiles that pass through or are destroyed by barriers instead of bouncing off.
public Material enemyMaterial
Material applied to enemy-fired projectiles for visual team identification. Set through CheckFriendlyFireMaterial when playerNum is negative. Creates visual distinction between projectiles that can harm the player versus those that cannot.
public Material friendlyMaterial
Material applied to player-fired projectiles for visual team identification. Set through CheckFriendlyFireMaterial when playerNum is 0 or greater. Helps players distinguish between friendly and enemy projectiles at a glance.
public bool horizontalProjectile = true
Determines raycast behavior for collision detection. Default is true. When true, uses offset raycasts from projectile sides for barrier detection. When false, uses direct center raycasts. Affects how projectiles interact with barriers and walls.
public bool isWideProjectile
Indicates if this is a wide projectile that requires special collision handling. When true, skips horizontal wall collision checks. Used in conjunction with horizontalProjectile to determine appropriate collision detection methods.
Collision Detection & Spawn Validation
Methods
protected virtual void CheckSpawnPoint()
Comprehensive spawn point validation that checks for walls, doodads, return zones, barriers, and units at the projectile's starting position. Handles barrier reflections for both enemy and friendly projectiles, destroys projectile if spawning inside solid objects, and attempts to hit units at spawn location. Registers projectile with Map system if spawn is valid.
protected virtual void CheckSpawnPointFragile()
Checks for fragile/destructible objects at spawn location using a 5-unit radius sphere overlap. Creates puff effects and applies damage to all fragile objects found, but does not destroy the projectile.
protected virtual bool CheckWallsAtSpawnPoint()
Checks for wall collisions at the projectile's spawn position using a 5-unit radius sphere overlap. Applies damage to any walls found (excluding the firing unit's collider) and destroys the projectile if walls are hit, creating appropriate impact effects.
Returns:
bool
: True if walls were hit and projectile was destroyed, false otherwise
protected virtual void TryHitUnitsAtSpawn()
Attempts to damage units at the projectile's spawn location. Handles special case for inseminator units (alien face huggers) by targeting their host unit with double damage. Destroys projectile with effects if any units are successfully hit.
Fields
protected RaycastHit raycastHit
Stores the result of raycast collision detection operations. Contains hit point, surface normal, collider reference, and other collision data used for creating effects, calculating reflections, and applying damage at the correct position and angle.
Special Projectile Behaviors
Methods
public virtual void AvoidRect(Transform avoidTransform, float avoidWidth, float avoidHeight)
Virtual method for implementing projectile avoidance behavior around rectangular areas. Base implementation is empty - derived projectile types override this to steer around obstacles.
Parameters:
- Transform avoidTransform: Transform of the rectangle to avoid
- float avoidWidth: Width of the avoidance area
- float avoidHeight: Height of the avoidance area
protected virtual void CheckFriendlyFireMaterial()
Updates the projectile's visual material based on team affiliation. Player projectiles (playerNum >= 0) use the friendly material if available, while enemy projectiles use the enemy material. Helps players identify projectile ownership visually.
protected virtual bool CheckReturnZones()
Scans for nearby ProjectileReturnZones that can capture and reverse this projectile. Only captures enemy projectiles (playerNum -1) within 64 units of an active zone. Initiates reversal behavior when a valid zone is found.
Returns:
bool
: True if the projectile was captured by a return zone, false otherwise
protected virtual bool IsHeldByZone()
Checks if this projectile is currently being held and reversed by a return zone. Returns true when the projectile has an active zone reference and is in reversing state.
Returns:
bool
: True if held by a return zone, false otherwise
protected virtual void ReverseProjectile()
Initiates projectile reversal toward its firing unit. Sets reverse velocity targets to 80% of negative initial velocity, creating a boomerang effect. Only reverses if the original firing unit still exists.
protected virtual void RunReversing()
Handles projectile reversal behavior when captured by return zones. Gradually adjusts velocity toward the zone's return point using interpolation. Destroys the projectile when it gets within 16 units of the target position.
public virtual void Target(float targetX, float targetY, int playerNum)
Virtual method for implementing projectile targeting behavior. Base implementation is empty - guided projectile types override this to track toward specified coordinates.
Parameters:
- float targetX: X coordinate of the target position
- float targetY: Y coordinate of the target position
- int playerNum: Player number associated with the targeting
Properties
public virtual bool StopBeingControlled { get; set; }
Virtual property that indicates whether the projectile should stop being controlled by external systems. Base implementation always returns false, but can be overridden by guided projectiles to signal when they should stop tracking targets.
Fields
public bool giveDeflectAchievementOnMookKill
When enabled, awards the "bronald_bradman" achievement if this deflected projectile kills an enemy. Checked in HitUnits when the projectile successfully damages a target. Used to track player skill in deflecting enemy projectiles back at enemies.
protected float heldDelay
Random delay before reversed projectile starts moving. Set to 0-0.333 seconds when caught by a return zone. Decrements each frame in RunReversing, creating a brief pause before the projectile reverses direction.
protected float reverseXI
Target X velocity for projectile reversal. Set to 80% of negative current X velocity when reversal begins. Used in RunReversing for smooth interpolation from current to reversed trajectory.
protected float reverseYI
Target Y velocity for projectile reversal. Set to 80% of negative current Y velocity when reversal begins. Used in RunReversing for smooth interpolation from current to reversed trajectory.
protected bool reversing
Indicates the projectile is being reversed by a return zone (like Brondleman's ability). Set to true when captured by a ProjectileReturnZone. Triggers special movement behavior in RunReversing that gradually redirects the projectile.
protected ProjectileReturnZone zone
Reference to the ProjectileReturnZone currently controlling this projectile. Set when the projectile enters a return zone's area of effect. Used to determine if the projectile should continue reversing behavior or has escaped the zone's influence.
Helper & Utility
Methods
protected virtual void DeregisterProjectile()
Removes this projectile from the Map's projectile tracking system, typically called during cleanup when the projectile is destroyed.
protected virtual void RegisterProjectile()
Registers this projectile with the Map's projectile tracking system, allowing it to be found by other game systems for collision detection and effects.