Inheritance and using GetComponent

Hi there,

I’m working on the damage system for my game and I have an Enemy abstract class which is inherited by all enemy type scripts, in this example it’s the Snail.

I have my system set up so that when the collider of a weapon object of a player collides with an enemies collider and they are pressing the “Attack” button, it calculates the damage and reduces the enemies health accordingly.

To do this, the weapon is using:

void OnTriggerStay2D(Collider2D other)
	{
		if (other.gameObject.tag == "Enemy" && Input.GetButtonDown("Attack"))
		{
			enemy = other.gameObject;

			if(character.alignment == "Artisan")
			{
				mainStat = character.luk;
				atkType = character.atk;
				defType = other.GetComponent<Enemy>().GetDef();
			}
		damage = damageScript.CalculateBasicDamage(character.atk, mainStat, defType);
		enemy.SendMessage("EnemyDamaged", damage, SendMessageOptions.DontRequireReceiver);
		Debug.Log("Enemy Hit.");
	}

The problem I’m having is that when this part of the script runs, I get a NullReferenceException at the GetComponent line. The enemy being collided with has the Snail script attached which inherits from Enemy, so I thought I’d be able to use GetComponent to get Enemy and use the GetDef() method to return the Snail’s defense for the calculation, but it doesn’t work. If I replace “Enemy” with “Snail” in GetComponent it does work however.

This wouldn’t be too big a deal if the above snippet didn’t need to be applicable to every monster in the game, but it wouldn’t be practical to have to make a gigantic if statement for every monster in order to get their defense stat.

You are properly using GetComponent in your script. GetComponent will properly find references to a parent class if a child class component is attached to the gameobject. However, GetComponent cannot find components that are not attached to the same object.

Are you sure that the Enemy (or Snail in this case) script is attached to the same gameobject that the collider is on?

If the gameobject with your Enemy script is a CHILD to the gameobject with the collider, you can use:

other.GetComponentInChildren<Enemy>();

If the gameobject with your Enemy script is a PARENT to the gameobject with the collider, you may need to use:

other.transform.parent.GetComponent<Enemy>();

or

other.transform.root.GetComponent<Enemy>();

Alternatively, to find the script anywhere up or down the transform tree of that object.

other.transform.root.GetComponentInChildren<Enemy>();

The problem turned out to be I had left the old Enemy script on the Snail from testing, so even though it was disabled, it was interfering with the Snail script that was on there. Removing the Enemy script solved the problem.