Home > Software engineering >  Health system in a 2D game
Health system in a 2D game

Time:11-04

The enemy is killed, if you jump on him, on contact, damage is done to me and the enemy, how can I make sure that only the enemy is dealt? what do you need to use for this?
The script is tied to the enemy and the player:

private void OnCollisionEnter2D(Collision2D coll)
    {
        Health health = coll.gameObject.GetComponent<Health>();

        if (coll.gameObject.CompareTag(collisionTag)) //t
        {
            foreach (ContactPoint2D point2D in coll.contacts)
            {
                if (point2D.normal.y >= 0.5f)
                {
                    //Destroy(enemy.gameObject);                    
                    health.takeDamage(damage);
                }
                else 
                {
                    health.takeDamage(damage);
                }
            }
        }
    }

I tried it like this, but then the damage is done from one side

foreach (ContactPoint2D point2D in coll.contacts)
            {
                if (point2D.normal.y >= 0.5f)
                {
                    //Destroy(enemy.gameObject);                    
                    health.takeDamage(damage);
                    

                }
                else if (point2D.normal.x >= 0.5f)
                {
                    health.takeDamage(damage);
                }
            }

enter image description here

CodePudding user response:

Check the Collision2D documentation. "The incoming GameObject involved in the collision." So coll.gameObject.GetComponent<Health>(); Refers to the incoming object, and the script is tied to the enemy and the player, both are involved in the collision. So health is taken from both as the player collides with the enemy and viceversa.

Attach the script only to the enemy so as only the energy is taken from him when the player's collisionTag collides in.

On the other hand, same thing happening in the if and in the else, makes it useless :)

if (point2D.normal.y >= 0.5f)
{
    //Destroy(enemy.gameObject);                    
    health.takeDamage(damage);
}
else 
{
    health.takeDamage(damage);
}

CodePudding user response:

My idea would be instead of using any method like takeDamage() just use a variable and it would be much more efficient.

Make a GameManager class and put the health of both the enemy and player in int or long variable and set its value to its maximum health.

Then create a instance of GameManager class itself, the code in GameManager class would look like,

public static GameManager Instance = this;
public int playerHealth = 100;
public int enemyHealth = 100;

In your Player Prefab create and attach a script containing these lines,

private void OnCollisionEnter2D(Collision2D coll)
    {
        if (coll.gameObject.Tag == "Enemy") //Tag your Enemy Prefab with name "Enemy".
        {
            //Now you can directly reduce the value of enemy and player health without create any reference to the GameManager class.
            
            //Whenever the player hits or come in contact with the enemy the health of player and enemy reduces by 10;

            GameManager.Instance.playerHealth -= 10; 
            GameManager.Instance.enemyHealth -= 10; 
        }
    }

You can then do the function as you wish in the Update() method of GameManager when the health of either the player or enemy's health become low or equals to 0.

For example,

private void Update()
{
    if(enemyHealth <= 0) 
    {
        PlayerWin();
    }

    if(playerHealth <= 0)
    {
        EnemyWin();
    )
}
  • Related