私は、私が意味するものの例として、私のコードで何かの事例研究を使用します。.NETのインターフェイス継承/階層 - より良い方法がありますか?
今、コンポーネントベースのゲームシステムの動作/アクションシステムに取り組んでいます。ゲームオブジェクトにのみ関連する詳細情報を示し、IBehaviorComponent及びそれらに添付IActionComponentを持つことができ、以下の公開:
public interface IBehaviorComponent : IBaseComponent
{
IBehavior Behavior { get; }
}
public interface IActionComponent : IBaseComponent
{
IAction Action { get; }
void ExecuteAction(IGameObject target = null);
}
は今、これはこれまでのところ、すべての罰金です(少なくとも私には!)。しかし、IActionComponentの実装を見ると、問題が発生し始めます。例えば
、シンプルIActionComponent実装:
public class SimpleActionComponent : IActionComponent
{
public IAction Action { get; protected set; }
public void ExecuteAction(IGameObject target = null)
{
Action.Execute(target);
}
public void Update(float deltaTime) { } //from IBaseComponent
}
しかし、のは、私はアクションは、時限スケジュール通りに実行されるようにすることができます、より複雑なIActionComponentの実装を紹介したいとしましょう:
public class TimedActionComponent : IActionComponent
{
public IAction Action { get; protected set; }
public float IdleTime { get; set; }
public float IdleTimeRemaining { get; protected set; }
public void ExecuteAction(IGameObject target = null)
{
IdleTimeRemaining = IdleTime;
}
public void Update(float deltaTime)
{
if (IdleTimeRemaining > 0f)
{
IdleTimeRemaining -= deltaTime;
}
else
{
Action.Execute(target);
}
}
}
今、IdleTimeを外部の影響によって変更できるように公開したいとします。
public interface ITimedActionComponent : IActionComponent
{
float IdleTime { get; set; }
float IdleTimeRemaining { get; set; }
}
しかし、ここでの問題は私のコンポーネントシステムはIBaseComponentから1レベルアップ時にすべてを保存することです:最初に私の考えは、新しいインターフェイスを作成していました。そのため、GameObjectのアクションコンポーネントは、ITimedActionComponent、IRandomizedActionComponent、ICrashTheProgramActionComponentなど、IActionComponentとして取得されます。基本的なタイプのコンポーネント(IActionComponent、IRenderableComponent、IPhysicsComponentなど)を超えて、必要なものを正確に知らなくても、そのコンポーネントの1つに対してGameObjectを照会することができるようにするために、理由は明らかです。
これを処理するよりクリーンな方法があります。これにより、取得したIActionComponentを興味のあるタイプにキャストすることなく、子クラスで定義されたこれらのプロパティを公開することができます。それとも、これを達成するための唯一の/最良の方法です。ような何か:
public void IWantYouToAttackSuperSlow(IGameObject target)
{
//Let's get the action component for the gameobject and test if it's an ITimedActionComponent...
ITimedActionComponent actionComponent = target.GetComponent<IActionComponent>() as ITimedActionComponent;
if (actionComponent != null) //We're okay!
{
actionComponent.IdleTime = int.MaxValue; //Mwhaha
}
}
は、今私はそれが唯一の方法だ考えていますが、私は無知だ木工品の中に隠れたパターンがあります場合、私は見たい、または誰でも提案することができた場合に考え出しこれを始めるにはもっと良い方法です。
ありがとうございます!
私の他の思想は、これでしょう、IActionComponentExecutorとして、内部に別のオブジェクトを使用していましたAction.Execute()を呼び出すタイミングを決定しますが、私は丸いa-boutの方法で正方形に戻ってきます - 外部オブジェクトはIActionComponentTimedExecutorを追跡する必要があります(ああ〜私たちは今エンターテイメントを取得しています!)IdleTimeを変更します。 – Terminal8
興味のある - 何らかの一般的なバッグに格納されているactionComponent.IdleTimeの状態ですか?もしそうなら、基本インターフェースに 'Apply(BagData bag)'と 'Store(BagData bag)'メソッドを持たせることができます。つまり、派生型を知る必要があるときにプロパティを照会するために使用できるメタデータ型システムを検討する必要があるかもしれません。 'TypeDescriptor'は、プロパティグリッドなどのようなものによって使用される既定の開始点です。 –
いいえ、現在はありません。私は概念に完全に精通していません - おそらくあなたが提供できる参考資料はありますか? – Terminal8