- Home /
get component of gameobject that is type of base class
hello, I have 5 scripts basically
1)Tower
2)Tower_Damage : Tower
3)TurrentLevelOne: Tower_Damage
4)Tower_Buffer:Tower
5)AttackSpeedBuff : Tower_Buffer
and then I have a shop where I can buy these towers TurrentLevelOnePrefab and AttackSpeedBuffPrefab
and i want to have access to the AttackSpeedBuff script or the TurrentLevelOne script but i dont know which script is attached to the bought tower
something like GetComponent(typeof(Tower)) but this one needs to be cast to (TurrentLevelOne) for example so i can have access to its methods , any ideas?
thanks in advance
i can do this with interfaces i think but i wanted to do it with abstract classes
Answer by Commoble · Mar 18, 2017 at 08:47 PM
There's a bunch of ways to do this (assuming Tower is a MonoBehaviour) . Here's a few:
Here's a bad way to do it (to show you you can use GetComponent on subclasses):
AttackSpeedBuff speedBuffComponent = towerPrefab.GetComponent<AttackSpeedBuff>();
if (speedBuffComponent != null)
{
// do stuff
}
TurretLevelOne turretComponent = towerPrefab.GetComponent<AttackSpeedBuff>();
if (turretComponent != null)
{
// do stuff
}
Here's another bad way to do it (to show you how to use typeof and GetType to determine what type a component is):
Tower towerComponent = towerPrefab.GetComponent<Tower>();
if (towerComponent != null)
{
// this is true if the tower component on the prefab is an
// AttackSpeedBuff component or a subclass of AttackSpeedBuff
if (typeof(AttackSpeedBuff).IsAssignableFrom(towerComponent.GetType()))
{
AttackSpeedBuff asbuff = (AttackSpeedBuff)towerComponent;
// do stuff
}
else if (typeof(TurretLevelOne).IsAssignableFrom(towerComponent.GetType()))
{
TurretLevelOne tl1 = (TurretLevel1)towerComponent;
// do stuff
}
}
Both of these ways work. They're not good practice, but they'll do what you need with minimal code reworking. A better way to do it would be to rework your classes so you can get them to do what you need them to do without your shop script knowing what specific kind of tower they are.
When I'm in this situation, I always try to refactor my classes before I resort to things like the solutions I gave above. Sometimes it takes a little creative thinking, but it's usually doable.
this is what i wanted to avoid actually xD
but i managed to do it by adding a simple interface
public interface ITower
{
bool BuyTower();
}
and now my Tower has this added
public abstract class Tower : $$anonymous$$onobehaviour , ITower
{
#region ITower implementation
public abstract bool BuyTower ();
#endregion
}
@ExtinctSpecie Just a heads up, if your Towers are the only thing that implement ITower, there's no need to make an interface; you can define your abstract and virtual functions in the Tower base class and have your subclasses override the functions, e.g.
public abstract class Tower : $$anonymous$$onoBehaviour
{
public abstract bool BuyTower();
}
public class AttackSpeedBuff : Tower
{
public override bool BuyTower()
{
// define the function
}
}
Interfaces are only necessary when you need completely unrelated things to have the same function.
but thanks for your time anyway that is an answer even tho not the best because when you get many towers you get lost into if statements and bad code
You may also consider creating base classes for your turrets and buffs, thus allowing you to call the turret or buff universally, not matter what level it is. Also, I'm not sure why your Tower_Damage derives from Tower. Also if your buffs aren't drastically different, they could all be one classes reworked through the inspector on each instance. Just remember the OOP principles.
Tower describes my stuff that every tower has like a range for example or cost Tower_Damage describes what a tower that can deal damage can do for example HitTarget(GameObject target) but my buff towers do not need something like hit target or rotate or findclosest target this way i can limit and not write code or variables that are never going to be used
i dont know maybe im doing it wrong but thats the best thing i can come up with at the moment
Your answer
