Install
$ agentstack add skill-xeldaralz-everything-claude-unity-event-systems ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Event Systems
Events decouple systems. The publisher doesn't know who's listening. The subscriber doesn't know who's publishing.
When to Use Each Type
| Type | Coupling | Config | Allocation | Best For | |------|----------|--------|------------|----------| | C# events / Action | Code-only | None | Zero with struct | Internal class communication | | UnityEvent | Inspector-wired | Designer | Some | Button clicks, animation events, designer-configurable | | SO Event Channel | Asset-based | Designer | Minimal | Cross-system communication | | Static EventBus | Global | None | Depends | Truly global events (rare) |
C# Events (Preferred for Code)
public sealed class HealthSystem : MonoBehaviour
{
// Declare event
public event System.Action OnHealthChanged; // current, max
public event System.Action OnDied;
[SerializeField] private float _maxHealth = 100f;
private float _currentHealth;
public void TakeDamage(float amount)
{
_currentHealth = Mathf.Max(0f, _currentHealth - amount);
OnHealthChanged?.Invoke(_currentHealth, _maxHealth);
if (_currentHealth _source.OnEvent += HandleEvent;
private void OnDisable() => _source.OnEvent -= HandleEvent;
// BAD — memory leak if object is destroyed or deactivated
private void Start() => _source.OnEvent += HandleEvent;
// No unsubscribe → delegate holds reference → object can't be GC'd
SO Event Channels (Cross-System)
See the scriptable-objects skill for the full pattern. Quick reference:
// Create event asset: Assets/Events/OnPlayerDied.asset
// Wire same asset to publisher AND subscriber via [SerializeField]
// Publisher
[SerializeField] private VoidEventChannel _onPlayerDied;
_onPlayerDied.Raise();
// Subscriber (completely decoupled — doesn't know about publisher)
[SerializeField] private VoidEventChannel _onPlayerDied;
private void OnEnable() => _onPlayerDied.Subscribe(HandlePlayerDied);
private void OnDisable() => _onPlayerDied.Unsubscribe(HandlePlayerDied);
UnityEvent (Designer-Configurable)
public sealed class InteractableObject : MonoBehaviour
{
[SerializeField] private UnityEvent _onInteract;
public void Interact()
{
_onInteract?.Invoke(); // Designers wire responses in Inspector
}
}
Use when designers need to configure responses without code:
- Button clicks
- Animation events
- Trigger zones
- Cutscene triggers
Caution: UnityEvents are slower than C# events and harder to debug. Use C# events for code-to-code communication.
Static EventBus (Global, Use Sparingly)
public static class GameEvents
{
public static event System.Action OnGamePaused;
public static event System.Action OnGameResumed;
public static event System.Action OnScoreChanged;
public static void RaisePaused() => OnGamePaused?.Invoke();
public static void RaiseResumed() => OnGameResumed?.Invoke();
public static void RaiseScoreChanged(int score) => OnScoreChanged?.Invoke(score);
}
Warning: Static events are never garbage collected. Subscribers MUST unsubscribe. Use only for truly global events that every system needs.
Zero-Allocation Pattern (Hot Path)
For events fired every frame (rare but exists):
// Use ref struct to avoid heap allocation
public readonly ref struct DamageEvent
{
public readonly float Amount;
public readonly Vector3 Position;
public readonly GameObject Source;
public DamageEvent(float amount, Vector3 position, GameObject source)
{
Amount = amount;
Position = position;
Source = source;
}
}
// Note: ref structs can't be stored in Action delegates
// Use a custom delegate or direct method call for zero-alloc
Common Mistakes
- Subscribing without unsubscribing → memory leak, events fire on destroyed objects
- Subscribing in Awake, unsubscribing in OnDestroy → events fire when object is disabled
- Using events for synchronous, same-frame logic → direct method call is simpler
- Too many event channels → if publisher and subscriber always exist together, use direct reference
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: XeldarAlz
- Source: XeldarAlz/everything-claude-unity
- License: MIT
- Homepage: https://github.com/XeldarAlz/everything-claude-unity#readme
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.