登壇したのは、ボーカゲームスタジオのプログラマー 松下 達也氏と、同社のテクニカルアーティスト Stephen Oberheim Jr.氏。
セッション前半では、 松下氏よりGameplay Ability Systemの活用事例が解説。同氏は本作にて、プレイヤーキャラクターの制御を中心にゲームプレイに関わるシステムの開発を担当した
次々に操作キャラを“乗り換える”。多彩なアクションの実装を「Gameplay Ability System」で効率化
『野狗子:Slitterhead 』は、架空の街「九龍」を舞台にしたバトルアクションアドベンチャーゲームです。本作の敵キャラクターは、人間に擬態する怪物「野狗子 (やくし)」。プレイヤーは、謎の生命体「憑鬼 (ひょうき)」を操作して街を奔走し、「野狗子」の殲滅に臨みます。
「憑鬼」は物理的な肉体を持たず、現実世界に干渉できないため、人間に憑依して身体の支配権を奪うことで「野狗子」と戦います。憑依対象を変えることでプレイアブルキャラクターの切り替えが可能で、キャラクターごとに異なるアクションが行える点が本作の特徴です 。
「憑鬼」に憑依された人間(画像手前の赤いパーカーを来た人物)と、本作の敵キャラクター「野狗子」(画像右奥)が戦う様子
「憑鬼」が憑依できるプレイアブルキャラクターは、特殊能力を持たない一般人「モブ」と、モブよりも性能が高く固有の能力を備えた「稀少体」の2種類に大別されます。
プレイアブルキャラクター間でとれるアクションの種類は共通ですが、性能やアニメーションが異なります。そのため、同一種類のアクションであっても、キャラクターそれぞれで異なるアクションとして実装 する必要がありました。
アクションを量産するにあたっては、ファイルの競合を避けつつ複数人で作業を行えるのに加え、類似したアクションを効率的に実装できるシステムが求められました。
また、アクション数の増加に伴う「攻撃中は回避できない」「攻撃アクションをダメージリアクションでキャンセルする」といった アクション同士の依存関係の増加 に対しても対策が必要でした。
そこで、プレイヤーアクションの実装には、アンリアルエンジン公式が提供するプラグイン「 Gameplay Ability System 」を採用。
講演では、Gameplay Ability Systemを構成する要素のうち、 「Ability System Component」「Gameplay Ability」「Gameplay Tag」 の3つが取り上げられ解説されました。
Ability System Component アクタとGameplay Ability System間でデータのやり取りを行うためのコンポーネントです。
Gameplay Ability Systemを利用する際は、対象のアクタにAbility System Componentを持たせる必要があります。
Gameplay Ability 特定のアクションやスキルを表す「 アビリティ 」にあたるアセットです。Gameplay Abilityをブループリントで継承して、アクションの実行内容や発動条件を定義します。
1つのGameplay Abilityアセットにつき、1つのアクションを実装・管理する
Gameplay Tag Gameplay Abilityの識別や発動条件の管理などに使用される、階層構造を持つタグシステムです。
階層は「.」によって分けられます。例えば「回避」のGameplay Abilityのタグは「Ability.Action.Dodge」と表記。右に行くにつれて深い階層を表しています。
スライド右側の画像は、Gamelpay Tagの階層の一例。プレイヤーのアクションやスキルに該当するタグ「Ability」の階層下に、Gameplay Abilityを区分する複数のタグを作成。その1つである「Action(移動・戦闘時に使用するアクションが分類)」の下には、アクション・スキルごとに「Dodge(回避)」「Guard(ガード)」といったタグが割り振られている
複数のアクションを階層構造で管理する「Gameplay Tag」の設計
Gameplay TagによってGameplay Abilityを管理するにあたり、本作では「プレイヤー」「敵キャラクター」「モブ」の各セクションでタグの階層を分割することで、作業の競合を防いでいます。3種類のセクションで重複するアクションが少なく、各セクションを実装する担当者が異なることが階層を分けた理由だと語られました。
講演では、3種類の階層のうち「プレイヤー」にあてがわれているタグ「Ability」を例に挙げ、階層の設計を紹介。
「Ability」の下では、Gameplay Abilityの識別や、アクタの状態の識別など用途に応じたタグが分離され、階層で管理されています。それらのうち松下氏は、「 Action 」「 Block 」「 Event 」の3つのタグについて解説しました。
Actionタグ 各Gameplay Abilityは、オプション「Ability Tags」に指定されたタグによって分類されます。本作では、 Ability Tagsに付与するタグを「Action」階層下において管理 しており、これを Actionタグ と呼んでいます。
Actionタグには、攻撃を回避するアクションに付与されるタグ「Dodge」や、攻撃をガードするアクションに付与されるタグ「Guard」などがあります。
また、 オプション「Cancel Abilities With Tag」や「Block Abilities With Tag」でキャンセル・ブロックしたいAbilityを指定する際にもActionタグが用いられます 。 Gameplay Abilityを実行すると、「Cancel Abilities With Tag」に指定されたタグを持つ実行中のGameplay Abilityがキャンセルされるほか、「Block Abilities With Tag」に指定されたタグを持つほかのGameplay Abilityが実行できなくなります。
Blockタグ 前述した「Block Abilities With Tag」に加えて、 実行をブロック(阻害)するGameplay Abilityの識別に「Block」タグが用いられます 。
Gameplay Abilityを実行すると、オプション「 Activation Owned Tags 」に指定されたタグがアクタに付与されます。アクタに付与されたタグがオプション「 Activation Blocked Tags 」に指定されているGameplay Abilityは、実行がブロックされます。
スライド画像右の設定を行った場合、「Ability.Block.Dodge」が「Activation Owned Tags」に指定されているため、このGameplay Abilityを実行中、アクタに「Ability.Block.Dodge」が付与される。そして、「Ability.Block.Dodge」が「Activation Blocked Tags」に指定されているため、このGameplay Abilityは重複して実行できない
前述した「Block Abilities With Tag」によるブロックの設定と比較して、 「Block」タグは特定のタイミングでのみブロックする実装も可能であるほか、管理やデバックを行いやすい と松下氏は述べました。
Eventタグ Gameplay Ability Systemには、特定のGameplay Abilityにイベントを送信する「 Send Gameplay Event 」関数や、対象のアクタで実行している全てのGameplay Abilityにイベントを送信する「 Send Gameplay Event to Actor 」関数が用意されています。
送信するイベントにはタグを紐づけられるほか、Gameplay Ability内の「Wait Gameplay Event」関数を用いると、特定のタグを持つイベントを待ち受けることが可能です。
イベントによるGameplay Ability間の通信には、イベントの識別に専用の「Event」タグが利用されています。
Gameplay Abilityの実行フロー
Gameplay Abilityの実行フローは、アクタやComponentで実行される部分とGameplay Abilityで実行される部分に分けられます。
対象のGameplay Abilityを実行するには、アクタに実行対象のGameplay Abilityを付与する必要があります。
本作では、Gameplay Abilityの付与に2種類の関数を使用。発動頻度の高いGameplay Abilityには「 Give Ability 」関数を採用。
一方、ダメージリアクションなど繰り返し発動しないアクションには、Gameplay Abilityの付与・実行・破棄を一括で行う「 Give Ability And Activate Once 」関数が用いられました。
Gameplay Abilityの付与後、Gameplay Abilityの発動前に「 Try Activate 」関数を実行し、発動条件のチェックを行います。
「Try Activate」関数は、発動条件として参照する対象に応じて複数用意されている
発動条件を満たしていると、正常にGameplay Abilityが発動し、実行処理が行われます。実行処理にあたる「 On Activate Ability 」イベントをオーバーライドし、アニメーションやエフェクトの再生といったアクションに必要な処理を実装します。
Gameplay Abilityの実行が終了あるいは中断された際は、 Gameplay Abilityの終了処理 が実行されます。
Gameplay Abilityが終了する要因は、ブループリントで「 End Ability 」関数が呼び出される場合と、別のGameplay Abilityの発動により実行がキャンセルされる場合の2種類。
Gameplay Abilityの終了処理は、「 On End Ability 」イベントをオーバーライドして実装します。アニメーションの強制終了や終了イベントの送信といった、アクション終了に伴う処理を行います。
クラス継承で380個のGameplay Abilityを量産 Gameplay Abilityを量産するにあたり、攻撃タイプやキャラクターのバリエーションごとにアクションのパラメータ定義を対応させるために、 クラスの継承 を用いました。
近接攻撃アクションを例に挙げると、ジャンプ攻撃・ダッシュ攻撃といった近接攻撃の各タイプに共通するベースとなるロジックを、1つのベースクラスとして実装しました。
ベースとなるロジックの実装には、アニメーション再生や、キャラクターのアニメーションを地形などの環境に応じて調整する機能「Motion Warping」の設定、パラメータの種類の設定といった基本的な処理が集約されている
ベースクラスを継承した子クラスとして、攻撃タイプ別の要素を実装。さらにその子クラスとしてキャラクター別の要素を実装しています。これにより実装を効率化できたと松下氏は語りました。
攻撃タイプ別の実装では、Gameplay AbilityのTagの設定を実施。この段階で、オプション「Ability Tags」「Activation Required Tags」「Activation Blocked Tags」を設定している
キャラクター別の実装では、アニメーションの差し替えとパラメータ調整のみを行う
最終的に作成されたプレイヤーアクションのGameplay Abilityは 総数380個 に上ると松下氏は語りました。
松下氏は、Gameplay Ability Systemのメリットとして、 複数人の作業でも効率的にアクションを実行できる 点や、 汎用性が高く使いやすいシステム である点を評価しました。
一方で、システムが複雑で一定のC++の知識が必要であるため学習コストが高い点を指摘。最初から全機能を完璧に習得しようとせず、手を動かしながら少しずつ使い方を身に着けていくことを推奨すると述べました。
『野狗子: Slitterhead』の開発事例|UNREAL FEST 2024 TOKYO 『野狗子:Slitterhead』Bokeh Game Studio公式サイト