Correct me if I’m wrong, but if I’m reading your problem right, these are your issues:
- You have several unrelated script types, each with a special function on them, and the function is the same name on each of these scripts, and you want to be able to call this function from Script A, regardless of which type of script Script B is.
- You need to get a reference to Script B or the script’s gameobject, regardless of which type Script B is.
To solve (1): In this situation, the first thing I’d do is use class inheritance to make each script class a subtype of the same base class. For example, if these are scripts for different enemy types, you can make each script class inherit from an Enemy class (that itself inherits from MonoBehaviour). Then, you can take the function shared by the two scripts, and put it in Enemy. So now you get a reference to an Enemy script, and you can call that function regardless of which subtype of Enemy you have.
Now sometimes, your scripts are just too different to use object inheritance like this. In this case (and only after carefully considering whether your setup can be refactored to use inheritance like this), THEN SendMessage becomes useful. SendMessage allows you to invoke a function by string in any script on a given GameObject, and BroadcastMessage also invokes that function in every script on every child object in that GameObject’s hierarchy (this can get very slow if the object has lots of children).
In either case, though, what we need in the first place is a reference to the gameobject or the script on it. These are mostly the same; if you have a variable someScript
containing a reference to a script (or any component class), you can get its gameobject via someScript.gameObject
. If you have a reference to a gameobject, you can get a reference to a script on it with someObject.GetComponent<ScriptType>()
(and if you have to use SendMessage and have the gameobject reference, you don’t need a reference to the script itself).
So now we’re at (2) – getting a reference. By far the best way to reference a script or gameobject from another script is to link them directly in the scene editor. This is possible when both objects are part of the scene asset; i.e. you can see both of them in the scene editor, neither is instantiated during runtime. In this case, you can link one object to another by going to your Script A and declaring public GameObject otherObject;
or public ScriptType otherScript;
, which will create a field in Script A’s inspector when it’s a component on an object. You can drag a gameobject or relevant script to that field to link it to the Script A component, and that public variable in the script’s code will be filled out by Unity for you, allowing you to reference that object or script directly without searching by name.
On the other hand, if either or both of your objects are being instantiated at runtime (and HAVE to be instantiated at runtime), then this gets a bit trickier, because we can’t link them in the scene editor. At this point, my thought process is usually something like this:
- Do the objects interact via collisions, triggers, raycasts, or similar interactions? These all grant the interacting objects references to each other.
- If not, then can I use the scripts that instantiated Script A and Script B’s objects to pass references to them? Call them A Creator and B Creator. If these have a reference to each other or interact with each other, they may be able to pass information about Script A and B when Script A and B are created (if neither script A nor B are created during runtime, then this is irrelevant because you can link them directly, as described earlier).
- If not, then do I have a script that can be referenced globally without searching by string (I won’t go into how to do this here), and is Script A or B important enough for that global script to have a reference to it?
- Finally, if none of these apply, then I’ll search for the object by string, preferably by tag rather than by name.
From here, you have a direct reference, and you can call the function on the script or call SendMessage on the gameobject.
This got a bit long-winded, but the point I’m trying to make here is that it’s only very, very rarely that you actually need to search for objects by string to call functions in their scripts. Sometimes you can solve a complicated problem by throwing it out and solving a simple problem instead, once you’re aware of the simpler problem’s existence.
If nothing in this answer applies to you, we’ll need to know the context in much deeper detail.