- Home /
Checking what type of enemy you hit
Hey so im creating a game where there is going to be alot of enemies and i use raycast for my melee weapon right now im checking the hit collider tag but that will make a big script if i should do it on every enemy so how should i do it? this is how i do it right now
private void DoAttack()
{
Ray ray = playingCam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, myWeapon.attackRange))
{
myWeapon.attackDamage = Random.Range(myWeapon.minAttackDamage, myWeapon.maxAttackDamage);
if (hit.collider.tag == "StoneGolem")
{
StoneGolemController eHealth = hit.collider.GetComponent<StoneGolemController>();
eHealth.TakeDamage(myWeapon.attackDamage);
Debug.Log(myWeapon.attackDamage);
}
}
}
Answer by ShadyProductions · Feb 04, 2020 at 12:13 PM
Make a base class Enemy and inherit all your subclasses like StoneGolemController from Enemy. And give enemy all the base stats that all enemies should have like health & takedamage method.
In addition you could make Enemy class abstract, so you can only have subclass instances on your game objects.
public class Enemy : MonoBehaviour
{
public int Health;
public void TakeDamage(int dmg)
{
Health -= dmg;
}
}
public class StoneGolemController : Enemy
{
// Any additional fields/methods that are only specific to the golem
}
Then you can do
if (hit.collider.tag == "Enemy")
{
// all golems are enemies, so GetComponent<Enemy>() will retrieve your StoneGolemController
// but as a Enemy type class, giving only access to its base logic.
Enemy eHealth = hit.collider.GetComponent<Enemy>();
eHealth.TakeDamage(myWeapon.attackDamage);
Debug.Log(myWeapon.attackDamage);
Debug.Log(eHealth.GetType().Name); // StoneGolemController
}
If you want different effects for each base method, you can mark your methods as virtual and you can override them in your subclass if you want like so:
public class Enemy : MonoBehaviour
{
public int Health;
public virtual void TakeDamage(int dmg)
{
Health -= dmg;
}
}
public class StoneGolemController : Enemy
{
public override void TakeDamage(int dmg)
{
Shield -= dmg; //just example
}
}
When you now execute following:
Enemy e = GetComponent<Enemy>();
e.TakeDamage(5); //will apply to the shield instead of health
Assuming that e is the golem, you will actually apply the overriden method.
More on inheritance you can find here:
https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/inheritance
$$anonymous$$ovement on the stonegolem should that be in its own script or under the public class StoneGolemController : Enemy?
I personally have movement in a seperate script to keep the logic seperate and easily adjustable, and I just reference the script in my subclass if I need to modify things like movement speed when he walks in traps etc. Like:
public class $$anonymous$$ovementController : $$anonymous$$onoBehaviour
{
public float $$anonymous$$ovespeed;
}
public class StoneGolemController : Enemy
{
public $$anonymous$$ovementController $$anonymous$$ovement;
private void Start()
{
$$anonymous$$ovement = GetComponent<$$anonymous$$ovementController>();
}
}
You could put it in the Enemy base class if movement is the same for each enemy type.
in this line of code you gave me where you have written // StoneGoleController is it because in the console it will say StoneGolemController cause in the console it just say Enemy
Debug.Log(eHealth.GetType().Name); // StoneGolemController