2017-12-01 34 views
0

저는 게임을 쓰고 있고 클래스 계층에 대한 의견을 듣고 싶습니다.추상 클래스를 어떻게 구조화 할 수 있나요?

현재 Character 클래스, AICharacter 클래스 및 KnightCharacter 클래스가 있습니다.

문자에는 Death()와 같은 모든 문자가 있어야하며 AICharacter는 AI가 구동하는 문자에 대한 자세한 내용으로 Death()를 재정의합니다. KnightCharacter는 Shields (Knights에만 해당) 처리와 같은 인물을 무시합니다.

내 플레이어가 KnightCharacter : Character를 소유 할 수있게하려면 어떻게해야하고 AI는 KnightCharacter : AICharacter : Character를 소유하도록 우아하게 허용 할 수 있습니까?

AI로 제어 할 때 AICharacter 만 기본적으로 구현하고 싶습니다.

감사

많은 유연성이 문자를 파괴하는 것입니다 제공하고 각 측면은 자신의 클래스 다양한 측면, 아래로 개체를
+2

나는 AI에 대한 인터페이스를 사용합니다 ...그런 식으로 KnightCharacter가 상속됩니다. AI 클래스를 코딩해야 할 때 AI 인터페이스를 구현합니다. –

+0

위의 Martin과 같지만 AICharacter가 능력이라면 인터페이스 여야합니다. 상속은 하위 클래스가 최상위 클래스로 정의됩니다. 인터페이스 구현은 클래스가 인터페이스를 수행 할 수있는 것으로 정의됩니다. 귀하의 경우 기사는 AIMovement를 수행 할 수있는 캐릭터입니다. – Everts

답변

2

한 가지 방법. 액션이나 RPG 캐릭터가 가질 수있는 측면의 예는 Health, Mana, WearsEquipment, UsesItems, MobileObject, PhysicalRigidbody, MeleeAttackPerformer, RangedAttackPerformer, MagicAttackPerformer, PlayerControlledMobile, AIControlledMobile, AudioSource 등등과 같은 것들입니다. 클래스는 공통 기반 (예 : AspectMixin 또는 그런 것.

이러한 각 클래스를 믹스 인으로 취급하면 해당 액터 유형에 적합한 측면을 가진 새로운 아키타 입을 만드는 데 많은 유연성을 얻을 수 있습니다. 예를 들어, 몬스터와 플레이어는 자신이 건강을 가지고 있다는 사실을 공유 할 수 있지만 AI 컨트롤과 플레이어 컨트롤을 제어하는 ​​클래스가 다릅니다. 또한, 건강 측면을 고정 된 물체 (예 : 배럴)에 추가하여 손상의 영향을받을 수 있습니다.

이를 위해 아키타 입체 객체는 해당 아키 타입에 대한 aspect mixins 목록을 저장합니다. 또한, 측면은 유형 (또는 인터페이스)별로 다른 측면의 주요 객체를 쿼리 할 수 ​​있어야합니다. 설정하는 데는 약간의 작업이 필요하지만 이는 유연성의 대가입니다.

FWIW, 이것은 Unity Engine이 권장하려고하는 접근 방식입니다 (동일한 개념에 대해 MonoBehavior : behavior..aspect ... 다른 단어라고 생각하십시오). 그러나 많은 개발자가 그들은 클래스가 신속하게 모 놀리식이되는 몇 가지 실패한 프로토 타입을 만들었습니다.


원래 질문으로 돌아가려면 재생할 수있는 클래스의 수와 AI가 같은 클래스의 문자를 제어 할 수 있는지 여부에 따라 다릅니다. 그렇다면 캐릭터의 컨트롤을 추상화 한 다음 AIControls 및 PlayerControls를 컨트롤에서 파생시키는 것이 가장 좋습니다.이 중 하나는 캐릭터 클래스와 인터페이스 할 수 있습니다.

반면에 AI 유형이 몇 가지 다양한 행동 (공격적인 몬스터, 평화로운 NPC)으로 나뉘어 질 수 있다면, 나는 각면을 하나의 측면으로 만들 것입니다.

+0

위대한 답변을 주셔서 감사합니다. 그래서 예를 들어, SubtractHealth() 함수가있는 헬스 애스펙트가 있고 if (GetComponent ()! = null)와 같은 체크를 할 수있는 함수에서 // AI 만 처리합니다. AspectMixin 클래스에서 상속 한 모든 것의 이점이 무엇인지 잘 모르겠다. 왜 내 구성 요소를 MonoBehaviours로 추가하지 않는가? –

+1

헬스 클래스가 AI에 의해 제어되는지 여부는 신경 쓰지 않아야합니다. 이 동작은 히스 클래스를 사용하는 AI 클래스에 속합니다. –

+0

유니티를 사용하는 것 같습니다. 좋은. 이 작업을보다 쉽게 ​​수행 할 수 있습니다. 따라서 Health에 Add() 및 Remove() 메서드가있는 것이 좋습니다. 기본적으로 다른 클래스는 상태 모듈과 인터페이스해야합니다. AI 컨트롤러는 일반적으로 Awake()에서 Health에 대한 참조를로드 한 다음 필요에 따라이를 사용합니다. 예 : if (myHealth.CurrentHPPercentage rodamn

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>(); 
    } 
} 
+0

여기에 나와있는 메서드는 단일 상속에 대한 올바른 대답입니다 (클래스의 단일 상속 체인에서 기능 만 필요로하는 경우). 여러 기본 클래스의 기능이 필요하면 다중 상속이 지원되지 않으므로 컴포지션으로 이동하거나 다양한 인터페이스에 대한 코드를 다시 구현해야합니다. 내 대답에 설명 된 것처럼 일반적인 관행은 믹스 인을 구성하는 것으로 보입니다. – rodamn