Detonator Asset — ItemDetonatorAsset
Setting up remote-controlled explosives in Unturned depends on understanding how the detonator pairs with charges, validates multiple simultaneous detonations through raycast and range checks, and triggers InteractableCharge.detonate() across the network. The detonator is a handheld device used to remotely trigger ItemChargeAsset barricades. ItemDetonatorAsset inherits from ItemAsset and is minimal (27 lines) because its behavior is driven entirely by the UseableDetonator class and the InteractableCharge component on placed charges.
Source code location: Unturned/Items/ItemDetonatorAsset.cs, Unturned/Useable/UseableDetonator.cs
Inheritance Chain
ItemAsset
→ ItemDetonatorAssetAsset Structure
csharp
public class ItemDetonatorAsset : ItemAsset
{
protected AudioClip _use; // Bundle "Use"
public override bool shouldFriendlySentryTargetUser => true;
}PopulateAsset
csharp
public override void PopulateAsset(in PopulateAssetParameters p)
{
base.PopulateAsset(in p);
_use = p.bundle.load<AudioClip>("Use");
}All detonator behavior is in the useable class. The asset only needs:
- The
Useaudio clip (plays when activating/detonating). - The
shouldFriendlySentryTargetUser = trueflag (hardcoded). - Standard
ItemAssetfields (name, description, size, rarity, etc.).
Sentry Hostility
shouldFriendlySentryTargetUser always returns true. Holding a detonator marks the player as hostile to friendly sentries. This prevents the exploit where a player holds a detonator near a sentry without triggering hostile response while having paired charges ready to detonate.
UseableDetonator
Pairing Mode
- Right-click near a placed charge (
InteractableChargewithEBuild.CHARGE). - A raycast detects charges within interaction range.
- The charge is added to an internal list of paired charges.
- Paired charges are visually highlighted with an outline effect via
HighlighterTool. - Multiple charges can be paired sequentially (up to an implementation-defined limit).
Detonation Mode
- Left-click sends a
DetonateChargeRPC for all currently paired charges. - Each charge is validated: line-of-sight check, range check, ownership check.
- Valid charges detonate simultaneously — each calls its own explosion logic via
InteractableCharge.detonate(). - Invalid charges (destroyed, out of range) are silently removed from the pairing list.
- After detonation, all pairings are cleared.
Detonation Sequence
1. UseableDetonator sends DetonateCharge RPC to server
2. Server validates each paired charge (exists, in range, not detonated)
3. Server calls InteractableCharge.detonate() on each valid charge
4. Each charge spawns detonation effect, applies DamageTool.explode(...)
5. Each charge's barricade drop is destroyedUnpairing
- Pairings are cleared when the detonator is unequipped.
- Individual charges can be unpaired by right-clicking them again (toggles the highlight).
- Pairings are stored in the
UseableDetonatorinstance, which exists only while equipped.
Detonator-Charge Validation
| Check | Requirement |
|---|---|
| Range | Charge must be within interaction range (default 5m) |
| Line of sight | Raycast from player's eyes to charge center must not be blocked |
| Ownership | If claims active, player must own or bypass the charge's claim |
| State | Charge must not have been already detonated |
Charges that fail validation are silently excluded. If all charges fail, the detonator plays a failure click sound.
UI Integration
The detonator provides minimal UI feedback:
- Paired charges: A small icon near the crosshair indicates the number of paired charges.
- Highlight: Paired charges have a colored outline via
HighlighterTool. - Range indicator: Charges outside the effective range flash red.
- Detonation: A visual and audio effect plays when charges detonate.
The UI is driven by UseableDetonator which tracks charge references and updates highlight states each frame.
Charge Two-State Highlight System
csharp
public bool isSelected { get; private set; }
public bool isTargeted { get; private set; }isTargeted: The charge the player is looking at (crosshair aim highlight).isSelected: The charge the player has selected for detonation (persistent highlight).
The visual feedback uses partial void updateHighlight() — platform-specific rendering.
Safezone Restrictions
canBeUsedInSafezone (inherited from ItemAsset) checks safezone.allowsItems. Detonators can be held but not used to detonate in safezones with weapon restrictions. The 2025 update (public issue #5175) extended detonator safezone checks to close an exploit where players used charges to destroy structures in zones that allowed building but not weapons.
Cargo Data Export
No custom Cargo table — ItemDetonatorAsset writes through the standard ItemAsset base.
Worked Code Example: Detonator Integration
Multi-Charge Detonation Scheduler
csharp
using SDG.Unturned;
using System.Collections.Generic;
using UnityEngine;
public class DetonationScheduler : MonoBehaviour
{
private static Queue<DetonationJob> _pendingJobs = new Queue<DetonationJob>();
private static int _maxChargesPerFrame = 8;
public struct DetonationJob
{
public Player instigatingPlayer;
public List<InteractableCharge> charges;
}
/// <summary>
/// Enqueues a detonation job that processes charges in batches
/// of up to 8 per frame to prevent frame hitches from large
/// simultaneous detonations.
/// </summary>
public static void ScheduleDetonation(Player player, List<InteractableCharge> charges)
{
_pendingJobs.Enqueue(new DetonationJob
{
instigatingPlayer = player,
charges = charges
});
}
private void Update()
{
if (_pendingJobs.Count == 0) return;
DetonationJob job = _pendingJobs.Dequeue();
int processedThisFrame = 0;
foreach (InteractableCharge charge in job.charges)
{
if (charge == null) continue;
charge.Detonate(job.instigatingPlayer);
processedThisFrame++;
if (processedThisFrame >= _maxChargesPerFrame)
break;
}
}
}
/// <summary>
/// Scans a region for destructible structures and estimates the
/// number of paired charges needed to achieve complete destruction.
/// </summary>
public static int EstimateChargesForRegion(
Vector3 center, float radius, ItemChargeAsset chargeAsset)
{
int requiredCharges = 0;
Collider[] hitColliders = Physics.OverlapSphere(center, radius);
foreach (Collider col in hitColliders)
{
BarricadeDrop barricade = BarricadeDrop.FindByRootFast(
DamageTool.getBarricadeRootTransform(col.transform));
if (barricade == null) continue;
ItemBarricadeAsset asset = barricade.asset as ItemBarricadeAsset;
if (asset == null || !asset.isVulnerable) continue;
float health = asset.health;
if (barricade.GetServersideData() != null)
{
requiredCharges += Mathf.CeilToInt(
health / chargeAsset.barricadeDamage + chargeAsset.structureDamage
);
}
}
return requiredCharges;
}Mermaid Diagram: Detonator Pairing and Detonation Flow
Comparison: Detonator vs. Other Triggering Methods
| Feature | Detonator (ItemDetonatorAsset) | Timed Fuse (Grenade) | Trip Wire (Trap) | Proximity Sensor (Mod) |
|---|---|---|---|---|
| Trigger method | Manual RPC on left-click | Automatic after fuse delay | Physics trigger enter | Proximity check |
| Multiple simultaneous | Yes (paired charges) | Only by multi-throwing | One per trigger | Area affect |
| Remote distance limit | LOS + 5m for pairing, unlimited for detonation | N/A | N/A | N/A |
| Sentry hostility | Always hostile (hardcoded) | Depends on item | Depends on trap | Depends on mod |
| Pairing persistence | Until unequipped or detonated | N/A | Permanent | Permanent |
| Visual feedback | Charge outline via HighlighterTool | Tracker icon | None | Zone radius vis |
| Ammo required | None (reusable) | None (disposable) | None (reusable) | Battery |
| SafeZone block | Yes (2025 update) | Depends on safezone | Depends on safezone | Depends on mod |
Failure Modes and Common Mistakes
Pairing list lost on weapon swap — Pairings are stored in the
UseableDetonatorinstance, which is destroyed when the player switches to another item. All pairings are lost. Players who swap to a weapon after placing charges, then swap back to the detonator, must re-pair every charge.Silent charge invalidation — If a charge is destroyed (by enemy fire, structure demolition, or server cleanup) while paired, it is silently removed from the pairing list. The UI charge count decrements but no notification is given. A player may believe they have 10 charges paired when only 6 remain due to destroyed charges.
Detonating while looking away — The detonator does not require the player to be looking at the charges. A player can pair charges, turn 180 degrees, and detonate them while looking at the sky. This creates confusion about whether line-of-sight is needed during detonation (it's not — only during pairing).
Detonator sentry flag in PvE servers —
shouldFriendlySentryTargetUser = trueis hardcoded. On PvE servers where friendly sentries exist, simply equipping a detonator (even with no charges placed) causes sentries to shoot. PvE players unaware of this flag may equip a detonator for inventory management and be killed by their own sentry.Rate-limiting gap for charge spam — There is no server-side rate limit on charge pairing. A player can pair 50 charges in rapid succession by right-clicking quickly across a field of charges. The server processes each pairing RPC individually, potentially creating a burst of ~50 RPCs in under a second.
How This Field Behaves Differently from the SDG Docs
SDG docs describe detonators as "consumable" items. Community resources sometimes list the detonator as one-time-use like the charge itself. In the SDK,
ItemDetonatorAssetis a standardItemAssetwith no durability, no ammo counter, and noshouldDeleteAfterUse. It is infinitely reusable — only the charges are consumable barricades.SDG docs state detonator has a "frequency" or "channel" system. Some documentation suggests detonators have configurable frequency settings to prevent cross-detection. In the SDK, there is no frequency or channel system. Any detonator can pair with any charge placed by any player within range — pairing is based on raycast proximity, not a frequency match.
SDG docs claim detonator requires a battery. The wiki discussion references detonators requiring power cells or batteries. In the SDK,
ItemDetonatorAssethas no battery slot, no power consumption, and no charge count. The detonator is purely mechanical in implementation (play sound, send RPC).SDG docs mention a "detonation radius multiplier" for charge count. Community guides suggest longer charge chains increase blast radius. In the SDK, each charge detonates independently with its own
_range2value. There is no radius scaling based on the number of paired charges. A single charge at 10m range and 10 charges at 10m range all explode with a 10m radius individually.
Performance Considerations
Pairing Iteration Cost
Each frame, UseableDetonator loops through paired charges to update their isTargeted and isSelected highlight states. With 50 paired charges, this is 50 per-frame update calls — approximately 0.05ms. On a 60 FPS client, this is negligible.
RPC Batching
The DetonateCharge RPC sends a list of charge transform references. With 50 charges, the RPC payload size is approximately 50 × 16 (transform network ID) = 800 bytes. This fits within a single reliable RPC packet (approx 1200 bytes max for Steam Networking).
State Storage
The detonator's pairing list stores transform references (8 bytes each) plus highlight state booleans (1 byte each). With 50 paired charges, client-side memory is approximately 450 bytes — negligible.
Deeper FAQ
Q: Can I detonate charges across the map?
Yes, once paired. The pairing requires proximity (5m, line-of-sight), but detonation has no distance limit. A player can pair charges at Location A, travel to Location B across the map, and detonate the charges from Location B. The server processes the detonation at the charges' positions regardless of the player's current location.
Q: Are charge pairings saved when the server restarts?
No. Pairings are stored in the UseableDetonator runtime instance, which exists only while the detonator is equipped and is destroyed on unequip. If the server restarts while a player has charges paired, the pairings are lost and must be re-established after restart. This can be disorienting if the server restarts mid-raid.
Q: What audio cue confirms successful charge pairing?
The _use AudioClip plays on right-click pairing attempt. The same audio plays for both successful pairing and un-pairing. There is no distinct "paired" vs. "unpaired" audio cue. Players must rely on the visual highlight to confirm pairing state.
Q: Can I pair charges placed by another player in my group?
Yes, if the charges have claim bypass active (default for ItemChargeAsset) or if you are in the same group as the charge owner. The BarricadeManager check during pairing uses the standard ownership validation, not exclusive charge-placement-ownership. A group member can pair another member's charges as long as claim or group rules allow interaction.
Cross-References
- Charge Explosive Asset — ItemChargeAsset — The charge asset that detonators pair with and trigger.
- Interactable Trap — Trigger Damage System — Automated trap defense compared to manual remote detonation.
- User Interface — Server Browser UI — UI patterns for multi-selection toggles similar to charge pairing.
- Sentry Asset — Sensor-based detection system that also uses per-player hostility tracking.
