Attributes
Markers you put on fields, methods and classes to change how the editor and engine treat them.
Inspector attributes
These control what shows up in the Properties panel when your script is on an entity.
The rule, stated once:
- Public fields are shown by default.
[SerializeField]opts a private field in.[HideInInspector]opts a public field out.
A shown field's value is authored in the Properties panel, saved into the scene, and applied before OnCreate every time the entity plays.
[SerializeField]
Shows a private field in the inspector and persists its value with the scene.
public class Enemy : GameEntity
{
[SerializeField] private float m_Speed = 3.0f;
[SerializeField] private int m_MaxHealth = 100;
}This is usually what you want over a public field — the designer can tune it, and the rest of your code still can't reach in and change it.
[HideInInspector]
Hides a public field. It's still an ordinary public field to game code; it just stops being authorable content.
[HideInInspector] public int RuntimeScore;[Header(string text)]
Draws a separator and a bold label above the field, for breaking a long inspector into readable sections.
[Header("Movement")]
[SerializeField] private float m_Speed = 3.0f;
[SerializeField] private float m_JumpForce = 8.0f;
[Header("Combat")]
[SerializeField] private int m_Damage = 10;[Tooltip(string text)]
Shown when the cursor rests on the field's row.
[Tooltip("Seconds of invulnerability after taking a hit.")]
[SerializeField] private float m_InvulnTime = 1.0f;[Range(float min, float max)]
Clamps a numeric field and draws it as a slider instead of a drag field. Ignored on non-numeric types.
[Range(0f, 1f)]
[SerializeField] private float m_Friction = 0.4f;All together
using JoystickEngine;
public class Enemy : GameEntity
{
[Header("Movement")]
[Tooltip("Units per second at full speed.")]
[SerializeField] private float m_Speed = 3.0f;
[Range(0f, 1f)]
[SerializeField] private float m_Acceleration = 0.3f;
[Header("Combat")]
[SerializeField] private int m_MaxHealth = 100;
[HideInInspector] public int CurrentHealth;
protected override void OnCreate()
{
// Authored values are already applied by the time this runs.
CurrentHealth = m_MaxHealth;
}
}Fields, not properties
These attributes only work on real fields. An auto-property's backing field is name-mangled by the compiler, so the engine's reflection can't find it — the attribute silently reads back empty and looks like it never arrived. Use fields.
[AnimationEvent]
Marks a method as callable by name from an animation clip's event track.
[AnimationEvent]
private void Footstep() => m_StepSound?.Play();
[AnimationEvent]
private void SpawnEffect(string effectName)
=> Particles.Spawn($"Effects/{effectName}.jparticle", Translation);Supported signatures: void F(), void F(string), void F(float), void F(int). An unsupported signature is reported once in the log and the event is skipped — playback never crashes over it.
The attribute is required rather than "any public method by name", for two reasons: an event-track dropdown can list exactly the marked methods, so an author picks from a list instead of typing a name that silently does nothing when misspelled; and an animation can't reach arbitrary methods on a script that never opted in.
See Animator.
[VisualNode]
Marks a method as a node in visual scripts. The node's pins are derived from the method's own signature, so the API is the node library — there is nothing to keep in sync.
| Property | What it does |
|---|---|
Category | Menu path in the node palette, e.g. "Math/Float" |
DisplayName | Node label. Defaults to a prettified method name |
Tooltip | Tooltip text |
Pure | true means no exec pins — the node is an expression usable inline. false (the default) means exec in and out, a statement |
[VisualNode(Category = "Gameplay", Tooltip = "Deal damage to this entity.")]
public void TakeDamage(int amount) { /* ... */ }
[VisualNode(Category = "Gameplay", Pure = true)]
public int GetHealth() => m_Health;Pin derivation is mechanical: parameters become input pins, the return value becomes an output pin (void means none), and out parameters become extra outputs.
Methods only
[VisualNode] targets methods. It does not compile on a property — which is why several engine properties that look like obvious node candidates aren't tagged.
The graph editor isn't usable in 0.1.0
Tagging a method registers it, but the visual script canvas renders a node and link count rather than a graph, and the "Compile & Generate C#" button discards its result without writing a file. See Node graphs for exactly what works today. Tag your methods if you like — they'll be there when the editor is — but don't plan a feature around visual scripting yet.
VisualDebug (Node, PinValue, Breakpoint) exists alongside this and is entirely unimplemented stubs.
[CreateResourceMenu]
Marks a GameResource subclass as creatable from Assets → Create and the Content Browser's Create submenu.
| Property | What it does |
|---|---|
MenuName | Path under "Assets/Create/", e.g. "Gameplay/Enemy Stats". Empty means the class's short name |
FileName | Default file stem for a new asset. Empty means the class's short name |
Priority | Menu ordering |
[CreateResourceMenu(MenuName = "Gameplay/Enemy Stats", FileName = "EnemyStats")]
public class EnemyStats : GameResource
{
public float Speed = 3.0f;
public int Health = 100;
}A class without the attribute is still a fully usable resource type — referenced from a field, loaded by name. The attribute only decides whether a menu item exists to create one from the UI, which also keeps abstract base classes out of the menu without a second opt-out attribute.
Networking attributes
[Rpc], [Replicated], [Predicted], [ServerOnly], [ClientOnly], [ServerOnlyTick] and [ClientOnlyTick] are documented on the Networking page.
See also
- Components — the built-in components your fields sit alongside
- Game resources —
[CreateResourceMenu]in context - Animator —
[AnimationEvent]in context - Node graphs — the state of visual scripting