RTSゲームユニットの構造


18

moveToやAttackアクションなどを複数回プログラムすることなく、多くの異なるユニットを作成する方法が欲しい

私の見方では、これを行うには2つの方法があります。

  1. できること/できないことを指定するフラグを持つ単一の汎用ユニットクラス(その後、静的配列でインスタンスを作成し、必要に応じてそれらを取得します)
  2. (Attack、Harvest、Patrol)のようなユニット固有のアクションの抽象メソッドを持つ抽象ユニットクラス。これらは、ユニットが実際に何も取得できない場合でも、すべてサブクラスで実装する必要があります。

これを行う最初の方法は最も簡単に思えますが、ほとんどのユニットで多くのコードが使用されないことになります。

2番目の方法も機能します。しかし、リソースを収穫できる2つの異なるユニットを使用することにした場合、2つの異なるクラスにまったく同じコードを使用することになります。これは正しい方法とは思えません。

これはこの問題への正しいアプローチですか?
AoEのようなゲームでは、すべてのユニットが、私が推測するもの、アクション/注文のリストのようなものを持っています。次に、そのアクションを必要とするすべてのユニットにそれを与えます。

はっきりしない(もっともらしい)場合、または探しているものに関する詳細情報が必要な場合は、コメントでお尋ねください。

回答:


25

一般的なアプローチは、ベースクラスの「ユニット」がすべてのユニットに共通する最も基本的な側面を実装するだけのコンポーネントベースのアプローチであり、各ユニットには実行できることを示す複数のコンポーネントオブジェクトのリストがあり、それがどうするか。

例えば、タンクは、コンポーネントかもしれないMobileDestructibleAttackerだけで、不動のタレットDestructibleAttackerおよび収穫をMobileDestructibleHarvester。これらのクラスには、これらの動作を実装するために必要なすべてのコードが含まれます。コンポーネント間の相互作用は、(Attackerのみが何であるか損傷する可能性がDestructible)他のユニットが、直接そのコンポーネントと相互作用し、必要な成分を有し、かつ場合、コンポーネントのチェックを有することによって実現することができます。

従来のクラス継承に対する利点は、能力を簡単に組み合わせることができることです。たとえば、歩兵の攻撃、輸送、飛行も可能なハーベスターが必要な場合は、必要なコンポーネントを追加するだけです。また、基本的なUnitクラスを肥大化させることなく、新しいコンポーネントの形で新しい機能を簡単に追加および削除できます。

エンジン全体がすでにコンポーネントベースであるため、Unityはそのようなアーキテクチャであなたをサポートします。したがって、これらのようなゲーム論理コンポーネントは、スクリプトの形式で追加できます。


それで、団結して、必要に応じてコンポーネントを無効にして有効にしますか?
ダニエルホルスト

@DanielHolstいいえ、必要に応じて追加および削除します。あなたはユニティエディタまたは使用のscripsであることを行うことができますgameObject.AddComponentし、gameObject.RemoveComponent
フィリップ

ああ大丈夫ですが、「moveTo」アクション/オーダーについて言います。ユニットは、注文がいつ行われたかをどのように知るのですか?
ダニエルホルスト

2
@DanielHolst私はあなたが何かを誤解したと思います。Movingコンポーネント手段は、「このユニットは、移動の一般可能です」。コンポーネントは、ユニットが動いているかどうかに関係なく、恒久的に取り付けられます。動いているという意味ではありません。ただし、コンポーネントを追加し、注文が履行またはキャンセルされたときにそのコンポーネントをユニットから削除することで、この方法で行うことできますMoveOrder
フィリップ

1
@DanielHolstこれで、他のすべてのワームの缶であるユニットAIの方向にドリフトしています。考えられるアプローチは、特定のコンポーネントが存在することを前提とするAIScriptコンポーネントのライブラリを用意するか、ユニットのコンポーネントに応じて動作を変更することです。しかし、それは本当にコメントで扱うにはあまりにも複雑なトピックです。
フィリップ

4

多くのゲームでは、エンティティにコンポーネントベースのシステムを使用します。このシステムでは、エンティティのクラス(または同等のもの)の一部としてコーディングするのではなく、より一般的なユニットタイプに多数の動作と能力を追加できます。


これを実装するのは非常に難しいでしょうか?
ダニエルホルスト

このようなパターンは、実装を全体的に簡単にするために使用されます。どのアプローチを取るべきか判断できない場合は、できるだけシンプルに始めて、より多くの機能を使用するにつれて選択肢を広げることをお勧めします。問題に対する感触が得られたら、状況に合ったアプローチにリファクタリングまたは書き直すことができます。
ロステイラーターナー

1
@DanielHolstあなたの質問にはUnity旗があることに気づきました。Unityは既に組み込みのコンポーネントシステムを備えており、継承よりも合成を強く支持しています。簡単な方法の1つMonoBehaviourは、アクションタイプごとにを作成し、実行可能なアクションを各ユニットタイププレハブにアタッチすることです(損傷値やコストなどのタイプごとの詳細でアクションインスタンスをカスタマイズします)。これにより、ユニット作成がデータ駆動型に維持されるため、多くのカスタムユニットタイプを簡単に作成できます。
DMGregory

@DanielHolstそれは「非常に難しい」というあなたの定義に依存します。私の答えは、これをどのように実装できるかについて詳しく説明します。
フィリップ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.