こんにちは、この記事では、Unreal Engine 4で開発し、アクターコンポーネントなどの有用なクラスを使用するアプローチについて、読者に私の見解を共有したいと思います。
アンリアルエンジン4のさまざまなチュートリアルでは、深く複雑なクラス継承階層を使用することが多いことに気付きました。 Unreal Engine 4エンジンは、アクターコンポーネントに基づいたコンポーネントアプローチの使用を推奨していますが。
読者が、アクター、アクターコンポーネント、およびブループリントのビジュアルスクリプトシステムについて詳しくない場合は、まず次の資料に精通することをお勧めします。
アンリアルエンジン4 /ゲームプレイプログラミング/ロシア語の
アクターまたはマテリアル
UE4パート2のC ++開発入門 (ゲームプレイクラス:オブジェクト、アクター、コンポーネントのセクション)
アンリアルエンジンチュートリアル。 パート2:ブループリント問題
例として、シューターの武器のようなものを考えてください。 BaseGunクラスのActorを作成し、このクラスに武器の射撃、射撃時の散布、射撃効果の作成、発射物(弾丸)のインスタンス化などのロジックを実装することは一般的な慣行です。自動機。 後に、BaseGunからの継承により新しいタイプの武器が実装されます。
しかし、ショットガンまたはスナイパーライフルをゲームに追加する必要がある場合はどうでしょうか?
多くの場合、この場合、新しいタイプの武器用に子孫クラスが作成されます。 スナイパーライフルの場合、子孫クラスはスナイパースコープをオン/オフし、スコープを介して撮影する際の広がりを減らすための追加のロジックを実装します。 ショットガンの場合、シューティングのロジックを書き換える(オーバーライドする)必要があります。 結局のところ、ショットガンは弾丸を撃ちません-ショットを撃ちます。
新しいタイプの武器がゲームに追加されると、開発者は次の一連のアクションを実行することがわかります。
- 既存の武器の1つまたはBaseGunから子孫クラスを作成します。
- 親クラスのロジックのオーバーライドまたは拡張。
これが問題が発生する場所です。 クラス階層が深いほど、プログラマがコードを実行するためのロジックがどのように機能するかを把握するのに時間がかかります。 このアプローチでは、親クラス(BaseGunまで)を常に変更する必要があります。 その理由は、基本クラスを設計する時点で、開発者はゲームの最終バージョンにどの種類の武器が現れるかをほぼ確実に計算できないからです。
別の方法があります。 ショットガンとスナイパーライフルのロジックをBaseGunクラスに追加します。 しかし、時間が経つにつれて、「多すぎる」ことを行い、「分割して征服する」という原則に違反する大胆なクラス(神オブジェクト)が得られます。 そのようなクラスを作成することは悪質な開発戦略です。解決策
また、武器のロジックをコンポーネントに転送するとどうなりますか? まず、プレイヤーが武器で実行できるアクションのリストを決定しましょう。 これらのアクションはすべてEnum E_WeaponActionTypeに追加されます。

武器を作成するには、BP_BaseWeaponとBP_Weapon_Actionの2つのクラスが必要です。
BP_BaseWeapon
BP_BaseWeaponはアクターであり、すべての種類の武器に対して、基底クラスおよび基本クラスになります。 BP_BaseWeaponでは、E_WeaponActionTypeの各アクションにCustomActionを追加します。 これらのアクションは、プレーヤーと武器の間のインターフェースになります。 また、BP_BaseWeaponには、BP_Weapon_Action型のオブジェクトのコレクションが含まれます。

BP_Weapon_Action
BP_Weapon_ActionはActorComponentです。このクラスの子孫は武器の動作を実装します。ショット、リロード、狙撃スコープの有効化/無効化などです。各BP_Weapon_Actionには、武器へのリンクと特定のBP_Weapon_Actionが実行するアクションのタイプが含まれます BP_Weapon_Actionには、BP_BaseWeaponから操作するための一連のパブリック関数(StartUseAction、StopUseAction、IsCanUseAction)、およびいくつかの保護された関数とプロパティも含まれています。
BP_BaseWeaponとBP_Weapon_Actionを抽象クラスとしてマークし、誤ってインスタンス化しないようにします。 しかし、彼らの子孫に対してはこれを行いません。
そして今、アンダーバレルグレネードランチャーと照準器を備えたアサルトライフルはどのように見えるでしょう。 これはBP_BaseWeaponクラスの子孫になり、3つのコンポーネントを配置する必要があります。
- BP_Fire_Action-弾薬を発射する動作を実装し、E_WeaponActionTypeからMain型を持ちます。
- BP_Scope_Action-スナイパースコープの表示の有効化/無効化を実装します。タイプはE_WeaponActionTypeのセカンダリです。
- BP_Scope_Action-アンダーバレルグレネードランチャーからの発砲を実装し、E_WeaponActionTypeの特別なタイプを持ちます。
BP_BaseWeaponでイベントが呼び出されると、対応する動作が検索され、StartUseActionが呼び出されます。 たとえば、UseWeaponAction_Mainを呼び出すと、BP_Fire_Actionが見つかり、武器が発砲します。

このアプローチの利点は、新しいタイプの武器が新しい動作を必要とする場合、BaseGunまたは他の親クラスを書き換えたり、ロジックでオーバーライドしたりしないことです。 BP_BaseWeaponの子孫を作成し、新しいタイプの武器の動作を実装するコンポーネントを追加および構成するだけです。 既製のブロックから新しいクラスを収集していることがわかります。 動作がない場合は、BP_Weapon_Actionに基づいて新しいコンポーネントを追加するだけです。
説明されているキャンペーンの使用は、さまざまな種類の武器の作成に限定されません。 他のゲームサブシステムに拡張できます。
- さまざまなゲームモード用のゲームモード。
- キャラクターのゲーム能力;
- さまざまなMobの作成。
- さまざまなインタラクティブゲームオブジェクトの作成など。