Search code examples
c#unity-game-enginedelegates

UnityAction loses subscribed event


I'm writing a keyboard manager for a virtual keyboard I created. I'm using a UnityAction to return to the calling object and process the keyboard input. However, somehow, my UnityAction loses its subscribed event, I get a "Object reference not set to an instance of an object.

I checked the calling function to see if upon arrival in the script the UnityAction was not null, and it is not. However checking everywhere else in the close returns null. You will find below all my debug code the places where I check that the UnityAction is not null. The only place in the code where it is not null is in the ReadUserInput function. All others are null.

I've used this coding approach in many places without a problem. Can't find why this one is sticky!

Calling Code:

    VRKeyboard.ProcessInput += AddKbdInputToInputline;
    VRKeyboard.ReadUserInput();

VRKeyboard Code:

public TMPro.TMP_Text InputLine;
public GameObject VRKeyboard;
public UnityAction ProcessInput;
private bool isdone = false;


// Update is called once per frame
void Update()
{
    if (ProcessInput == null) Debug.Log("ProcessInput is null at update"); else Debug.Log("ProcessInput is NOT null at update");
    if (isdone) CloseKeyboard();
}

public void ReadUserInput()
{
    InputLine.text = "";
    VRKeyboard.SetActive(true);
    if (ProcessInput == null) Debug.Log("ProcessInput is null at open"); else Debug.Log("ProcessInput is NOT null at open");
}



public void OnPointerDown(PointerEventData p)
{
    Text ButtonPressed;

    ButtonPressed = GetComponentInChildren<Text>(this);

    switch (ButtonPressed.text)
    {
        case "Clear All":
            InputLine.text = "";
            break;

        case "Backsp":
            InputLine.text = InputLine.text.Substring(0, InputLine.text.Length - 1);
            break;

        case "Enter":
            isdone = true;
            break;

       default:
            InputLine.text += ButtonPressed.text;
            break;
    }


    if (ProcessInput == null) Debug.Log("ProcessInput is null at pointerdown"); else Debug.Log("ProcessInput is NOT null at pointerdown");

}

public void OnPointerUp(PointerEventData p)
{

}

public void CloseKeyboard()
{
    GameObject VRKeyboard = transform.parent.parent.parent.gameObject;

    VRKeyboard.SetActive(false);
    if (ProcessInput == null) Debug.Log("ProcessInput is null at close");

    //This line below is where I get the error:
    ProcessInput(); 
}

Solution

  • I resolved the problem by using a Static variable for ProcessInput... Weird still, I'm not sure while Unity forgets the value of a public UnityEvent while it's processing a OnPointerDown event.