1

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?

derHugo
  • 83,094
  • 9
  • 75
  • 115
L.Vezzani
  • 55
  • 5
  • 1
    Double check that you have the appropriate references set in your other script. Possible one of the button was dragged to multiple slots instead of just one of them, making it not error, but subscribe to the same button twice. Hard to say without seeing the other script that is subscribing. Please add the `Start` function from that other script to your question above. – hijinxbassist Feb 16 '23 at 01:02
  • The singleton mode is not very effective in the effect you want to achieve, you can try to add some global instances – wenbingeng-MSFT Feb 22 '23 at 09:19

2 Answers2

2

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!

derHugo
  • 83,094
  • 9
  • 75
  • 115
0

I suspect what you want is a single event being triggered across all your button instances, instead of a unique event for each button instance. Using code to describe the point, I suggest making your event static like so:

public static event Action<string> OnClickedPanel;

And then you’d subscribe to the event using the class type, not an instance:

PanelControl.OnClickedPanel += ...

Once you do that, you can remove the “instance” variable panelControl and all references to it, as I suspect it’s sole purpose was to try and access the events.

Milan Egon Votrubec
  • 3,696
  • 2
  • 10
  • 24