Delegate on multiple objects didn't work the way I thought

Viewed 30

I had an idea to use delegates for my buttons whenever the button is pressed I can notify everthing listening/subscribed(?) to it and do stuff (I feel like this is a scenario where delegates aren't needed). I have this code attached to 3 objects

public class ClassSelectButton : MonoBehaviour
{
    public delegate void ClassSelectDelegate();
    public event ClassSelectDelegate classSelectedEvent;

    public BaseClass classToGive;

    void Awake()
    {
        var button = GetComponent<Button>();
        if (button)
            button.onClick.AddListener(() => OnButtonPressed());
    }

    void OnButtonPressed()
    {
        if (classSelectedEvent != null)
            classSelectedEvent();
    }
}
public class Player : MonoBehaviour
{
    public BaseClass playerClass;

    void Start()
    {
        FindObjectOfType<ClassSelectButton>().classSelectedEvent += Test;
    }

    void Test(BaseClass newClass)
    {
        playerClass = newClass;
    }
}

Turns out this doesn't work the way I thought it would because when pressing the button only one of the delegates work and I realized that since there's multiple instances of this script there's duplicates of the delegate and so only one of them is being listened to. So what's an alternative way to go about doing this?

p.s: As I was writing this I realized another problem is probably because I'm using FindObjectOfType

1 Answers

Because your delegate is not a match. One of them has a void in parentheses and the other has a BaseClass parameter and the compiler rejects it. Note that you wrote below that playerClass is equivalent to BaseClass...

void Test(BaseClass newClass)
{
   playerClass = newClass;
}

And when the event is run on the other side, you have not defined any new class for it. This mismatch prevents code execution.

void OnButtonPressed()
{
   if (classSelectedEvent != null) classSelectedEvent("Where is new Class??");
}

For fix this issue

First upgrade your delegate as shown below and then move the class from the event run.

public delegate void ClassSelectDelegate(BaseClass baseClass);

Run the event along with the class parameter:

void OnButtonPressed() => classSelectedEvent?.Invoke(classToGive);
Related