GameDev : Script Communication (Damage and Life systems)!
Ok, to test OnTriggerEnter method we Destroy both Enemy and Player, but in a real game we want take some damage before die. So we need to set up a Life and Damage system.
How can make this possible?
In Pseudo code this is what we want
After they collide, Player take damage and Enemy die.
If we think about it, to takedamage we need a Life!
So we need to create a Life System!
If we think a game like an RPG or even a FPS, we take damage before die.
Well, Life is a simple variable! We use a variable contains our life and every time we take damage life go down, of we take some health regen or potion, life goes up!
We can start in easy way to create “life” variable in our Player script.
I make the variable private, but we need to ACCESS that variable outside of this class, right?
Because we have to take a “lives” every time we are hit by the enemy.
For now, we try to take things easy to understand better, but in more advance topics and articles I will talk about PROPERTIES.
With it we can take every variable private inside our Class, but ACCESSIBLE FROM OUTSIDE without problems.
Properties are great!
We starting with create a method to Damage our Player
A little explanation here: we make this method PUBLIC, because we have to access it from the outside.
If I make it private, it is the same as with variables and this method can ONLY be called WITHIN THE PLAYER CLASS.
If I write
void Damage()
is the same as PRIVATE.
private void Damage() and void Damage(), same thing.
And this type of syntax works even with variables.
Inside the Damage () method what do we need?
Simple: lives must decrease by 1.
We can do this with 3 different syntax
lives = lives- 1
lives = live-=1
lives- -
The last type is probably the most use, follow by second.
The first type it works and it’s not wrong, but normally is the less used.
So with this method we take off one lives every time.
But if we have zero lives?
We have to Die right?
Inside Damage method, we check if the lives are LESS THAN ONE
With this we are ok!
To make it better, we can do this
We have a method of taking damage and a method of dying, easy and clean.
I make it PRIVATE, because the method Damage () can be called OUTSIDE script, but the DIE () method only INSIDE this script.
And it’s completely fine.
But now we have to understand the concept of SCRIPT COMMUNICATION. Because the two script have to COMMUNICATE to call DAMAGE() method every time we take hit.
The script communication, especially at the beginning, is not the easiest thing to understand, but we try to explain it in the simplest way possible.
To call method from one class to another class we need A REFERENCE, ok?
This way whenever the Enemy class hits the Player class, the Damage()
method will be called by the Player class.
In this specific case, we are inside a Trigger method ok?
And inside OnTriggerMethod, in this section
we have a REFERENCE OF EVERY OBJECTS HIT BY ENEMY
It sounds complicated, but in the previous article we saw how it works, right?
With this concept in mind, thanks to “OTHER”, we can ENTER INSIDE ANY OBJECT that COLLIDES WITH US, and MANIPULATE COMPONENTS of that object.
We look in code : if I type
other.gameObject.
then we use GETCOMPONENT.
As we can read, GetComponent takes a component of another object! In this case, we need to call the Damage () method.
WHICH COMPONENT DO WE HAVE TO TAKE TO BE ABLE TO CALL THAT METHOD?
Damage() is inside Player script, and every scripts is a COMPONENTS of gameObjects with specific behaviour.
So we need to enter in Player to call Damage()
If we take PLAYER COMPONENT, we enter in Player script and we can call Damage() method!
The syntax of GetComponent is
GetComponent<>();
Between the major / minor signs we need to insert the Component we need.
If we use GetComponent<>().
after the dot sign we can go deep in that component, like this
Try to test it with Debug.log()
Press Play
Lives go down by 1 and Enemy Die. Good!
Before finish : every time we need scripts communication, is ALWAYS a best practice make a CHECK.
We saw in test that code run without problems, but if I make this
I press Play e than press Pause.
Go in Player inspector and REMOVE THE SCRIPT
Press Pause again and see what happen
Unity give us a REFERENCE NULL EXCEPTION, because we try to grab a Component that MISS, so is NULL.
That’s why every time the best practice is to make a control if component is NULL.
To do this check, we store a value of Player in a varibale, like this
We delete the line below, and create a check if this component is Null
This symbol != means NOT
In this case, IF PLAYER IS NOT NULL, RUN THE CODE
And because we have now a DIRECT REFERENCE TO PLAYER, to call Damage() we type
Add some Enemy inside the Scene and test it
When the game is run, if we take Enemy from the folder and insert it into the scene, they work without problems.
To test the three “lives” and the various behaviors it is fine, also because we do not now have “Managers” who manage the flow of the game.
But everything for now works fine!
We have Life system, we take Damage(), and after 3 hit we Die()!
Amazing!!