I'm creating a system where there is a base "Hero" class and each hero inherits from that with their own stats and abilities. What I'm wondering is, how could I call a variable from one of the child scripts in the parent script (something like maxMP = MP) or call a function in a parent class that is specified in each child class (in the parent update is alarms() in the child classes alarms() is specified to do something.)

Is this possible at all? Or not?

Thanks.

link|improve this question

42% accept rate
1  
If you need to call a child class' function inside of your parent class, you should probably take another look at your design. Your parent class should be unaware of any of the more detail classes which are derived from it. – ktodisco Mar 18 at 19:41
feedback

2 Answers

I suppose you can use reflection to achieve the setting of stats, as long as Unity3D allows it. I should warn you however reflection is relatively slow so you should look at your design before implementing reflection. The method calling is simple, make the base Hero class's Alarms() virtual and override it in the children classes.

The output of the following for instance is

Hero's MP is 40/100

Hero's MP is 40/400

Wizard's Alert!

class Program
{
    static void Main()
    {
        BaseHero hero = new Wizard() {MaxMp = 100, Mp = 40};
        Console.WriteLine("Hero's MP is {0}/{1}", ((Wizard) hero).Mp,
                                                    ((Wizard) hero).MaxMp);
        hero.SetStat("MaxMp",400);
        Console.WriteLine("Hero's MP is {0}/{1}", ((Wizard)hero).Mp, 
                                                    ((Wizard)hero).MaxMp);
        hero.TriggerAlert();
    }
}

class BaseHero
{
    public void TriggerAlert()
    {
        Alert();
    }

    //This will only fire if the child classes do not override,
    //or if the child class calls base.Alert()
    protected virtual void Alert()
    {
        Console.WriteLine("Base Alert!");
    }

    //Reflection to set fields, requires the name of the field and the value
    public void SetStat<T>(string statName,T value)
    {
        FieldInfo field = GetType().GetField(statName);
        field.SetValue(this, value);
    }
}

class Wizard:BaseHero
{
    public int Mp = 0;
    public int MaxMp = 0;

    protected override void Alert()
    {
        Console.WriteLine("Wizard's Alert!");
        //Uncomment this line to have both the Wizard's alert and the base hero's alert fire
        //base.Alert();
    }
}
link|improve this answer
1  
Yup, Unity does allow reflection. Also, you are spot on in pointing out that it is quite slow. – ktodisco Mar 19 at 2:31
Hrmm...I'm redoing my code in a more intuitive manner, I should be able to fix most of my errors with the variables. What I'm more wondering is how would I get each child to do the alarms() function? If I write in the child's update() function doesn't it override everything in the parent's? Because alarms() is specified in the child class rather than the parent class, it won't allow me to just call the alarms() function in the parent update. – Timothy Williams Mar 19 at 5:15
If I'm understanding you correctly uncomment the last line in Wizard.Alert() that will change the output to add in Base Alert! at the end. Also the BaseHero.TriggerAlert() method isn't needed if you make Alert() public or internal. – Tangeleno Mar 20 at 23:38
feedback

if you think about it a different way, your Stats and Abilities data could be components on the Hero & Wizard objects, which you would then access with:

myHero.GetComponent<StatsComponent>().GetMp();

then you're simplifying your hierarchy and preferring composition over inheritance.

Hero.TriggerAlert() could access a component directly or use the SendMessage() functionality built into Unity game objects.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.