2017-03-28 18 views
0

Unity 3Dで状態マシンを制御しようとしています。 私の質問は継承に関するものです。私は、どのようにして状態が変化するのかを処理する基本ロジックを設定しようとしています。しかし、継承ラインをさらに下げると、私は文字スペックフィックなことをするためには、異なる種類のキャラクターが必要です。しかし、私は継承でこれを行うことができません。ステートマシンの継承チェーンが分岐する

誰かが私の考えがどのように行われているのではないことを確認できますか?私は別の解決策を見つけることを知っています。

擬似コード:

コントローラクラス::

パブリッククラスSoliderController:

 // STATE CONTROLLERS CONTROLL THE CHARACETER BY CHOOSING WITCH STATE THEY SHOULD BE IN 

abstract class StateController { 
    StateBase state; 
    int HitPoints; 
    int Hunger: 

    abstract void Update() 
    { 
      CheckIfStateShouldChange(); 
      state.UpdateState(this); 
    } 
} 

WolfStateController : StateController { 

    WolfState state; 

    override void Update() 
    { 
    base.Update(); 
    state.Update(this); 
    } 
} 

SheepStateController : StateController { 

    SheepState state; 

    override void Update() 
    { 
    base.Update(); 
    state.Update(this); 
    } 
} 

    // STATES CONTAINS LOGIC FOR BEHAVIOUR IN A CERTAIN STATE 
StateBase { 

     virtual void UpdateState(StateController controller) 
     { 

     // Does things all inheriting classes should do 

     } 
    } 

WolfState : StateBase { 

     override void UpdateState(WolfStateController wolfstate) 
     { 
     base.UpdateState(WolfStateController wolfstate) 
      //Does wolf specific things that needs to be done in all WolfStates 
     } 
} 

WolfStalkAndHuntState : WolfState { 

     override void UpdateState(WolfStateController wolfstate) 
     {  
      base.UpdateState(WolfStateController wolfState); 
      //Hunts sheep and attacks on sight 
     } 
    } 

SheepState : StateBase { 

     override void UpdateState(SheepStateController sheepState) 
     { 
      //Does sheepy things 
     } 
    } 

SheepReproduceState : SheepState { 

     override void UpdateState(SheepStateController sheepState) 
     {  
      base.UpdateState(SheepStateController sheepState); 
      // Looks for mate and gets freaky 
     } 
} 
+0

基本クラスが十分でない理由を擬似コードで見ても、あまり明確ではありません。どうぞあなたは詳しく教えていただけますか? – Augure

+0

また、すべての単一文字タイプに対して子クラスを作成する必要がある理由はわかりません。必要な更新フェーズを呼び出すだけで、必要なすべてのデータを保持する抽象的な文字への参照を呼び出すだけで、より抽象的なコントローラを使用する必要があります。 – Augure

+0

継承の代わりに、戦略パターンの使用を検討したいと思うかもしれません。 https://en.wikipedia.org/wiki/Strategy_pattern –

答えて

0

私はこのような何かを示唆しているMonoBehaviour { [HideInInspector]パブリックsState currentStateのを。

[HideInInspector] public FireState fireState; 
[HideInInspector] public IdleState idleState; 
[HideInInspector] public ChaseState chaseState; 


private void Awake() 
{ 
    fireState = new FireState(this); 
    idleState = new IdleState(this); 
    chaseState = new ChaseState(this); 
} 

private void Start() 
{ 
    currentState = idleState; 
} 

private void Update() 
{ 
    currentState.Update(); 
} 

インタフェース:

public abstract class sState 
{ 
public abstract void Update(); 
public abstract void ToChaseState(); 
public abstract void ToIdleState(); 
public abstract void ToFireState(); 
} 

例クラス

public class IdleState : sState 
{ 
private readonly SoliderController controller; 


public IdleState(SoliderController soliderController) 
{ 
    controller = soliderController; 
} 

public override void Update() 
{ 

    Patrol(); 

    //Condition to change state 
    if (*expresion1*) 
     ToChaseState(); 
    if (*expresion2*) 
     ToFireState(); 
} 

private void Patrol() 
{ 
     //Your Logic for the behvaiour wanted. 
} 

public override void ToChaseState() 
{ 
    controller.currentState = controller.chaseState; 
} 

public override void ToFireState() 
{ 
    controller.currentState = controller.fireState; 
} 

public override void ToIdleState() 
{ 
    Debug.LogWarning("Can't transition to same state"); 
} 
} 

変更をチェックするこの方法は、方法が容易であり、また、あなたが同様の状態の特定の行動をimpletementすることができます。また、新しい状態を追加するのは簡単ですが、インターフェイスに新しいClassメソッドとToNewStateメソッドを実装するだけです。

希望しました。

関連する問題