ItemBarrelAsset — Barrel Attachments
Advanced30-45 minutesWindowsVisual Studio
Customizing weapon audio profiles, ballistic properties, and recoil behavior in Unturned starts with understanding how barrel attachments override the shooting sound, apply silencer/brake flags, and integrate with the inherited caliber stat modifier system. ItemBarrelAsset defines muzzle attachments that modify a weapon's sound profile, recoil, and ballistic properties. It inherits from ItemCaliberAsset, inheriting a full stat modifier system for recoil, spread, sway, shake, firerate, damage, bullet drop, ADS speed, and movement.
Source code location: Unturned/Bundles/ItemBarrelAsset.cs
Inheritance Chain
ItemAsset
→ ItemCaliberAsset
→ ItemBarrelAssetItemCaliberAsset provides the shared stat modifier system and caliber compatibility checking used by all five attachment types. ItemBarrelAsset adds sound modification, durability, and visual prefab loading on top of that base.
Class Definition
csharp
public class ItemBarrelAsset : ItemCaliberAsset
{
protected AudioClip _shoot;
public AudioClip shoot => _shoot;
protected GameObject _barrel;
public GameObject barrel => _barrel;
private bool _isBraked;
public bool isBraked => _isBraked;
private bool _isSilenced;
public bool isSilenced => _isSilenced;
private float _volume;
public float volume => _volume;
private byte _durability;
public byte durability => _durability;
public override bool showQuality => durability > 0;
[Obsolete("Moved to ItemCaliberAsset.BallisticGravityMultiplier")]
public float ballisticDrop => BallisticGravityMultiplier;
public float gunshotRolloffDistanceMultiplier { get; protected set; }
}Core Fields
Barrel Sound and Visual
| Field | Type | .dat Key | Default | Description |
|---|---|---|---|---|
_shoot | AudioClip | Bundle "Shoot" | — | Override shooting sound |
_barrel | GameObject | Bundle "Barrel" | — | Barrel attachment prefab |
The barrel prefab is loaded via loadRequiredAsset<GameObject>(p.bundle, "Barrel"). The _shoot AudioClip replaces the gun's default firing sound when this barrel is attached.
Sound Suppression
| Field | Type | .dat Key | Default | Description |
|---|---|---|---|---|
_isSilenced | bool | Silenced (flag) | false | Suppressor: reduces sound and flash |
_volume | float | Volume | 1.0 | Sound volume multiplier |
gunshotRolloffDistanceMultiplier | float | Gunshot_Rolloff_Distance_Multiplier | 0.5 (if silenced) / 1.0 | Sound distance multiplier |
When isSilenced is true, the default gunshotRolloffDistanceMultiplier drops to 0.5, halving the maximum distance the gunshot can be heard. The Volume key provides an additional volume reduction. The suppressed barrel also hides muzzle flash in-game.
Recoil Compensation
| Field | Type | .dat Key | Default | Description |
|---|---|---|---|---|
_isBraked | bool | Braked (flag) | false | Compensator: indicates the barrel reduces recoil |
The isBraked flag is a boolean. When true, the barrel has compensator/brake visual styling. The actual recoil reduction comes from the _recoil_x and _recoil_y fields inherited from ItemCaliberAsset — setting Recoil_X and Recoil_Y below 1.0 in the .dat reduces horizontal and vertical recoil respectively.
Durability and Quality
| Field | Type | .dat Key | Default | Description |
|---|---|---|---|---|
_durability | byte | Durability | 0 | Barrel durability (0 = infinite, 1-100 = degradable) |
The showQuality override returns true when durability > 0. A durability value of 0 means the barrel never degrades. Values 1-100 create a barrel that wears down with use — at 0 quality it provides no stat benefits.
The quality of the barrel is stored at byte offset 16 of the gun's 18-byte state array.
PopulateAsset
csharp
public override void PopulateAsset(in PopulateAssetParameters p)
{
base.PopulateAsset(in p);
_shoot = p.bundle.load<AudioClip>("Shoot");
_barrel = loadRequiredAsset<GameObject>(p.bundle, "Barrel");
_isBraked = p.data.ContainsKey("Braked");
_isSilenced = p.data.ContainsKey("Silenced");
_volume = p.data.ParseFloat("Volume", defaultValue: 1.0f);
_durability = p.data.ParseUInt8("Durability");
float defaultGunshotRolloffDistanceMultiplier = isSilenced ? 0.5f : 1.0f;
gunshotRolloffDistanceMultiplier = p.data.ParseFloat(
"Gunshot_Rolloff_Distance_Multiplier",
defaultValue: defaultGunshotRolloffDistanceMultiplier);
}Both isBraked and isSilenced are parsed as flag presence (ContainsKey), not as boolean values. The gunshotRolloffDistanceMultiplier defaults to 0.5 for silenced barrels and 1.0 for non-silenced. The Volume key provides an audio level adjustment separate from the rolloff distance.
Inherited Stat Modifiers (ItemCaliberAsset)
Since ItemBarrelAsset extends ItemCaliberAsset, it inherits all stat modifiers. The following fields are available on every barrel asset and can be set in the .dat file.
Direct Recoil Modification
| Field | .dat Key | Default | Description |
|---|---|---|---|
recoil_x | Recoil_X | 1.0 | Horizontal recoil multiplier |
recoil_y | Recoil_Y | 1.0 | Vertical recoil multiplier |
aimingRecoilMultiplier | Aiming_Recoil_Multiplier | 1.0 | ADS recoil modifier |
A compensator barrel would typically set Recoil_X and Recoil_Y below 1.0 (e.g., 0.8 for 20% reduction).
Spread and Accuracy
| Field | .dat Key | Default | Description |
|---|---|---|---|
spread | Spread | 1.0 | Spread angle multiplier |
sway | Sway | 1.0 | Weapon sway multiplier |
shake | Shake | 1.0 | Camera shake multiplier |
ADS and Movement
| Field | .dat Key | Default | Description |
|---|---|---|---|
aimDurationMultiplier | Aim_Duration_Multiplier | 1.0 | ADS speed modifier |
aimingMovementSpeedMultiplier | Aiming_Movement_Speed_Multiplier | 1.0 | ADS movement speed modifier |
Damage and Ballistics
| Field | .dat Key | Default | Description |
|---|---|---|---|
ballisticDamageMultiplier | Ballistic_Damage_Multiplier or Damage | 1.0 | Bullet damage multiplier |
BallisticGravityMultiplier | Ballistic_Drop | 1.0 | Bullet drop multiplier |
FirerateOffset | Firerate | 0 | Firerate adjustment (positive = faster) |
The Damage key is a legacy fallback — when Ballistic_Damage_Multiplier was added to all attachment types, the existing barrel-only Damage key was kept as a fallback default.
Caliber Compatibility
| Field | .dat Key | Default | Description |
|---|---|---|---|
calibers | Calibers / Caliber_N | — | Compatible caliber IDs |
isPaintable | Paintable | false | Can receive cosmetic paint |
The CalibersContainId(ushort) and CalibersContainAnyOfIds(ushort[]) methods check compatibility against the gun's attachmentCalibers.
Special Flags
| Field | .dat Key | Default | Description |
|---|---|---|---|
ShouldOnlyAffectAimWhileProne | Bipod | false | Bipod: only affects ADS while prone |
CanDamageInvulernableEntities | Invulnerable | false | Can damage invulnerable-tagged entities |
shouldDestroyAttachmentColliders | Destroy_Attachment_Colliders | true | Remove colliders from attachment prefab |
instantiatedAttachmentName | Instantiated_Attachment_Name_Override | GUID | Prefab name override for legacy animation |
Description UI
ItemBarrelAsset does not override BuildDescription — it relies entirely on ItemCaliberAsset.BuildDescription. The caliber base renders each non-default stat modifier with color coding:
- Positive effects (lower recoil, tighter spread) appear in green.
- Negative effects (higher recoil, wider spread) appear in red.
- Unchanged stats (value = 1.0) are omitted.
Cargo Data Export
BuildCargoData writes to the Barrel Cargo table with the barrel-specific fields, then delegates to ItemCaliberAsset.BuildCargoData for the shared caliber fields:
csharp
CargoDeclaration data = builder.GetOrAddDeclaration("Barrel");
data.Append("GUID", GUID);
data.Append("Braked", isBraked);
data.Append("Silenced", isSilenced);
data.Append("Volume", volume);
data.Append("Durability", durability);
data.Append("Gunshot_Rolloff_Distance_Multiplier", gunshotRolloffDistanceMultiplier);The base class appends to the Caliber table with all stat modifier values and caliber IDs.
Attachment Integration
When a barrel is attached to a gun, UseableGun applies its modifiers to the weapon's runtime stats:
- Sound override:
_shootreplaces the gun's firing sound. - Volume reduction:
_volumescales the AudioSource volume. - Rolloff reduction:
gunshotRolloffDistanceMultiplierscalesgunshotRolloffDistance. - Stat modifiers: All
ItemCaliberAssetmodifiers multiply the gun's base values. - Prefab instantiation: The
_barrelGameObject is instantiated and parented to the weapon's barrel hook.
The prefab is loaded from the asset bundle as "Barrel" and attached to the gun's Hook_Barrel transform. The shouldDestroyAttachmentColliders flag (default true) removes colliders from the instantiated prefab to avoid physics interference.
Common Issues
- Silenced vs Braked conflict — Both flags can be set simultaneously, which is unintuitive. A barrel with both
SilencedandBrakedgets the suppressed rolloff and visual while also potentially reducing recoil — this may not match player expectations. - Volume without Silenced — Setting
VolumewithoutSilencedreduces the sound level without muzzle flash suppression. This creates a quieter but still visible weapon, which may be intentional (subsonic ammo simulation) or an oversight. - Durability without value — Adding
Durabilityto the.datwithout specifying a value parses as 0 (infinite durability). The key's presence alone doesn't enable durability tracking. - ballisticDrop depreciation — The
ballisticDropproperty is marked[Obsolete]and redirects toItemCaliberAsset.BallisticGravityMultiplier. It was renamed because it actually multiplies gravity rather than providing a raw drop value. - Gunshot rolloff stacking — The barrel's
gunshotRolloffDistanceMultipliermultiplies the gun'sgunshotRolloffDistance. A silent barrel (0.5) on a rocket launcher (64m) produces 32m audible range. On a standard gun (512m) it produces 256m — still quite audible.
Worked Code Example: Barrel Audio Analyzer
csharp
using SDG.Unturned;
using UnityEngine;
public static class BarrelAudioAnalyzer
{
/// <summary>
/// Calculates the effective audible range of a gunshot after barrel
/// modifications, factoring in the gun's base rolloff and the
/// barrel's multiplier. Returns distance in meters.
/// </summary>
public static float GetEffectiveGunshotRange(
ItemGunAsset gun, ItemBarrelAsset barrel)
{
float baseRolloff = gun.gunshotRolloffDistance;
float barrelMultiplier = barrel != null
? barrel.gunshotRolloffDistanceMultiplier
: 1f;
return baseRolloff * barrelMultiplier;
}
/// <summary>
/// Returns the decibel attenuation at a given distance,
/// useful for AI hearing range calculations.
/// </summary>
public static float GetAttenuationAtDistance(
ItemGunAsset gun, ItemBarrelAsset barrel, float distance)
{
float maxRange = GetEffectiveGunshotRange(gun, barrel);
if (distance >= maxRange) return 0f;
return 1f - (distance / maxRange);
}
}Mermaid Diagram: Barrel Audio Pipeline
Comparison: Barrel Types
| Barrel Type | isSilenced | isBraked | Volume | Rolloff Multiplier | Best For |
|---|---|---|---|---|---|
| Standard | false | false | 1.0 | 1.0 | Default config |
| Suppressed | true | false | 0.5 | 0.5 | Stealth/PvP |
| Compensated | false | true | 1.2 | 1.0 | Recoil control |
| Flash Hider | false | false | 1.0 | 1.0 | PvP concealment |
| Hybrid | true | true | 0.7 | 0.5 | Stealth + control |
Failure Modes and Common Mistakes
Braked + Silenced combo misleading — Both flags set creates a barrel that is quieter (silenced) AND reduces recoil (braked). Players may craft this expecting both benefits, but the
Volumekey must also be set below 1.0 for full silencing effect.Durability with silenced barrel — A durable barrel on a silenced weapon degrades the silencer's effectiveness over use (the
Volumemultiplier drifts toward 1.0). Players unaware of durability may think their silencer broke when it just wore down.
How This Field Behaves Differently from the SDG Docs
- SDG docs describe Braked as "muzzle brake." Community resources list "Muzzle Brake" as a separate item type. In the SDK,
isBrakedis a boolean flag on any barrel, not a dedicated item. Any barrel can be braked by setting theBrakedkey. - SDG docs claim durability is shown in UI. Some documentation suggests durability displays as a bar. In the SDK,
showQualityreturnsdurability > 0, but the quality display is a number (1-100), not a durability bar. - SDG docs reference a "Barrel" attachment slot but list it as separate from "Muzzle." In the SDK, the barrel IS the muzzle attachment. There is no separate muzzle slot — barrel and muzzle are the same attachment point (
Hook_Barrel).
Performance Considerations
Barrel audio is standard Unity AudioSource playback. One AudioClip instance per barrel type, loaded into memory at asset load. Memory: ~200KB per clip for a 2-second WAV at 44.1kHz mono. With 100 barrel variants, ~20MB of audio memory. Gunshot rolloff calculation is one float multiplication per gunshot.
Deeper FAQ
Q: Can I change the barrel's audio clip per weapon skin?
Yes. The _shoot AudioClip is loaded from the asset bundle. A weapon skin could override the Shoot audio via the skin's bundle. Skin audio overrides use the same key ("Shoot") in the skin's bundle.
Q: Does the barrel affect bullet velocity or projectile type?
No. Barrel attachments modify audio (silencing) and ballistic stats (recoil, spread) but do not change bullet velocity, projectile type, or ammo type. Those are controlled by the magazine (ItemMagazineAsset) and caliber (ItemCaliberAsset) systems.
Cross-References
- ItemCaliberAsset — Weapon Mod Base Class — The parent class providing all stat modifier fields.
- ItemGripAsset — Grip Attachments — Grip prefab loading that follows the same attachment pattern.
- ItemGunAsset — Gun Weapon System — Gunshot rolloff and how barrels modify weapon audio.
