- Home /
How to obtain Subclasses of a class/type?
Say, I have a class called EnemyUnit and multiple subclasses of it called EnemyArcher, EnemyInfantry, etc.
I'm creating an AI for movement in a game and I want to have an EnemyArcher stay one space away from a player unit. The problem is how to check if the current iteration of EnemyUnit in a foreach loop [EnemyUnit enemy in enemyUnitList] is an EnemyArcher? All enemy units have the tag "Enemy" if that helps, but I doubt it.
Can GetComponent work? and if so, how? Thanks.
Answer by CodeElemental · Jun 05, 2014 at 09:03 AM
Assuming you have the class hierarchy something like this :
EnemyUnit (base class)
EnemyArcher
EnemyCaster
EnemyWarrior
Then you can do :
List<EnemyUnit> enemies;
// Fill the list
// Iterate the list
for (int i = 0; i < enemies.Length ; i++)
{
if (enemies[i] is EnemyArcher)
{
// Enemy is archer subclass
} else if (enemies[i] is EnemyCaster)
{
// Enemy is caster subclass
}
}
The is operator is a fundamental operator in OOP ;) However it's usually easier to directly use the as operator since both perform the same check, but the as operator also cast the reference into that type, if possible:
for (int i = 0; i < enemies.Length ; i++)
{
EnemyArcher archer = enemies[i] as EnemyArcher;
if (archer != null)
{
// Enemy is archer subclass
// use "archer" here
continue;
}
EnemyCaster caster = enemies[i] as EnemyCaster;
if (caster != null)
{
// Enemy is caster subclass
// use "caster" here
continue;
}
}
The as-cast does a type check and doesn't throw an exception if it fails but simply returns null. The advantage is that you have both in once: The type check and the cast which is usually necessary since you want to access something specific for this class.
Answer by fafase · Jun 05, 2014 at 09:22 AM
Use polymorphism, way better and faster.
Your enemy class contains all basic info about enemy, sub classes just override the contents when needed.
public abstract class Enemy:MonoBehaviour{
public abstract void Move();
}
public class EnemyCaster:Enemy{
public override void Move(){print("EnemyCaster");}
}
public class EnemyArcher:Enemy{
public override void Move(){print("EnemyArcher");}
}
now you can create a collection of enemy and place those into it.
List<Enemy>list = new List<Enemy>();
foreach(Enemy enemy in list){
enemy.Move();
}
This will print the implementation in the sub class even though you have a collection of top class. This is polymorphism, one of the three big lines of OOP (encapsulation, inheritance, polymorphism).