Skip to content

ItemGearAsset — Head-Worn Clothing Base Class

Overview

ItemGearAsset is an abstract intermediate class in the clothing asset hierarchy. It inherits from ItemClothingAsset and serves as the base for head-worn clothing items: hats (ItemHatAsset), masks (ItemMaskAsset), and glasses (ItemGlassesAsset). It adds one primary feature: the hair and beard override system that dynamically replaces child mesh materials with the character's hair and beard materials.

The gear branch of the clothing hierarchy (gear → hats/masks/glasses) is distinguished from the bag branch (bag → shirts/pants/vests/backpacks) by this hair/beard override capability. Gear items are worn on the head and interact with the character's hair and facial hair systems. Bag items are worn on the body and provide storage.

Source code location: Unturned/Bundles/ItemGearAsset.cs (88 lines), inheriting from ItemClothingAsset.cs (304 lines), and ItemAsset.cs (base).

Inheritance Chain

ItemAsset
  └─ ItemClothingAsset (abstract) — armor, proof, movement speed, visuals
       └─ ItemGearAsset (abstract) — hair/beard override, legacy Hair/Beard flags
            ├─ ItemHatAsset
            ├─ ItemMaskAsset
            └─ ItemGlassesAsset

Position in the Clothing Tree

ItemClothingAsset
  ├─ ItemGearAsset (abstract)          ← THIS CLASS
  │    ├─ ItemHatAsset                 — hat prefab
  │    ├─ ItemMaskAsset                — mask prefab, earpiece, filter rate
  │    └─ ItemGlassesAsset             — vision system, blindfold
  └─ ItemBagAsset (abstract)
       ├─ ItemShirtAsset               — textures, mesh override
       ├─ ItemPantsAsset               — textures
       ├─ ItemVestAsset                — vest prefab, fallback shirt
       └─ ItemBackpackAsset            — backpack prefab, metal audio

Class Definition

csharp
public class ItemGearAsset : ItemClothingAsset
{
    public string hairOverride { get; protected set; }
    public Color32? hairOverrideNonGoldColor { get; set; }

    public string BeardOverride { get; set; }
    public Color32? beardOverrideNonGoldColor { get; set; }

    public override void PopulateAsset(in PopulateAssetParameters p) { ... }
    internal override void BuildCargoData(CargoBuilder builder) { ... }
}

Hair Override System

Purpose

The hair override system allows head-worn items to include hair geometry that dynamically matches the player's chosen hair color. Instead of every hat, mask, or glasses item requiring its own hair-colored texture (which would need a separate version for every hair color), ItemGearAsset enables a single model with a placeholder mesh whose material is replaced at runtime.

hairOverride

csharp
public string hairOverride { get; protected set; }
.dat KeyTypePurpose
Hair_OverridestringName of child MeshRenderer to replace with hair material

When hairOverride is set to a child transform name, the clothing system:

  1. Finds the MeshRenderer on the gear prefab with the matching name
  2. Replaces its material with the character's hair material
  3. The hair material uses the character's chosen hair color

This allows a single hat item to work with any hair color — the hair geometry on the hat is dynamically colored to match the player.

hairOverrideNonGoldColor

csharp
public Color32? hairOverrideNonGoldColor { get; set; }
.dat KeyTypePurpose
Hair_Override_NonGoldColorColor32 (RGB)Fallback color for players without Gold Upgrade

The Gold Upgrade unlocks full RGB hair color control. Players without Gold are limited to preset hair colors. The NonGoldColor provides a fallback color for these players, ensuring the hair override still looks intentional even without custom color support.

This color is also used in the cosmetic preview UI (item selection screen, loadout menu) since the preview may not have a player character with a specific hair color.

Parsing Logic

csharp
hairOverride = p.data.GetString("Hair_Override");
if (!string.IsNullOrEmpty(hairOverride)
    && p.data.TryParseColor32RGB("Hair_Override_NonGoldColor", out Color32 hairColor))
{
    hairOverrideNonGoldColor = hairColor;
}

The non-gold color is only parsed if hairOverride is set (non-empty). The parsing is conditional: if the color key is present and parseable, it's stored; otherwise hairOverrideNonGoldColor remains null (no fallback color).


Beard Override System

BeardOverride

csharp
public string BeardOverride { get; set; }
.dat KeyTypePurpose
Beard_OverridestringName of child MeshRenderer to replace with beard material

Identical in concept to hair override but for beard/facial hair. When BeardOverride is set, the named child mesh on the gear prefab has its material replaced with the character's beard material.

beardOverrideNonGoldColor

csharp
public Color32? beardOverrideNonGoldColor { get; set; }
.dat KeyTypePurpose
Beard_Override_NonGoldColorColor32 (RGB)Fallback color for non-Gold players

Same pattern as hair — provides a fallback beard color for players without the Gold Upgrade and for cosmetic preview rendering.

Parsing Logic

csharp
BeardOverride = p.data.GetString("Beard_Override");
if (!string.IsNullOrEmpty(BeardOverride)
    && p.data.TryParseColor32RGB("Beard_Override_NonGoldColor", out Color32 beardColor))
{
    beardOverrideNonGoldColor = beardColor;
}

Legacy Hair/Beard Visibility Keys

ItemGearAsset overrides the hairVisible and beardVisible properties set by ItemClothingAsset using legacy keys:

csharp
hairVisible = p.data.ContainsKey("Hair");
beardVisible = p.data.ContainsKey("Beard");

Key Conflict Resolution

There are two sets of hair/beard visibility keys in the inheritance chain:

LevelKeysDefaultLogic
ItemClothingAssetHair_Visible, Beard_VisibletrueParseBool with default
ItemGearAsset (override)Hair, Beardoverrides baseContainsKey

The ItemGearAsset.PopulateAsset runs after ItemClothingAsset.PopulateAsset and replaces the values set by the base class. This creates a priority system:

  1. If Hair_Visible is set in the .dat, ItemClothingAsset reads it
  2. If Hair is set in the .dat, ItemGearAsset overrides with ContainsKey result
  3. If neither is set, hairVisible defaults to true (from ItemClothingAsset)

Backward Compatibility

The code comment explains:

These values were originally only in gear assets, but mesh override shirts
need to be able to hide the hair and beard as well.

The Hair and Beard keys (without _Visible suffix) are the original keys from when only gear items (hats, masks, glasses) could hide hair. When ItemShirtAsset later needed the same functionality, Hair_Visible/Beard_Visible were added to ItemClothingAsset so all clothing could use them. The legacy Hair/Beard keys remain in ItemGearAsset for backward compatibility with older gear mods.

Practical Effect

For gear items (hats, masks, glasses), both naming conventions work:

.dat EntryEffect
Hair (present)hairVisible = true (show hair)
Hair (absent)hairVisible = false (hide hair — overrides base default of true)
Beard (present)beardVisible = true (show beard)
Beard (absent)beardVisible = false (hide beard — overrides base default of true)
Hair_Visible truehairVisible = true (from ItemClothingAsset, may be overridden by legacy Hair)
Hair_Visible falsehairVisible = false (from ItemClothingAsset, may be overridden by legacy Hair)

Recommendation: Use the modern Hair_Visible/Beard_Visible keys for new mods. The legacy Hair/Beard keys exist for backward compatibility and have inverted semantics (presence = visible) that differ from the base class defaults.


Relationship with ItemClothingAsset

ItemGearAsset extends ItemClothingAsset but does not modify most of its behavior:

FeatureBehavior
Armor systemInherited unchanged
Proof systemInherited unchanged
Movement speedInherited unchanged
Wear audioInherited unchanged (sleeve sound default for gear types)
Cosmetic priorityInherited unchanged (GetDefaultTakesPriorityOverCosmetic returns false)
Skin overrideInherited unchanged
Collider managementInherited unchanged
PRO behaviorInherited unchanged
Hair/beard visibilityOverridden — uses legacy Hair/Beard keys

The only behavioral difference between ItemGearAsset and ItemClothingAsset is the hair/beard visibility override and the addition of hair/beard material override fields.


PopulateAsset Call Chain

ItemAsset.PopulateAsset
  └─ ItemClothingAsset.PopulateAsset
       ├─ armor, proof, movement, visuals
       ├─ hairVisible = ParseBool("Hair_Visible", defaultValue: true)
       └─ beardVisible = ParseBool("Beard_Visible", defaultValue: true)

       └─ ItemGearAsset.PopulateAsset
            ├─ hairVisible = ContainsKey("Hair")          ← OVERRIDES base
            ├─ beardVisible = ContainsKey("Beard")         ← OVERRIDES base
            ├─ hairOverride = GetString("Hair_Override")
            ├─ TryParseColor32RGB("Hair_Override_NonGoldColor")
            ├─ BeardOverride = GetString("Beard_Override")
            └─ TryParseColor32RGB("Beard_Override_NonGoldColor")

BuildCargoData — Wiki Export

csharp
internal override void BuildCargoData(CargoBuilder builder)
{
    base.BuildCargoData(builder);

    CargoDeclaration data = builder.GetOrAddDeclaration("Gear");
    data.Append("GUID", GUID);
    data.Append("Hair", hairVisible);
    data.Append("Beard", beardVisible);
}
ColumnSource
GUIDPK, FK to Clothing table
HairhairVisible
BeardbeardVisible

The Gear Cargo table records the resolved hair/beard visibility after the legacy key override. If a subclass (like ItemMaskAsset) adds more columns to the Gear table, those are appended in the subclass's BuildCargoData override.


Abstract Nature

ItemGearAsset is abstract — it cannot be instantiated directly. It exists solely as a shared base for concrete subclasses. In the asset type system, items are registered with concrete types like EItemType.HAT, EItemType.MASK, or EItemType.GLASSES, not a generic "gear" type.

The class provides common infrastructure but no prefab loading — each subclass loads its own prefab ("Hat", "Mask", "Glasses"). The ClothingPrefab virtual property is not overridden in ItemGearAsset — it remains returning null from the ItemClothingAsset base.


.dat File Reference — Gear-Specific Keys

These keys are added by ItemGearAsset on top of all ItemClothingAsset and ItemAsset keys:

.dat KeyTypeDefaultCategory
Hairflagoverrides base Hair_VisibleLegacy hair visibility (presence = show)
Beardflagoverrides base Beard_VisibleLegacy beard visibility (presence = show)
Hair_OverridestringnullChild mesh name for hair material replacement
Hair_Override_NonGoldColorColor32 (RGB)nullFallback hair color for non-Gold players
Beard_OverridestringnullChild mesh name for beard material replacement
Beard_Override_NonGoldColorColor32 (RGB)nullFallback beard color for non-Gold players

Subclass Implementation Patterns

ItemHatAsset

csharp
public class ItemHatAsset : ItemGearAsset
{
    // Inherits hair/beard override system
    // Loads "Hat" prefab
    // Adds layer/cloth validation
}

Hats commonly use hair override to include hair geometry that dynamically matches the player's hair color. A baseball cap with a Hair_Override "Cap_Hair" child mesh shows the wearer's hair color peeking through.

ItemMaskAsset

csharp
public class ItemMaskAsset : ItemGearAsset
{
    // Inherits hair/beard override system
    // Adds earpiece functionality
    // Adds filter degradation rate
}

Masks typically hide hair and beard (the mask covers the face) and rarely use hair/beard override since the face is covered.

ItemGlassesAsset

csharp
public class ItemGlassesAsset : ItemGearAsset
{
    // Inherits hair/beard override system
    // Adds vision system (Headlamp, NVG, Blindfold)
    // Overrides cosmetic priority
}

Glasses rarely use hair/beard override — they sit on the face and don't interact with hair/beard meshes.


Gold Upgrade and Color Fallback

The Gold Upgrade system interacts with hair/beard overrides:

Player statusHair colorNonGoldColor effect
Gold UpgradeFull RGB controlNot used — player's chosen color is used
No Gold UpgradePreset colors onlyNonGoldColor is used if set
Cosmetic previewNo player contextNonGoldColor is used if set

The NonGoldColor fallback prevents hair/beard override meshes from rendering with a default or blank color when the player's chosen color isn't available. For items that include hair geometry as part of their design (hats with hair, masks with beard elements), setting a NonGoldColor ensures the item looks intentional even for free players.


Common Issues

  1. Hair_Visible/Hair confusion: The Hair key (without _Visible) has inverted semantics compared to Hair_Visible. Hair (present) = show; Hair_Visible true = show. But Hair (absent) = hide (overrides base default of true). This is the most common source of hair visibility bugs in gear items.

  2. Hair override mesh not found: The hairOverride string must match a child MeshRenderer name exactly (case-sensitive). If the named mesh doesn't exist on the prefab, the override is silently skipped — no error is reported.

  3. NonGoldColor parsing failure: If Hair_Override_NonGoldColor is present in the .dat but fails to parse (wrong format, wrong field count), hairOverrideNonGoldColor remains null. The color must be in RGB format (three values).

  4. BeardOverride vs Beard_Override: The C# property is BeardOverride (PascalCase, no underscore), but the .dat key uses Beard_Override with underscore. This inconsistency is a known naming artifact — follow the .dat key naming exactly.

  5. Override on non-gear items: Hair/beard override fields only exist in ItemGearAsset. Shirts, pants, vests, and backpacks (which inherit from ItemBagAsset) do not have hair/beard override capability. Mesh override shirts can hide hair/beard via Hair_Visible/Beard_Visible but cannot replace hair/beard materials.

Document history

VersionDateAuthorNotes
1.02026-07-2857 StudiosInitial publication. Full ItemGearAsset documentation including hair/beard override system, legacy key compatibility, Gold Upgrade color fallback, and subclass integration.