Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

share|improve this question
2  
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 '12 at 19:41

3 Answers 3

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();
    }
}
share|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 '12 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 '12 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 '12 at 23:38

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.

share|improve this answer

If there are properties or methods in your child class that requires usage from your parent class, then you should probably recompose your class design and consolidate that functionality upward. Unless there is a fault with the parent class method that prevents a child class method from doing something different and/or unique. In that case, read below.

For your follow on question, which seems to be "How do I have a common function in my parent class that is common to all subclasses, yet have each child class have a different implementation?", I may have a solution. You could use one public method that calls a virtual method in your parent class, that will be inherited by all of your child classes. The virtual method could then be overriden safely by all of your parent classes and have a slightly different implementation or effect, but still be used by calling the parent class public method. For example,

public class ParentObject
{
    public void Run()
    {
        ImplementationRun()
    {

    // Stub virtual method to be overriden in child classes
    protected virtual void ImplementationRun()
    {
    }
}

public class ChildObject : ParentObject
{

    protected override void ImplementationRun()
    {
        // Child Class specific implementation here
    }
}

This way you could still utilize your child class methods in the virtual function, that will execute in the parent class method, rather than contort the parent class method to suit a child class specific instance.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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