| name | component-attributes |
| description | Modify S&box Component properties using Property Attributes to customize inspector display. Use when creating components, enhancing inspector UX, organizing properties with headers/groups, adding constraints with Range, or conditionally showing fields. Use when this capability is needed. |
| metadata | {"author":"echohello-dev"} |
S&box Component Attributes
Enhance S&box Component properties with attributes to control inspector appearance and behavior.
When to Use
- Creating new components with configurable properties
- Improving existing component inspector UX
- Organizing related properties into groups
- Adding value constraints (ranges, conditional display)
- Marking runtime state as read-only
- Creating debug/advanced feature tabs
Core Concept
Properties with [Property] appear in the inspector. Additional attributes modify display:
public sealed class MyComponent : Component
{
[Property]
public string Basic { get; set; }
[Property, Title("HP"), Range(0, 100), Icon("favorite")]
public int Health { get; set; }
}
Essential Attributes Quick Reference
| Attribute | Purpose | Example |
|---|
[Header("Text")] | Section label | [Property, Header("Stats")] |
[Group("Name")] | Collapsible group | [Property, Group("Rendering")] |
[Range(min, max)] | Slider control | [Property, Range(0, 100)] |
[Title("Text")] | Custom label | [Property, Title("HP")] |
[Description("Text")] | Help text | [Property, Description("Max health")] |
[Icon("name")] | Visual marker | [Property, Icon("favorite")] |
[ReadOnly] | Non-editable | [Property, ReadOnly] |
[ShowIf("prop", val)] | Conditional show | [Property, ShowIf("UseCustom", true)] |
[HideIf("prop", val)] | Conditional hide | [Property, HideIf("AutoMode", true)] |
Organization Patterns
Header Sections
Group related properties under labels:
[Property, Header("Player Stats")]
public int MaxHealth { get; set; } = 100;
[Property]
public int CurrentHealth { get; set; } = 100;
[Property, Header("Economy")]
public long Currency { get; set; } = 1000;
Collapsible Groups
Create foldable sections:
[Property, Group("Rendering")]
public Color Color { get; set; }
[Property, Group("Rendering")]
public bool CastShadows { get; set; }
Toggle Groups
Enable/disable groups with a checkbox:
[Property]
public bool UseAdvancedSettings { get; set; } = false;
[Property, ToggleGroup("UseAdvancedSettings")]
public float AdvancedValue { get; set; }
Feature Tabs
Separate advanced/debug features:
[Property, Feature("Debug")]
public bool ShowDebugInfo { get; set; }
[Property]
public string Name { get; set; }
Value Constraints
Range Sliders
Constrain numeric values:
[Property, Range(0, 100)]
public float Health { get; set; } = 100f;
[Property, Range(0, 100, clamped: false)]
public int Value { get; set; }
[Property, Range(0, 100, slider: false)]
public int Precise { get; set; }
Step Increment
Snap to specific increments:
[Property, Step(10)]
public int RoundedValue { get; set; } = 50;
Conditional Display
Show/Hide Based on Other Properties
[Property]
public bool UseCustomSpeed { get; set; } = false;
[Property, ShowIf("UseCustomSpeed", true)]
public float CustomSpeed { get; set; } = 5f;
[Property, HideIf("AutoCalculate", true)]
public float ManualValue { get; set; }
Display Enhancement
Custom Labels and Icons
[Property, Title("HP")]
public int Health { get; set; }
[Property, Icon("favorite"), Title("Health Points")]
public int MaxHealth { get; set; }
Descriptions and Help Text
[Property, Description("The maximum health this player can have")]
public int MaxHealth { get; set; } = 100;
Read-Only Runtime State
[Property, ReadOnly]
public int ContractsCompleted { get; set; } = 0;
[Property, ReadOnly, Icon("trending_up")]
public long TotalEarnings { get; set; } = 0;
Practical Example: Health Component
public sealed class HealthComponent : Component
{
[Property, Header("Health Settings"), Range(1, 1000), Icon("favorite")]
public int MaxHealth { get; set; } = 100;
[Property, ReadOnly, Icon("favorite_border")]
public int CurrentHealth { get; set; } = 100;
[Property, Space, Header("Regeneration")]
public bool EnableRegeneration { get; set; } = true;
[Property, ShowIf("EnableRegeneration", true), Range(0, 100)]
public float RegenPerSecond { get; set; } = 5f;
protected override void OnStart()
{
CurrentHealth = MaxHealth;
}
protected override void OnFixedUpdate()
{
if (EnableRegeneration && CurrentHealth < MaxHealth)
{
CurrentHealth = Math.Min(
CurrentHealth + (int)(RegenPerSecond / 50f),
MaxHealth
);
}
}
public ()
{
CurrentHealth = Math.Max(CurrentHealth - damage, );
}
}
Benefits:
- Range constrains health values
- ReadOnly shows runtime state without allowing edits
- ShowIf conditionally displays regen rate
- Icons add visual categorization
- Headers organize logically
Common Pitfalls
Forgetting [Property]
[Range(0, 100)]
public int Value { get; set; }
[Property, Range(0, 100)]
public int Value { get; set; }
Using [Property] with [RequireComponent]
[Property, RequireComponent]
private ModelRenderer Body { get; set; }
[RequireComponent]
private ModelRenderer Body { get; set; }
Invalid ShowIf/HideIf References
[Property, ShowIf("NonExistentProp", true)]
public int Value { get; set; }
[Property]
public bool Enable { get; set; }
[Property, ShowIf("Enable", true)]
public int Value { get; set; }
Overusing Groups
[Property, Group("A"), ToggleGroup("B"), Feature("C")]
public int Value { get; set; }
[Property, Group("Settings")]
public int Value { get; set; }
All Available Attributes
Organization
[Header("Text")] - Section label
[Space] - Vertical spacing
[Group("Name")] - Collapsible group box
[ToggleGroup("BoolProperty")] - Checkbox-enabled group
[Feature("TabName")] - Separate tab
[FeatureEnabled("TabName")] - Toggle tab on/off (bool property)
[Order(priority)] - Custom display order
Display
[Title("Text")] - Custom label
[Description("Text")] - Help text below property
[Icon("name")] - Icon next to label
[ReadOnly] - Visible but not editable
[KeyProperty] - Primary identifier in lists
[InlineEditor] - Edit nested objects inline
[Hide] - Completely hidden (still serialized)
Constraints
[Range(min, max)] - Slider control with optional clamping
[Step(increment)] - Drag increment value
[ShowIf("property", value)] - Show if condition met
[HideIf("property", value)] - Hide if condition met
Input Controls
[TextArea] - Multi-line text input
[ImageAssetPath] - Image file picker
[FontName] - Font dropdown
[InputAction] - Input action dropdown (from Input.config)
[Flags] - Multi-select enum (requires [Flags] on enum)
Component
[RequireComponent] - Auto-link/create component on same GameObject
Workflow for Enhancing Components
- Identify categories - Group related properties
- Add headers/groups - Use
[Header] or [Group]
- Constrain values - Add
[Range] where applicable
- Mark runtime state - Use
[ReadOnly] for calculated values
- Add context - Use
[Title], [Description], [Icon]
- Implement conditionals - Use
[ShowIf]/[HideIf] for contextual properties
- Test in inspector - Verify layout and behavior
Resources
Converted and distributed by TomeVault — claim your Tome and manage your conversions.