Event is always null, despite adding a function to it.

I’m working on a hostage negotiation game where the player has to try psychologically manipulate hostage takers to get their hostages out of the building, safe. The player can show empathy, pity or tough love to the hostage takers in order to influence them, but they all react differently to what you say to them. Essentially, I wanted to trigger an “OnEmpathy” event to notify each Hostage Taker that the player just showed Empathy.

So, now for some code examples so I can walk you through what’s happening, and what I expect to happen. First of all, here is the HostageTaker class, which I plan to instantiate in each level to handle each individual hostage taker. There can be four in total. I removed two methods at the end which are the same as “EmpathyControl”.

public class HostageTaker

{   //This is the hostage taker class instantiated in each level to add hostage takers to the level.
    public float fear;
    public float nervousness; //The basic stats between each hostage taker.
    public float anger;
    public string customName; //Name and age for extra info.
    public byte age;
    public string personality;

    void OnEnable()
    {
        ButtonHandler.OnEmpathy += this.EmpathyControl;
    }
    public void start()
    {

    }
    public void update()
    {

    }
    public void StatDegrade()
    {
        fear += Time.deltaTime * NegotiationControls.statDegradeFactor;
        nervousness += Time.deltaTime * NegotiationControls.statDegradeFactor;
        anger += Time.deltaTime * NegotiationControls.statDegradeFactor;
    }
    public void EmpathyControl()
    {
        if (personality == "Alpha")
        {
            nervousness -= 5 * NegotiationControls.difficultyMult;
            fear -= 5 * NegotiationControls.difficultyMult;
            anger += 5 * NegotiationControls.difficultyMult;
            MonoBehaviour.print("Debug");
        }
        else if (personality == "Beta")
        {
            nervousness += 5 * NegotiationControls.difficultyMult;
            fear -= 5 * NegotiationControls.difficultyMult;
            anger -= 5 * NegotiationControls.difficultyMult;
            MonoBehaviour.print("Debug");
        }
        else if (personality == "Gamma")
        {
            nervousness -= 5 * NegotiationControls.difficultyMult;
            fear += 5 * NegotiationControls.difficultyMult;
            anger -= 5 * NegotiationControls.difficultyMult;
            MonoBehaviour.print("Debug");
        }
    }

“EmpathyControl” is the method I plan to call with the OnEmpathy event that is triggered when you press the Empathy button. I have the button handling script here:

public delegate void EmpathyCall();
    public static event EmpathyCall OnEmpathy;

And the rest of the relevant code:

public void OnMouseDown() 
    {
        if (this.name == "Empathy" && OnEmpathy != null) //Button identification & null event check.
        {
            print("Empathy Called.");
            OnEmpathy();
        }
        else if(this.name == "Pity")
        {
            print("Pity Called.");
        }
        else if(this.name == "Tough Love")
        {
            print("Tough Love Called.");
        }
        else
        {
            print("Call error. Cannot identify button or OnEmpathy is Null.");
        }
    }

Basically, this script is running on each button, so when I press one, it’ll identify which button was pressed, then check to see if the event is null. Right now, Pity and Tough Love work just fine. Their debug texts appear, but when I try to use OnEmpathy != null, the condition is never true, essentially meaning, OnEmpathy has to be null. Regardless, I’ve subscribed EmpathyControl to OnEmpathy here: ButtonHandler.OnEmpathy += this.EmpathyControl;.

What I expect to happen is that I press one of the GUI buttons, for example, the Empathy button, then it sends out an OnEmpathy event. Each Hostage Taker then picks up this OnEmpathy event and reacts accordingly to it. The only problem is that OnEmpathy remains null, even when I subscribe a method to it, and I really don’t know why.

Thanks in advance.

I was just about to say add a Debug.Log() in OnEnable to see whether you get there or not.

While writing this and wondering why this wouldn’t work I noticed your HostageTaker class does not inherit from Monobehaviour. Therefore OnEnable wouldn’t be called automatically, as this is only called on classes that are either derived from MonoBehaviour and ScriptableObjects.

The engine won’t care about other classes having this method, so you need to call it somewhere explicitly or change this to be a Monobehaviour and attach it to your hostage takers.

Hopefully that solves the issue.