我如何构建我的抽象类

时间:2017-12-01 07:25:22

标签: c# class inheritance unity3d abstract

我正在写一个游戏,想对我的班级层次结构有所了解。

目前我有一个Character类,一个AICharacter类和一个KnightCharacter类。

字符包含所有字符必须促进的Death()之类的东西,AICharacter使用AI驱动字符的额外细节覆盖Death()。 KnightCharacter会覆盖像处理盾牌之类的角色(仅适用于骑士)。

我怎样才能优雅地让我的玩家拥有一个KnightCharacter:角色和我的AI拥有一个KnightCharacter:AICharacter:Character?

我基本上只想在AI控制下实现AICharacter。

由于

2 个答案:

答案 0 :(得分:2)

一种提供很大灵活性的方法是将角色和对象分解为各个方面,每个方面都是自己的类。动作或RPG角色可能具有的方面的一些示例是Health,Mana,WearsEquipment,UsesItems,MobileObject,PhysicalRigidbody,MeleeAttackPerformer,RangedAttackPerformer,MagicAttackPerformer,PlayerControlledMobile,AIControlledMobile,甚至是AudioSource等等......这些中的每一个课程将来自一个共同的基础,例如AspectMixin或类似的东西。

如果您将这些类中的每一个都视为混合,那么您在创建具有对该类型的actor有意义的方面的新原型时会获得很大的灵活性。例如,这将允许怪物和玩家分享他们有健康的事实,但是有不同的类来控制他们(AI控制与玩家控制)。此外,可以将健康方面添加到静止物体(例如枪管),以使其受到损坏的影响。

为实现此目的,您的原型对象存储该原型的方面mixins列表。此外,这些方面需要能够通过类型(或接口)查询主要对象的其他方面。设置需要做一些工作,但这是灵活性的代价。

FWIW,这是Unity引擎试图鼓励的方法(考虑他们称之为MonoBehavior:行为......因为相同概念的不同词语),尽管许多开发人员不会这样做。得到它"直到他们制作了几个失败的原型,其中的课程很快变成了单一的。

回到原来的问题,这取决于你有多少可玩类,以及AI是否可以控制相同类的字符。如果是这样,最好从控制字符中抽象出控件,然后从控件派生出AIControls和PlayerControls,其中任何一个都可以与你的角色类接口。

另一方面,如果AI类型可以分解为几种不同的行为(攻击性怪物,和平NPC),我会让每个人都成为一个方面。

答案 1 :(得分:1)

普通的c#继承可能无法满足您的要求。你哥哥不能和你有不同的祖父。

由于您似乎在寻找创意,所以这里使用泛型:

abstract class BaseController
{
    virtual GameEvent ReadNextEvent();
}

class PlayerController : BaseController
{
    override GameEvent ReadNextEvent
    {
        return userInterface.ReadNextEvent();
    }
}

class NonPlayerController : BaseController
{
    override GameEvent ReadNextEvent
    {
        artificialIntelligenceEngine.Think();
        return artificialIntelligenceEngine.ReadNextEvent();
    }
}

abstract class Character<T> where T : BaseController
{
    protected T controller;

    abstract ProcessEvents();
}

class KnightCharacter<T> : Character<T>
{
    override ProcessEvents()
    {
        var e = controller.ReadNextEvent();
        switch (e.Action)
        {
            1 : SwingSword(); break;
            2 : LiftShield(); break;
            3 : Yell("None shall pass!"); break;
        }
    }
}



class Program 
{
    void Example()
    {
        var playerKnight = new KnightCharacter<PlayerController>();
        var aiKnight = new KnightCharacter<NonPlayerController>();
    }
}