Method 1 - Unity UI Event System
Thanks to Byte56 for pointing out that there's a new approach to messaging in Unity, which is much more similar to what the asker describes in Unreal.
One quick heads-up: This approach is quite verbose compared to what I'm used
to. If you just need a quick way to call a method on another object,
without all the loosely-coupled robustness of the Event System, scroll
down and I'll include some other options.
You'd start by creating a new C# script that defines an interface inheriting from
public interface IDamagable : IEventSystemHandler
void TakeDamage(DamageEventData damageData);
Each method you define in this interface becomes a message that you can send. If the message needs data, then we'll also need to define our data object by extending
public class DamageEventData : BaseEventData
// This doesn't have to be in this scope, but I didn't want to create
// yet another script file for it, so this seemed the most logical place
public static readonly ExecuteEvents.EventFunction<IDamagable> takeDamageDelegate
= delegate (IDamagable handler, BaseEventData data)
var casted = ExecuteEvents.ValidateEventData<DamageEventData>(data);
public float damageAmount;
public DamageEventData(EventSystem eventSystem,
) : base(eventSystem)
this.damageAmount = damageAmount;
What's up with that delegate? Since our interfaces can contain multiple methods, Unity's Event System uses a delegate to link up the right handler method and provide it the correct data type. You can do this inline, but having it defined statically somewhere is a bit friendlier to the garbage collector. (Example borrowed from this Event System walkthrough)
Next, ensure any script component you want to receive these messages implements your interface:
public Explodable : MonoBehaviour, IDamagable
public Transform explosionPrefab;
public float damageThreshold = 0.5f;
public void TakeDamage(DamageEventData damageData)
if(damageData.damageAmount > damageThreshold)
Instantiate(explositionPrefab, transform.position, transform.rotation);
public void ToggleInvulnerability()
// No-Op: I declare by fiat that explodable objects are never invulnerable.
Finally you can send this message to all scripts on a given GameObject that implement your interface:
if(Physics.Raycast(ray, out hit))
DamageEventData data = new DamageEventData(
// If your message has no data - eg. the ToggleInvulnerability() method,
// you can replace that delegate in the last argument with:
// (handler, data) => handler.ToggleInvulnerability
Whew, that was a bit of a marathon. You can use other methods of the ExecuteEvents class to search the hierarchy for a recipient of the message, or broadcast a message up the hierarchy. The docs say you can also recursively send a message down the hierarchy, but I haven't found the method for that yet.
Method 2 - Just grab the component you need
If your message/interface describes a type of behaviour that maps well to a single component, then you might as well make it a component and address it directly:
var damagable = targetObject.GetComponent<Damagable>();
if(damagable != null)
Strictly speaking this is more tightly coupled - but for a lot of gameplay we don't need the industrial grade decoupling the Event System was introduced to handle (primarily for UI widgets). The separation of a Damagable component MonoBehaviour from the rest of an object/character's behaviour logic scripts already decouples it enough for our purposes, I would claim.
You can also do this with interfaces, if you have multiple components that care about the same kinds of messages:
var damagables = targetObject.GetComponents<IDamagable>();
foreach(var damagable in damagables)
GetComponent has some performance cost, so try to cache these component references if you're using them frequently. For things that happen only a handful of times per frame though, it's still quite reasonable to use.
Method 3 - Old SendMessage approach
This is how it worked in Unity 4 & earlier. Because the Event System in Method 1 is described as a replacement for this, don't expect this to stick around in future versions.
But if you just need something quick & dirty, it's hard to get moreso than this:
Then in your recipient scripts, you'd include a method with the name TakeDamage:
public void TakeDamage(float damageAmount)
hp -= damageAmount;
if(hp <= 0)
Note that this method doesn't need to be
public - Unity calls it using reflection with the name you pass, no interfaces or anything - but I like marking it that way to remind myself that it's called externally.
Note that this reflection and string manipulation isn't all that cheap in terms of performance, so definitely don't use this for something that's running many times every frame. This approach also tends to obfuscate the call stack when debugging, and needs to be manually refactored if you ever change the names of your methods. For these reasons it's commonly considered an anti-pattern, so use it very cautiously if you use it at all.