Skip to content

Getting Started Quick Start

github-actions[bot] edited this page May 3, 2026 · 4 revisions

Quick Start - Your First Message in 5 Minutes

Home | Getting-Started | Visual-Guide | Samples


Goal: Get a working message system in 5 minutes. Copy, paste, run.

Stuck? -> ..-Reference-Troubleshooting | ..-Reference-Faq


Step 0: Install (30 seconds)

Unity Package Manager -> Add package from git URL:

https://github.com/wallstop/DxMessaging.git

Requirements: Unity 2021.3+ | .NET Standard 2.1 | All render pipelines supported


Your First Message (3 Steps)

Step 1: Define messages

using DxMessaging.Core.Messages;
using DxMessaging.Core.Attributes;

// Recommended: attributes + auto constructor (beginner-friendly)
[DxUntargetedMessage]
[DxAutoConstructor]
public readonly partial struct WorldRegenerated
{
    public readonly int seed;
}

[DxUntargetedMessage]
[DxAutoConstructor]
public readonly partial struct VideoSettingsChanged
{
    public readonly int width;
    public readonly int height;
}

[DxTargetedMessage]
[DxAutoConstructor]
public readonly partial struct Heal
{
    public readonly int amount;
}

[DxBroadcastMessage]
[DxAutoConstructor]
public readonly partial struct TookDamage
{
    public readonly int amount;
}

// Performance option: keep [DxTargetedMessage] on a readonly struct to stay zero-boxing friendly, and drop [DxAutoConstructor] only if you need custom constructor logic.

// Optional parameters with custom defaults
[DxTargetedMessage]
[DxAutoConstructor]
public readonly partial struct HealAdvanced
{
    public readonly int amount;
    [DxOptionalParameter(true)]  // Custom default value
    public readonly bool showEffect;
    [DxOptionalParameter(Expression = "Color.green")]  // Expression for any type
    public readonly Color effectColor;
}

Step 2: Add a messaging component

using DxMessaging.Unity;
using DxMessaging.Core.Messages;
using UnityEngine;

public sealed class HealthUI : MessageAwareComponent
{
    protected override void RegisterMessageHandlers()
    {
        base.RegisterMessageHandlers();
        _ = Token.RegisterUntargeted<WorldRegenerated>(OnWorld);
        _ = Token.RegisterComponentBroadcast<TookDamage>(this, OnDamage);
    }

    private void OnWorld(ref WorldRegenerated m) { /* update UI */ }
    private void OnDamage(ref TookDamage m) { /* flash damage */ }
}

Important: Inheritance and base calls

Important

If you override any of the lifecycle methods that DxMessaging hooks, your override must call the matching base method first. Forgetting this is silent: no errors, no compile failure, just dead handlers. The Roslyn analyzer (DXMSG006) and the ..-Guides-Inspector-Overlay will flag the mistake, but they fire after the broken code is already written.

The five guarded methods, with what breaks if you forget the base call:

Method What breaks
base.Awake() The registration token is never created; no handler on this component runs.
base.OnEnable() When MessageRegistrationTiedToEnableStatus is true, your handlers never re-enable with the component.
base.OnDisable() Handlers stay live while the component is disabled, processing messages they should not see.
base.OnDestroy() Registrations leak past the component's lifetime; held references prevent GC.
base.RegisterMessageHandlers() The default StringMessage handlers never register. Override RegisterForStringMessages => false if you do not want them.

Start, Update, FixedUpdate, LateUpdate, and OnApplicationQuit are not hooked. You can override them without calling base.

See ..-Reference-Analyzers#dxmsg006-missing-base-call and the symptom-first ..-Reference-Troubleshooting.

Step 3: Send messages

using DxMessaging.Core.Extensions;   // Emit helpers
using UnityEngine;

// Untargeted (global)
var world = new WorldRegenerated(42);
world.Emit();

// Targeted (to a specific component or GameObject)
var heal = new Heal(10);
heal.EmitGameObjectTargeted(gameObject);     // no InstanceId cast needed

// Broadcast (from a specific source)
var hit = new TookDamage(5);
hit.EmitGameObjectBroadcast(gameObject);     // no InstanceId cast needed

// String convenience (global)
"Saved".Emit();

Summary

You have:

  1. Defined 4 message types
  2. Created a component that listens
  3. Sent messages from anywhere

Registration cleanup is automatic. Messages are type-safe.


What You Built

  • Untargeted messages (WorldRegenerated, VideoSettingsChanged) -> Global announcements anyone can hear
  • Targeted messages (Heal) -> Commands to a specific object
  • Broadcast messages (TookDamage) -> Events from a source that others observe

Next Steps


Quick Tips

Do's

  • Use MessageAwareComponent for Unity components (automatic lifecycle)
  • Store struct in variable before emitting: var msg = new Heal(10); msg.Emit();
  • Call base.RegisterMessageHandlers() when overriding

Don'ts

  • Don't emit from temporaries: new Heal(10).Emit() won't compile (struct emit methods require ref this)
  • Don't use Untargeted for commands to one object (use Targeted instead)
  • Don't forget using DxMessaging.Core.Extensions; for Emit* methods

Clone this wiki locally