Search code examples
c#unity-game-engineevents

Only one instance has non-null event action in unity. why?


I have this script in 3 different buttons in the UI. I need to make sure that just one panel is open when pressing a button. I use another script to receive the OnClickedPanel event and it subscribe to the event in Start(). When debugging the code all of the instances except one have OnClickedPanel = null.

public class PanelControl : MonoBehaviour
{
    [SerializeField] GameObject panel;

    public static PanelControl panelControl;
    public event Action<string> OnClickedPanel;
    private void OnEnable()
    {
        panelControl = this;
        MenuControl.menuControl.OnMakeRoom += MakeRoom;
    }
    
    // Update is called once per frame
    public void TogglePanel()
    {
        panel.SetActive(!panel.active);
        Debug.Log(OnClickedPanel);
        OnClickedPanel?.Invoke(this.name);
    }


    private void MakeRoom(string _openPanel)
    {
        if (_openPanel != this.name)
        {
            Debug.Log("opening" + _openPanel);
            panel.SetActive(false);
        }
    }
    private void OnDestroy()
    {

        MenuControl.menuControl.OnMakeRoom -= MakeRoom;
    }
}

What am I messing up?


Solution

  • Well in OnEnable you do

    panelControl = this;
    

    which is static and apparently is supposed to be a singleton pattern ... but you say yourself have 3 instances of it!

    So they overwrite each other and you end up with only the very last one to be the panelControl instance.

    I can just guess but your other scripts probably subscribe via the supposed to be singleton

    PanelControl.panelControl.OnClickedPanel += ...;
    

    Now I hope you see why you should immediately stop using singletons at all for your use case and rather introduce a proper reference management!