Trying to overcome mental block on Messages

Please, help me to understand. How is that possible: I declare

void ShowMainMenu (string greetings)

Then I declare

void OnUserInput(string input)

So, why does ShowMainMenu doesn’t work right there, where I’ve declared it (and I need to call it in Start), but OnUserInput works well in same conditions? (I don’t need to call it from Start or Update).

Really, I’m stuck here.

The Terminal.cs file you imported to your project is making the call to OnUserInput() but it doesn’t know to make the call to methods with other names; it is just not designed to do so.

It’s using a non-Unity feature in C# called Reflection which lets it hunt down classes - amongst other things - containing methods of a specific name and then calls them.

If you deliberately put an error into your OnUserInput method somewhere so that it logs out to the Unity console, you should probably see as part of the ‘stack trace’ of calls that it originates from Terminal and passes through C#'s reflection for invoking methods by name.

1 Like

So, at this point, if I get it right ALL methods NORMALLY works like that:

  • Declare Method anywhere in the script
  • Call this Method in the script

As you see it in code, target method appears twice (declare+call), but actually works only ones. That’s what stuck in my head. So, the problem here is exactly in OnUserInput() method, as it was provided to me (not written by me), and it works somehow I cannot understand right now.

Am I figure out it right?

Hi,

You declare your methods, then later you call them, declaring them does not call them, for example;

public class Example : MonoBehaviour
{
    private void HelloWorld()
    {
        Debug.Log("Hello World!");
    }

    private void Start()
    {
        // HelloWorld();
    }
}

With the above example, nothing happens. But if you were to uncomment the method call within the Start method, the HelloWorld method is then called, as such you would see “Hello World!” displayed in the console.

With the scenario you are discussing, what you haven’t seen is the code within the WM2000 package that you imported, hence you are seeing a method being declared but you haven’t see what is calling it. This is deliberate. The team has provided you with a skeleton solution which enables you to then add some functionality/details but all the while it is predominantly using their code in the background. Some of the architecture used in this provided solution would be beyond most new students initially, although you do cover these topics later in the course.

If you expand the project view and have a look inside the WM2000 folder you will see a file named InputBuffer.cs, this class defines a delegate which is subsequently used within the Terminal.cs class.

This line from the Awake method;

inputBuffer.onCommandSent += NotifyCommandHandlers;

If you then take a look at the NotifyCommandHandlers method;

    public void NotifyCommandHandlers(string input)
    {
        var allGameObjects = FindObjectsOfType<MonoBehaviour>();
        foreach (MonoBehaviour mb in allGameObjects)
        {
            var flags = BindingFlags.NonPublic | BindingFlags.Instance;
            var targetMethod = mb.GetType().GetMethod("OnUserInput", flags);
            if (targetMethod != null)
            {
                object[] parameters = new object[1];
                parameters[0] = input;
                targetMethod.Invoke(mb, parameters);
            }
        }
    }

This code first finds all of the MonoBehaviours, e.g. GameObjects with a class attached which inherits from MonoBehaviour. Then, it cycles through each of those classes and seeks a method named “OnUserInput”, using this line;

var targetMethod = mb.GetType().GetMethod("OnUserInput", flags);

Then, assuming it finds one, it calls it using Invoke;

targetMethod.Invoke(mb, parameters);

You are not expected to understand any of the above yet, which is why you are given a package to import which provides the backbones of the solution, on which you build, but for the sake of answering your question, this is where your method OnUserInput is being called from.

Hope this helps. :slight_smile:

3 Likes

This is awesome! Thank you!

1 Like

Youre welcome :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms