Clarence Hann

SendMessage() or GetComponent()?

In this article, you will learn:

  • Why there’s a chance we might want to use SendMessage() sometimes?
  • What are the pros and cons of using SendMessage() and GetComponents()?

You might be interested if you are:

An awesome artist

A cool technical artist

Or

A To-Be-Senior programmer.

TLDR:

SendMessage() is easy to use and shorter to type. But it introduces a “magic string” problem. Using GetComponent() we steer away from the difficulties in maintaining the code compared to the SendMessage().

You can skip this article if you get what it means above.

Why there’s a chance we might want to use SendMessage() sometimes?

An artist friend of mine has been working with Unity for years, and recently he started to learn to code. From the snippets he showed me, I noticed one thing: he used SendMessage() a lot. For example:

public class Game : MonoBehaviour
{
    private GameObject pawn;

    public void AdvancePawn()
    {
        pawn.SendMessage("Advance", 1);
    }
}
public class Pawn : MonoBehaviour
{
    public void Advance(int steps)
    {
        gameObject.transform.position += Vector3.up * steps;
    }
}

I asked him, why do you use SendMessage()? He said the Youtube video he followed uses it, and when he typed pawn.Advance() his IDE was persistent in telling him there’s an error.:

Then why pawn.Advance() here doesn’t work?

I guess most of you might have already known, but the answer is, the SendMessage() here is to call the Advance() method of the pawn inside of the Game class, because we cannot directly call pawn.Advance(). So if you write “pawn.”, the auto-completion won’t give you an Advance() tip. Why? Because pawn is a GameObject, and not an instance of the class Pawn. Since the GameObject class doesn’t have an “Advance” function, you don’t see the “Advance” method on the list.

If you wanna learn more about unity components, Unity has a more detailed explanation (It’s long and less relevant! You don’t have to click it!): https://docs.unity3d.com/Manual/Components.html

SendMessage() is a method of the GameObject class. It will go over each component on this GameObject, check its script, and find out the exact method with the exact number of parameters. Here its official documentation (Again, it’s less relevant): https://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html

Let’s get back to where we were. My friend learned why he couldn’t call Advance() directly, and he looked up the Internet, and discovered the existence of this function of the GameObject class: GetComponent(). But he continued to use SendMessage(). Guess why?

Because it’s longer and harder to type GetComponent with <> and ()!

True and you know what, it’s actually a (and perhaps only) drawback of “GetComponent()”. One score for “SendMessage()”.

What are the pros and cons of using SendMessage()?

My friend had been happy with SendMessage for a long long time, until one day he suddenly wanted to rename it to “Move”, and give it 2 parameters: one for the direction, and one for the number of steps.

This is partly because SendMessage() only takes 1 parameter. Another external reading here. But mainly, the problem roots down to “Magic Strings”. Basically, it can cause you the following troubles:

1. Hard to rename

If you need to rename “Advance()” to “Move()” when you are using SendMessage(), you will have to press Ctrl + H (Command + H for mac) to replace all the occurrence, because “Find All References” won’t work. (“Go To Definition” won’t work neither)

If you have methods than share the word “Advance”, manually replacing them can be a real headache:

But “Find All References” will do things smartly hence save you time:

2. Hard to read definition

You might want to read the definition of the function you wanna call, for example, to see the type of the parameter of the function. If you’re using SendMessage(), again you have to use Find & Replace, which is less convenient than letting the IDE do it for you – the “Go To Definition” feature.

3. No Auto-completion

If you use SendMessage(), you lose the perk of browsing through the available functions of the component you’re calling:

If you use GetComponent(), then you directly call the component’s function, so that you’ll be able to see the auto-completion and won’t have to go the old school Find & Replace way.

To end the long boring dullness, using SendMessage() can cost you more time during development than GetComponent() because you can harness the handiness of the IDE, to easily find all references, go to definition, etc. instead of using the error-prone and tedious Find & Replace method.

Leave a Reply

Your email address will not be published. Required fields are marked *