'Subscriber don't receive delegate

Sorry if I bother again with a silly delegates-related question... I'll try to be as precise as possible. I have this situation: Object A + Script A, Object B,D,E... + Script B. Script B has a delegate and should trigger a reaction in Object A through Script A working as a subscriber. E.g.

public class ScriptA : MonoBehaviour
{
    void Start() {
        FindObjectOfType<ScriptB>().onScriptBEvent += DoSomethingInA;
    }

    void DoSomethingInA (string s, float q) {

        print("String: "+s+"; Float: "+q);
    }

}

and

public class ScriptB : MonoBehaviour
{
        
    public delegate void ScriptBDelegate(string name, float q);
    public event ScriptBDelegate onScriptBEvent;

    void Start() {
    }
    
    void RandomMethodInB (string s, float q) {
    
        if(onScriptBEvent != null){
        onScriptBEvent (s, q);
        }
    }
    
}

But it doesn't work. Adding some Debug code I noticed that onScriptBEvent doesn't pass the nullity test although Script A is subscribed.

In my program I wrote alrady many other delegates and every of them work just fine. I try to subscribe Script A to other delegates and they work just fine. The only difference that I see is that Script B is added to many objects (B,C,D..) while the others scripts with delegates are always instantiated once.

Any hint?

Edit solution thx to Ruzihm: the problem was that FindObjectOfType find the first instantiated object, not necessarily the one that send the mesasge. The simplest solution (for me) is to create an array of Script B and than subscribe to each of them:

public class ScriptA : MonoBehaviour
    {
        private ScriptB[] scriptList = new ScriptB[100];
        
        void Start() {
            scriptList = FindObjectOfType<ScriptB>();

            foreach (var script in scpritList){
            script.onScriptBEvent += DoSomethinInA;
            }
        }
    
        void DoSomethingInA (string s, float q) {
    
            print("String: "+s+"; Float: "+q);
        }
    }

and it works!



Solution 1:[1]

Are there multiple objects with ScriptB in the scene simutanously? If there are more than one, FindObjectOfType would only return the first object it found.

To make sure you are referencing the right object, you should do one of these:

  • If the object B is already in the scene, you should drag the object B into the ScriptB field of object A

      [SerializeField] ScriptB m_ObjectB; //drag object B into this field in inspector
      void Start()
      {
          m_ObjectB.onScriptBEvent += DoSomethingInA;
      }
    
  • If object B was instantiated from script, get the reference and add delegate using that

      ScriptB newObjectB = Instantiate(objectBPrefab).GetComponent<ScriptB>();
      newObjectB.onScriptBEvent += DoSomethingInA;
    

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Trong Nguyen