Grenade Asset — ItemThrowableAsset
Mastering throwable weapon mechanics in Unturned — from timed fragmentation grenades to sticky C4 variants, flashbang crowd control, and impact-triggered explosives — depends on understanding how ItemThrowableAsset inherits the weapon damage multiplier system while adding fuse timing, throw physics force values, and four explosive type flags that determine detonation behavior. ItemThrowableAsset inherits from ItemWeaponAsset, reusing the damage table infrastructure for explosive throwables. It defines grenades, flashbangs, sticky grenades, impact grenades, smoke grenades, flares, and other hand-launched projectiles.
Source code location: Unturned/Items/ItemThrowableAsset.cs
Inheritance Chain
ItemAsset
→ ItemWeaponAsset
→ ItemThrowableAssetInheriting from ItemWeaponAsset gives throwables access to playerDamageMultiplier, zombieDamageMultiplier, animalDamageMultiplier, range, and the BuildExplosiveDescription / BuildNonExplosiveDescription helper methods.
Throwable Prefab and Audio
| Field | Type | Source |
|---|---|---|
_throwable | GameObject | Bundle "Throwable" — the physics projectile |
_use | AudioClip | Bundle "Use" — sound played on throw release |
The throwable prefab is instantiated at the player's hand position and launched with Rigidbody.AddForce. It must have a Rigidbody and Collider. The prefab carries the appropriate throwable behavior component (Grenade, Flashbang, StickyGrenade, ImpactGrenade, etc.).
Explosive Type Flags
Four boolean flags define detonation behavior:
| Flag | .dat Key | Description |
|---|---|---|
_isExplosive | Explosive | Radial damage on detonation using weapon damage multipliers |
_isFlash | Flash | Blind and deafen nearby players |
_isSticky | Sticky | Attaches to surfaces on contact using OnCollisionEnter |
_explodeOnImpact | Explode_On_Impact | Detonates immediately on collision, no fuse wait |
Flag Combinations
| Flags | Behavior |
|---|---|
_isSticky | _isExplosive | Sticky grenade |
_isSticky | _isFlash | Sticky flashbang |
_explodeOnImpact | _isExplosive | Impact grenade |
_isFlash only | Flashbang (no damage) |
| None | Smoke grenade or flare |
When any of explosive/flash/impact is true, shouldFriendlySentryTargetUser returns true. Pure smoke/flare throwables are considered non-hostile.
Fuse Timing
fuseLength controls the delay between release and detonation:
| Condition | Default |
|---|---|
Custom Fuse_Length set | Parsed float value |
isExplosive or isFlash | 2.5 seconds |
| Neither (smoke/flare) | 180 seconds (3 minutes) |
The fuse timer starts on release, not on collision. Impact grenades ignore the fuse entirely.
Throw Physics
| Field | Type | Default | Description |
|---|---|---|---|
strongThrowForce | float | 1100 | Primary-throw force in Newtons |
weakThrowForce | float | 600 | Secondary-throw underhand force |
boostForceMultiplier | float | 1.4 | Sprint-throw multiplier |
The throw trajectory:
- Launch direction = camera forward + upward pitch offset.
AddRelativeForce(throwForce * direction, ForceMode.Impulse).- Spin torque for visual rotation.
- Standard
Physics.gravityaffects the arc. - Boosted throws only while sprinting.
Explosion Parameters
| Field | Type | Description |
|---|---|---|
explosionEffectGuid / _explosion | Guid + ushort | Explosion effect reference |
explosionLaunchSpeed | float | Physics launch velocity for blast impulse |
The explosion effect is instantiated at the detonation point. DamageTool.explode(...) applies damage using:
playerDamageMultiplier,zombieDamageMultiplier,animalDamageMultiplier,barricadeDamage,structureDamage,vehicleDamage,resourceDamage,objectDamagefromItemWeaponAsset.rangeas the blast radius.explosionLaunchSpeedfor the physics impulse.
Explosion Damage Calculation
csharp
DamageTool.explode(new ExplosionParameters(...)
{
playerDamage = playerDamageMultiplier.damage,
zombieDamage = zombieDamageMultiplier.damage,
animalDamage = animalDamageMultiplier.damage,
barricadeDamage = barricadeDamageMultiplier.damage,
structureDamage = structureDamageMultiplier.damage,
vehicleDamage = vehicleDamageMultiplier.damage,
resourceDamage = resourceDamageMultiplier.damage,
objectDamage = objectDamageMultiplier.damage,
range = this.range,
launchSpeed = explosionLaunchSpeed,
});Linear falloff from epicenter to range. Entities at exactly range take 0 damage.
Impact Behavior
ExplodeOnImpactDestroyOnClient (default false):
- true: Clients destroy the throwable immediately on collision (more responsive).
- false: Clients keep the prefab alive until server confirms detonation (backwards compatibility).
Impact grenades use collision velocity threshold: relative velocity > 1 m/s triggers detonation. Slow rolling along ground does not trigger.
Concrete Throwable Behaviors
Grenade (standard explosive)
- Attached when
_isExplosive && !_isSticky && !_explodeOnImpact. - Starts fuse timer on
Start()after being thrown. - On fuse complete: plays explosion effect, calls
DamageTool.explode, destroys self. - Bounces with configurable bounciness from the prefab's physics material.
Flashbang
- Attached when
_isFlash && !_isSticky && !_explodeOnImpact. - Full-screen white flash overlay with configurable duration.
- Loud deafening audio effect.
- Duration inversely proportional to distance from epicenter.
- Zombies within
rangeare stunned for the flash duration.
StickyGrenade
- Attached when
_isSticky && (_isExplosive \|\| _isFlash). - On
OnCollisionEnter: attaches transform to contact surface. - Disables rigidbody gravity and sets
isKinematic. - Fuse timer continues after sticking.
- If parent object is destroyed, falls with gravity until next collision.
ImpactGrenade
- Attached when
_explodeOnImpact. - On
OnCollisionEnter: immediately detonates. - Fuse timer not started — instantaneous on collision.
- Used for rocket-propelled grenades and contact explosives.
The UseableThrowable Launch Sequence
- Equip: Throwable prefab loaded from
ItemThrowableAsset._throwable. - Pull pin: Left-click starts throw animation; fuse starts on release, not pull.
- Aim: Camera forward determines trajectory.
- Release: Prefab instantiated at hand position,
AddForce(throwForce * direction), fuse starts. - Boost: Sprinting applies
boostForceMultiplier. - Physics: Parabolic arc under
Physics.gravity. - Detonation: Trigger behavior (fuse, impact, sticky) fires.
- Cleanup: GameObject destroyed; explosion effect spawned.
Network Synchronization
Client: "I'm throwing a grenade at position X with velocity V"
Server: "Confirmed, start fuse timer. Result at T+2.5s"
Client: (predicts explosion at T+2.5s)
Server: "Grenade detonated at T+2.5s, all clients explode"Server-authoritative timer with client prediction. Late-joining players see explosion if still playing but receive no damage.
Description UI
BuildDescription displays:
- "Flash" tag if
_isFlash(green,DescSort_Important). - "Sticky" tag if
_isSticky(green). - "Explodes on Impact" tag if
_explodeOnImpact(green). - Fuse length in seconds if explosive or flash.
- Explosive damage table via
BuildExplosiveDescriptionif_isExplosive.
Safezone Restrictions
canBeUsedInSafezone returns false when safezone.noWeapons is true. All throwables blocked in weapon-restricted safezones. Non-weapon safezones allow throwables.
Prefab Requirements
| Requirement | Reason |
|---|---|
Rigidbody | Physics simulation for parabolic arc |
Collider | Surface interaction (bounce, stick, impact) |
TriggerGrenadeBase component | Detonation logic |
| Trail renderer (optional) | Visual arc in flight |
| Particle system (optional) | Explosion effect |
Cargo Data Export
Writes to the Throwable Cargo table through its ItemWeaponAsset base.
Writes to the Throwable Cargo table through its ItemWeaponAsset base.
Worked Code Example: Custom Throwable Behavior
csharp
using SDG.Unturned;
using UnityEngine;
public static class ThrowableBehaviorController
{
/// <summary>
/// Creates a throwable with custom fuse time, overriding the asset's
/// default fuse length. Useful for skill-based throwable modification.
/// </summary>
public static void ThrowWithCustomFuse(
ItemThrowableAsset throwable,
Player player,
float customFuseLength,
Vector3 direction
)
{
GameObject throwableObj = GameObject.Instantiate(
throwable.throwable, player.look.aim.position, Quaternion.identity
);
Rigidbody rb = throwableObj.GetComponent<Rigidbody>();
if (rb != null)
{
float force = player.movement.isSprinting
? throwable.strongThrowForce * throwable.boostForceMultiplier
: throwable.strongThrowForce;
rb.AddForce(direction * force, ForceMode.Impulse);
}
Grenade grenadeComponent = throwableObj.GetComponent<Grenade>();
if (grenadeComponent != null)
grenadeComponent.Invoke("Explode", customFuseLength);
}
}Mermaid Diagram: Throwable Launch Sequence
Comparison: Throwable Types by Flag Combination
| Flags Set | Class | Behavior | Fuse | Sticks | Damages Players | Damages Structures |
|---|---|---|---|---|---|---|
_isExplosive | Grenade | Radial damage | 2.5s | No | Yes | Yes |
_isFlash | Flashbang | Blinding + deafening | 2.5s | No | No (stun only) | No |
_isSticky + _isExplosive | StickyGrenade | Attaches to surface | 2.5s | Yes | Yes | Yes |
_explodeOnImpact + _isExplosive | ImpactGrenade | Instant on collision | None | No | Yes | Yes |
| None | Smoke/Flare | Non-lethal visual | 180s | No | No | No |
How This Differs from SDG Docs
- SDG docs describe grenade throw force as "configurable per grenade." Community resources suggest per-throwable force values. In the SDK,
strongThrowForce,weakThrowForce, andboostForceMultiplierare asset-level fields shared by all throwables. Per-grenade customization requires per-asset values. - SDG docs claim smoke grenades are non-explosive. The wiki lists smoke as a separate item category. In the SDK, smoke is a throwable with no flags set (no explosive, flash, sticky, or impact). It is handled by a separate
SmokeMonoBehaviour but shares the throwable asset base. - SDG docs reference "fragmentation" as a damage type. Community discussion mentions fragmentation damage vs. blast damage. In the SDK,
DamageTool.explodeapplies uniform radial damage with linear falloff — there is no fragmentation sub-type.
Performance Considerations
Each throwable instantiation creates a GameObject with Rigidbody, Collider, and a behavior component. Object pooling is not used — each throw is a fresh instantiate. With rapid grenade spam (5 throws/second from 10 players), this generates 50 GameObject.Instantiate calls per second. Each explosion performs one Physics.OverlapSphere. This is acceptable on modern hardware but may cause stuttering on lower-end servers during heavy firefights.
Deeper FAQ
Q: Can the fuse timer be cancelled mid-throw?
No. Once the throwable leaves the player's hand (prefab instantiated and force applied), the fuse starts on the server. There is no "catch grenade" or "defuse" mechanic.
Q: What determines flashbang duration per player?
Flash duration is inversely proportional to distance from the flashbang epicenter. A player at the center gets full bright + full deaf; a player at range gets minimal effect. The formula is 1 - (distance / range).
Q: Can throwables damage the thrower?
Yes. DamageTool.explode applies damage to all entities in the blast radius, including the thrower. There is no self-damage reduction or friendly fire exclusion.
Cross-References
- Charge Explosive Asset — ItemChargeAsset — Placed explosives vs. thrown explosives comparison.
- Detonator Asset — ItemDetonatorAsset — Remote detonation vs. timed fuse comparison.
- ItemCaliberAsset — Weapon Mod Base Class — The damage multiplier system inherited by
ItemWeaponAsset. - Interactable Trap — Trigger Damage System — Static trap damage vs. thrown damage comparison.
