Script Communication

It might be tempting to place all the logic within one script. For one, it’s easier as you don’t have to jump between multiple scripts. Because everything’s in one script, there’s no need to think about the communication between multiple scripts. In addition, if there’s something you want to add, remove, or modify, you can just do it in the one script as you don’t have to keep track of what other scripts are doing.

However, by putting everything in one script, there are huge flaws that can, and will likely, arise:

  • Harder to debug: Regardless of what kind of game you make, whether it be a simple platformer to a full-blown FPS, by putting everything in one script, you’ll going to have hundreds of lines of code. Sure, even having separate scripts can still generate hundreds of lines of code, but when you’re trying to debug why a character is moving left when the player is pressing right or why an enemy is still alive after the player kills it, it makes it more harder to figure it out.
  • Little to no flexibility: Say you got a grandiose idea for a game and you start working on it. Yet, as you progress through the development, you came to the realization that the idea is too grandiose for you, so you decided to scale it down to more manageable concepts that you can accomplish. If you realize it before it was too late, it wouldn’t be a problem. However, you have already incorporate parts of the concept into your script, so now what? There’s no need for it anymore and because you wrote everything in one script, you have to painstakingly read through your code, making sure any trace is removed.
  • Still need communication : Even if you decide that it’s easier to write everything in one script and was willing to attach said script on every object that needs it, you are still left with the issue of communication between each object. Aside from combat, a player doesn’t control what an enemy can do. Aside from inventory, a player doesn't control what the benefits of an item is. Aside from dialog, a player doesn’t control what a NPC will do. Without any communication between the player and an enemy, item, and NPC, there is no progress in the game.

Luckily in Unity, it’s as simple as assigning a variable to the script you want and using the GetComponent<> method to grab said script.

For instance:

private GameObject _thePlayer;Player pScript = _thePlayer.GetComponent<Player>();

In this example, I’m creating a Player script variable called pScript. In order to get the script, I would need to grab the Player script from _thePlayer game object.

Once you grab the script, the communication line between the scripts will be established.

There are a couple of ways of getting the game object that has the script you want to communicate with.

The first way is externally, usually through the inspector:

Enemy script that has a reference of the Player

This way is useful if you’re dealing with an object that is already in the scene, like the Game Manager. On the other hand, this method won’t work if the object is being spawned in at runtime, like an enemy, and the script you want is attached to a non-prefab object in the scene, like the Game Manager or player.

The other way is internally, usually through code:

Finding the Player via Tag
Finding the Player via Collision

By finding the object through code, you bypass the “public” variable declaration needed. Furthermore, you also eliminate the need to assign the object to a variable and the error that present itself when the script needed is not from a prefab. And yet, it generate a couple of new issues you’ll have to deal with. First, using the FindGameObjectWithTag method can be taxing on the system, especially when multiple objects are calling it. In addition, because it’s through code, the tag or name has to be exact. If you forget to tag the object, the communication link will never be established. Furthermore, if, in the future, you decide to change the name of the object, you’ll need to remember to change it in the script as well.

Regardless of how to establish the communication link, you’ll need to check and make sure the link is established. You can easily check by doing a null check:

Player pScript = _thePlayer.GetComponent<Player>();if(pScript == null)
{
Debug.Log("Cannot grab Player script from the object!!!");
}

By doing this, even though it doesn’t stop the script from running and creating errors, it gives you a warning that the script you’re looking for was not found on the object you’re trying to pull said script from.