Problem with Collider2D

Hi I have a problem with those two scripts. The Sword script triggers when its PolygonCollider2D hits BoxCollider2D of the Enemy and it triggers damageImage.color = flashColour;, but it doesn’t make currentHealth shrink. Maybe some fresh look will help?

EnemyHealth

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class EnemyHealth : MonoBehaviour {

    public  int startingHealth = 10;
    public int currentHealthEnemy;
    public Image damageImage;
    public AudioClip deathClip;
    public float flashSpeed = 5f;
    public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
    public int scoreValue = 10;
   
    Animator anim;
    AudioSource enemyAudio;
    ParticleSystem hitParticles;
    BoxCollider2D boxCollider2D;
    PolygonCollider2D polygonCollider2D;
     public Sword sword;

    enemy enemyMobility;

    bool isDead;
    bool damaged;

   
    void Awake ()
    {
        //Seeting up the references
        sword = GetComponent <PolygonCollider2D>;
        anim = GetComponent <Animator> ();
        enemyAudio = GetComponent <AudioSource> ();
        hitParticles = GetComponentInChildren <ParticleSystem>();
        boxCollider2D = GetComponent <BoxCollider2D> ();
        polygonCollider2D = sword.GetComponent <PolygonCollider2D>();

       
       
        //setting up initial health
        currentHealthEnemy = startingHealth;
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.name== "sword")
        {
            damageImage.color = flashColour;

        }
        else{
            return;
        }
    }

    void Start()
    {
        if (polygonCollider2D.isTrigger == true){
        GameObject go = GameObject.FindWithTag("DamageImage");
        damageImage = go.GetComponent<Image>();
       
        }
        else{
            return;
        }
    }
    void Update()
    {
        //if the enemy has just been damaged...
        if(damaged)
        {
            damageImage.color = flashColour;
       
        }
        else
        {
            damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
        }

   
        damaged = false;
    }
   
    public void TakeDamage (int amount)
    {
        damaged = true; //błyskanie
        if(!isDead)
        {
            return;
        }
        enemyAudio.Play ();
        currentHealthEnemy -= amount;

        if(currentHealthEnemy <= 0)
        {
            Death ();
        }
    }
   
    void Death ()
    {
        isDead = true;
        //boxCollider2D.isTrigger = true;


        anim.SetTrigger ("enemyDead");
        enemyAudio.clip = deathClip;
        enemyAudio.Play ();
        Destroy (this.gameObject);

       
    }

}

Sword:

using UnityEngine;
using System.Collections;

public class Sword : MonoBehaviour {

    Animator anim;
    GameObject enemy;
    EnemyHealth enemyHealth;
    ScoreManager scoreManager;
    //public int amount = 100;
    bool enemyInRange;
    public int attackDamage = 10;

    void Awake()
    {
        anim = enemy.GetComponent<Animator>();
        enemy = GameObject.FindGameObjectWithTag ("Enemy");
        enemyHealth = enemy.GetComponent<EnemyHealth>();
    }

void OnTriggerEnter2D(Collider2D enemy)
    {
        if(enemy.tag== "Enemy")
        {
        //Destroy (enemy.gameObject);
            enemyInRange = true;

        }
    }
    void OnTriggerExit2D (Collider2D enemy)
    {
        if(enemy.name == "Enemy")
        {
           
            enemyInRange = false;
        }
   
    }

    void Update ()
    {

        //if the enemy is in range and this enemy is alive...
        if (enemyInRange)
        {

            Attack();
        }
       
        //if the enemy has zero or less health///
        if (enemyHealth.currentHealthEnemy <= 0)
        {
            //tell the animator that enemy is dead
            anim.SetTrigger ("enemyDead");
        }
    }

    void Attack()
    {
   
       
        //if the enemy has health to lose///
        if (enemyHealth.currentHealthEnemy > 0 && enemyInRange)
        {
            //damage the enemy
       
            enemyHealth.TakeDamage (attackDamage);
        }
       
    }
}

For now, I have this error:
cannot convert method group ‘GetComponent’ to non-delegate type ‘Sword’ consider using parentheses to invoke the method.
I have no idea what that error means.
Please help:)

Well, you’re assigning a polygon collider to sword:

sword =GetComponent;

but your sword is of type 'Sword:

public Sword sword;

You need to make it of type PolygonCollider2D:

public PolygonCollider2D sword;

I changed it, but there is an error, which occured before:

UnassignedReferenceException: The variable sword of EnemyHealth has not been assigned.
You probably need to assign the sword variable of the EnemyHealth script in the inspector.

Of course I made an assignement in the inspector, but I keep getting this error when both colliders touch themselves.

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class EnemyHealth : MonoBehaviour {

    public  int startingHealth = 10;
    public int currentHealthEnemy;
    public Image damageImage;
    public AudioClip deathClip;
    public float flashSpeed = 5f;
    public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
    public int scoreValue = 10;
   
    Animator anim;
    AudioSource enemyAudio;
    ParticleSystem hitParticles;
    BoxCollider2D boxCollider2D;
    public PolygonCollider2D sword;
    // public Sword sword;
    PolygonCollider2D polygonCollider2D;

    enemy enemyMobility;

    bool isDead;
    bool damaged;

   
    void Awake ()
    {
        //Seeting up the references
        //sword = GetComponent <PolygonCollider2D>;
        anim = GetComponent <Animator> ();
        enemyAudio = GetComponent <AudioSource> ();
        hitParticles = GetComponentInChildren <ParticleSystem>();
        boxCollider2D = GetComponent <BoxCollider2D> ();
        polygonCollider2D = sword.GetComponent <PolygonCollider2D>();

       
       
        //setting up initial health
        currentHealthEnemy = startingHealth;
    }
(...)
}

So the error occurs only when the colliders collide? Can you show your collision code?

It is inside EnemyHealth and Sword scripts:) Yes, it occurs when they collide. It’s weird, I thought everything was written correctly.

Aslo, there is an error

NullReferenceException: Object reference not set to an instance of an object
Sword.Awake () (at Assets/Sword.cs:16)

on that fragment of code inside Sword.cs:

void Awake()
    {
        anim = enemy.GetComponent<Animator>();

But it occurs even if I start the game.

anim = enemy.GetComponent();

enemy is null. I see you do this:

anim = enemy.GetComponent();
enemy = GameObject.FindGameObjectWithTag (“Enemy”);

You should switch them around like this:

enemy = GameObject.FindGameObjectWithTag (“Enemy”)
anim = enemy.GetComponent();

Unfortunately, it doesnt work. They are colliding, but right now the blinking of a screen (damageImage.color=flashColour;) is not working as well, so objects are colliding, but there is some problem with EnemyHealth script.
I guess I should put something in this condition in EnemyHealth script:

void OnTriggerEnter2D(Collider2D other)
    {
        if(other.name== "sword")
        {
            damageImage.color = flashColour;

        }
        else{
            return;
        }
    }

To be clear: Sword is a child of a Player object and it’s PolygonCollider2D is getting enabled in an animation. Maybe that’s why the code is not working?

Okay, for now here is the situation:

If Sword object is not assigned in the inspector, the OnTriggerEnter2D method is running, but only
damageImage.color = flashColour;
works. In this case, when I run the game the EnemyHealth script is automatically being unchecked by Unity.

When I assign the Sword object in inspector, then the EnemyHealth script is checked, but the damageImage.color=flashColour; is not working.

In both cases, when I put Destroy (this.gameObject); in OnTriggerEnter2D method, it destroys the object, so colliders are working.

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class EnemyHealth : MonoBehaviour {

    public  int startingHealth = 10;
    public int currentHealthEnemy;
    public Image damageImage;
    public AudioClip deathClip;
    public float flashSpeed = 5f;
    public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
    public int scoreValue = 10;
 
    Animator anim;
    AudioSource enemyAudio;
    ParticleSystem hitParticles;
    BoxCollider2D boxCollider2D;

    public Sword sword;

    PolygonCollider2D polygonCollider2D;


    GameObject enemy;
    bool isDead;
    bool damaged;

 
    void Awake ()
    {
        //Seeting up the references
   
        enemy = GameObject.FindGameObjectWithTag ("Enemy");
        boxCollider2D = GetComponent <BoxCollider2D> ();

        polygonCollider2D = sword.GetComponent <PolygonCollider2D>();

        anim = GetComponent <Animator> ();
        enemyAudio = GetComponent <AudioSource> ();
        hitParticles = GetComponentInChildren <ParticleSystem>();
     
     
        //setting up initial health
        currentHealthEnemy = startingHealth;
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.name== "sword")
        {
            damageImage.color = flashColour;
            damaged=true;
            //Destroy (this.gameObject);


        }
        else{
            return;
        }
    }

    void Start()
    {
        if (boxCollider2D.isTrigger == true){
        GameObject go = GameObject.FindWithTag("DamageImage");
        damageImage = go.GetComponent<Image>();
     
        }
        else{
            return;
        }
    }
    void Update()
    {
        //if the enemy has just been damaged...
        if(damaged)
        {
            damageImage.color = flashColour;

     
        }
        else
        {
            damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
        }

 
        damaged = false;
    }
 
    public void TakeDamage (int amount)
    {
        damaged = true; //błyskanie
        currentHealthEnemy -= amount;
        /*if(!isDead)
        {
            return;
        }*/
        enemyAudio.Play ();


        if(currentHealthEnemy <= 0 && isDead)
        {
            Death ();
        }
    }
 
    void Death ()
    {
        isDead = true;
        //boxCollider2D.isTrigger = true;


        anim.SetTrigger ("enemyDead");
        enemyAudio.clip = deathClip;
        enemyAudio.Play ();
        Destroy (enemy.gameObject);

     
    }

}

Sword:

using UnityEngine;
using System.Collections;

public class Sword : MonoBehaviour {

    Animator anim;
    GameObject enemy;
    EnemyHealth enemyHealth;
    ScoreManager scoreManager;
    bool enemyInRange;
    public int attackDamage = 10;

    void Awake()
    {
        enemy = GameObject.FindGameObjectWithTag ("Enemy");
        enemyHealth = enemy.GetComponent<EnemyHealth>();
        anim = enemy.GetComponent<Animator>();
    }

void OnTriggerEnter2D(Collider2D enemy)
    {
        if(enemy.tag== "Enemy")
        {
     
            enemyInRange = true;

        }
    }
    void OnTriggerExit2D (Collider2D enemy)
    {
        if(enemy.name == "Enemy")
        {
         
            enemyInRange = false;
        }
 
    }

    void Update ()
    {

        //if the enemy is in range and this enemy is alive...
        if (enemyInRange)
        {

            Attack();
        }
     
        //if the enemy has zero or less health///
        if (enemyHealth.currentHealthEnemy <= 0)
        {
            //tell the animator that enemy is dead
            anim.SetTrigger ("enemyDead");
        }
    }

    public void Attack()
    {
 
     
        //if the enemy has health to lose///
        if (enemyHealth.currentHealthEnemy >= 0)
        {
            //damage the enemy
     
            enemyHealth.TakeDamage (attackDamage);
        }
     
    }
}

Also, I’m getting
“NullReferenceException: Object reference not set to an instance of an object”
on “polygonCollider2D = sword.GetComponent ();” in EnemyHealth

and on

    public void Attack()
    {
  
      
        //if the enemy has health to lose///
        if (enemyHealth.currentHealthEnemy >= 0)

in Sword script, when colliders collide

I think it’s because of this code in your Awake method of Sword script:

  • enemy = GameObject.FindGameObjectWithTag (“Enemy”);
  • enemyHealth = enemy.GetComponent();

Either:

  1. It can’t find any GameObject with tag “Enemy”
  2. enemy does not have an EnemyHealth script attached to it.

Check to see your enemy is really tagged as “Enemy” and is not disabled when the game starts. Also make sure it has an EnemyHealth component.

The Enemy object is presented on a screen at the same time Player with Sword object (when game starts, they are already on a screen). Enemy is tagged as Enemy and has Enemy Health Script attached to it.
If I don’t attach any object in Inspector to the Enemy Health (Sword), then when game starts, it is disabled. When I attach object Sword, it starts checked.
Sword object is checked as visible all the time, but it’s Polygon Collider 2D is being enabled in Animator. Maybe this is a problem? I am struggling with script-animator triggers right now, so maybe animations are preventing the script Sword and EnemyHealth from running properly?

this is what it looks like:

”polygonCollider2D = sword.GetComponent();”

Are you assigning sword in the inspector?

You mean in the script EnemyHealth in inspector? Yes, I do. I attached a screenshot in previous post. Is this what you mean?

No can you post a screenshot of Sword?


This is it. Polygon Collider 2 is being enabled in the animator.

I think it’s because your PolygonCollider2D is disabled. Try enabling it and see if that fixes your NullReference error.

But as I said before, Polygon Collider 2D is getting enabled during the animation, look:


And, of course, enabling it, besides the animation, doesn’t change anything.

Yes, but Awake runs before the animation so at the time Awake runs it will be disabled and GetComponent will not get it because it’s disabled.

I moved
polygonCollider2D = sword.GetComponent ();
from Awake() to Update()
but there is the same error.

I put this line of code where it was before, and I run the game again. EnemyHealth.currenthealthEnemy is shrinking now, as the sword collides with it.
Now I have to learn how to make trigger “anim.SetTrigger (“enemyDead”);” from void Death() work, because “Destroy(enemy.gameObject);” that is present in a code after the anim.SetTrigger doesn’t run. When it is before SetTrigger, it works.

Thank you very much for helping me. I appreciate it.

PS: The bad thing is, I don’t know what was the problem here.:wink:

It was a while, and the problem still occurs.
When the Sword collides with Enemy object, everything works fine.
But when it comes to a prefab made of the Enemy object, the health parameter is not shrinking, like the sword collider is not colliding with enemyprefab object (but it is, there is a screen light blinking and particles system working).
I made sure that I find every object with tag, not the name (because of “clone” in prefab names). I can’t find the fault in code (or maybe the problem is somewhere else?)

This is the sword script:

using UnityEngine;
using System.Collections;

public class Sword : MonoBehaviour {

    Animator anim;
    GameObject enemy;
    EnemyHealth enemyHealth;
    ScoreManager scoreManager;
    //public int amount = 100;
    bool enemyInRange;
    public int attackDamage = 10;


    void Awake()
    {

        enemy = GameObject.FindGameObjectWithTag ("Enemy").gameObject;
        enemyHealth = enemy.GetComponent<EnemyHealth>();
        anim = enemy.GetComponent<Animator>();



    }

void OnTriggerEnter2D(Collider2D enemy)
    {
        if(enemy.tag== "Enemy")
        {
        //Destroy (enemy.gameObject);
            enemyInRange = true;

        }
    }
    void OnTriggerExit2D (Collider2D enemy)
    {
        if(enemy.tag == "Enemy")
        {
          
            enemyInRange = false;
        }
  
    }

    void Update ()
    {

        //if the enemy is in range and this enemy is alive...
        if (enemyInRange)
        {

            Attack();
        }
        /*
        //if the enemy has zero or less health///
        if (enemyHealth.currentHealthEnemy <= 0)
        {
            //tell the animator that enemy is dead
      
            anim.SetTrigger ("enemyDead");

        }*/
    }

    public void Attack()
    {
  

        //if the enemy has health to lose///
        if (enemyHealth.currentHealthEnemy >= 0)
        {
            //damage the enemy

            enemyHealth.TakeDamage (attackDamage);
        }
        else {
            return;
        }
      
    }
}

I tried to move everything from Awake() to Update(), as sword script should find references to enemy clone objects (prefabs) as they are spawning, but when I do it, nothing is spawning any more. I don’t get eny errors and I have no idea why it is happening.

The EnemyHealth script:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class EnemyHealth : MonoBehaviour {

    public  int startingHealth = 10;
    public int currentHealthEnemy;
    public Image damageImage;
    public AudioClip deathClip;
    public float flashSpeed = 5f;
    public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
    public int scoreValue = 10;

    AnimationClip clip;
    Animator anim;
    AudioSource enemyAudio;
    public GameObject hitParticles;
    BoxCollider2D boxCollider2D;
    //public Sword sword;
    public Transform sword;
    PolygonCollider2D polygonCollider2D;
//    public Enemy enemy;
    //enemy enemyMobility;
    GameObject enemy;
    bool isDead;
    bool damaged;
    private Animator animator;

  
    void Awake ()
    {
        //Seeting up the references
        //sword = GetComponent <PolygonCollider2D>;
        enemy = GameObject.FindGameObjectWithTag ("Enemy");
        boxCollider2D = GetComponent <BoxCollider2D> ();
        currentHealthEnemy = startingHealth;


        anim = GetComponent <Animator> ();         //można przenieść do start()
        enemyAudio = GetComponent <AudioSource> ();
        //hitParticles = GetComponentInChildren <ParticleSystem>();
      
      

    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag== "Sword")
        {
            polygonCollider2D = sword.GetComponent <PolygonCollider2D>();
            damageImage.color = flashColour;
            damaged=true;
            Instantiate (hitParticles, enemy.transform.position,Quaternion.Euler(0, 180,0 ));

            //Destroy (this.gameObject);
            //return;

        }

        else{
            return;
        }
    }

    void Start()
    {
        //setting up initial health
        sword = GameObject.FindWithTag("Sword").transform;
        Debug.Log(enemy);
        Debug.Log(this);
        if (boxCollider2D.isTrigger == true){
        GameObject go = GameObject.FindWithTag("DamageImage");
        damageImage = go.GetComponent<Image>();
            isDead = false;
        }
        else{
            return;
        }

    }
    void Update()
    {


        //if the enemy has just been damaged...
        if(damaged)
        {
            damageImage.color = flashColour;

      
        }
  
        else
        {
            damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
        }

  
        damaged = false;


    }
  
    public void TakeDamage (int amount)
    {
        damaged = true; //błyskanie

        currentHealthEnemy -= amount;
        enemyAudio.Play ();
            if(currentHealthEnemy <= 0 && !isDead)
        {
            Death ();
        }
    }
  
    void Death ()
    {

        isDead = true;
        //boxCollider2D.isTrigger = true;

//        Animation.Play(clip.name);
        anim.SetTrigger ("enemyDead");
        //transform.GetComponent<Animation>().Play("enemyDead");
        enemyAudio.clip = deathClip;
        enemyAudio.Play ();
        Destroy (this.gameObject);


      
    }
    /*
    public Animator GetAnimator()
    {
        return animator;
    }*/

}

Confusing.

Is there only one enemy and that’s the only enemy that will ever exist and exists at the start of the scene?
Is that how lines 18 and 20 are always the correct references?