简体   繁体   中英

Inheritance Variable Questions (Changing inherited variables) in Unity (C#)

I'm sorry, I'm kind of blanking on this subject. For example, lets say I have a base class Character and two subclasses FriendlyCharacter and EnemyCharacter. I want them both to inherit the variables such as health, but I shouldn't make the health variable in Character public right? I would assume that if I changed a public variable in Friendly character, it would change the all instances of health correct?

How would I initialize Character to contain variables that will be inherited by other classes? Once inherited, those classes would have their own instance of that variable. I feel like having to just re-initialize the variable in each subclass would just make the initialization in the base class pointless.

I would greatly appreciate any help.

What you're looking for is interfaces, or abstract/virtual functions. Broadly speaking, there are two techniques:

public abstract class Character : MonoBehaviour
{
    public float m_Health { get; protected set; }
    protected abstract float DefaultHealth { get; }
    void Awake()
    {
        m_Health = DefaultHealth;
    }
}
public class Enemy : Character
{
    protected override float DefaultHealth { get { return 10; } }
}

(Use virtual functions instead of abstract if there should be a base implementation and overriding is optional.) The above pattern is used when the logic is all shared, but little bits are specified differently in subclasses. Big functions in the base class call little functions which may be specified in subclasses.

The second technique is for when the classes look the same to the outside world but function differently on a fundamental level:

public interface ILiving
{
    float Health { get; }
}
public class Character : ILiving
{
    // implement health as a normal variable
    public float Health { get; protected set; }
}
public class OldMan : ILiving
{
    // implement health based on time until death at 2020
    public float Health { get { return (2020-DateTime.Now.Year)/20; } }
}

In this case, two types both have health, but the logic by which they operate is different. To the outside world, they look the same, but they're so different that they shouldn't share any logic.

Note that in Unity, things can get messy. Since we're forced to inherit from MonoBehaviour (and C# lacks multiple inheritance), we can occasionally not use inheritance where we would like to. In those cases, we can mimic inheritance by using interfaces, explicit interface implementation (a reasonable facsimile of protected functions), and extension methods. (The class which defines the extension methods will play the role of the base class.) In general, this comes up when classes want to be part of two class hierarchies (based on two irreconcilable sets of functionality). In a game, armor, weapons, and spells might all want to participate in an upgrade system. Armor and weapons are part of the equipment class hierarchy, but spells are not. So the relevant data is made into interface functions, and the shared code is defined as extension methods (since armor and spells do not share a common base class, except MonoBehaviour ).

In the context of Unity, I'm not sure what you're asking about really works that way.

The best way to accomplish this would be to make a Game Object (Character) that you can copy and tweak as needed (FriendlyCharacter/EnemyCharacter) and just change the Tags in Unity to make sure they interact as they should with other objects.

Generally speaking, in Unity the "Public" or "Private" labels just dictate whether the values can be changed outside of that particular script (ie in the Inspector or by other scripts).

EDIT: Also, as a broader note on Inheritance, changing any inherited variable within an object of a class (or subclass) won't ever change that variable for all of the objects born from the higher class, and that is not what "Public" or "Private" refer to, either.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM