简体   繁体   English

Unity (C#) 中的继承变量问题(更改继承的变量)

[英]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.例如,假设我有一个基类 Character 和两个子类 FriendlyCharacter 和 EnemyCharacter。 I want them both to inherit the variables such as health, but I shouldn't make the health variable in Character public right?我希望他们都继承诸如健康之类的变量,但我不应该将 Character 中的健康变量设为公开,对吗? 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?我将如何初始化 Character 以包含将由其他类继承的变量? 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.请注意,在 Unity 中,事情可能会变得混乱。 Since we're forced to inherit from MonoBehaviour (and C# lacks multiple inheritance), we can occasionally not use inheritance where we would like to.由于我们被迫从MonoBehaviour (而 C# 缺乏多重继承),我们有时不能在我们想要的地方使用继承。 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 ).所以将相关数据做成接口函数,共享代码定义为扩展方法(因为盔甲和法术不共享公共基类,除了MonoBehaviour )。

In the context of Unity, I'm not sure what you're asking about really works that way.在 Unity 的上下文中,我不确定您要问的内容是否真的有效。

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.实现这一点的最佳方法是制作一个可以根据需要复制和调整的游戏对象(角色)(FriendlyCharacter/EnemyCharacter),只需更改 Unity 中的标签以确保它们与其他对象进行交互。

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).一般而言,在 Unity 中,“公共”或“私人”标签仅指示是否可以在该特定脚本之外(即在检查器中或通过其他脚本)更改值。

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.编辑:此外,作为对继承的更广泛的说明,更改类(或子类)的对象内的任何继承变量永远不会更改从更高类产生的所有对象的变量,这不是“公共”或“私人”指的是,要么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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