皆様いかがお過ごしでしょうか。歌乃です。
最近UEを弄り回してます。下手なゲームより面白い。
いろいろと実装して試行錯誤しているうちにBPがスパゲッティ状態にorz
コード書いても書かなくてもこれってどーなんだ。
前回以降に実装してみたものを列挙
一つの機能を実現しようとすると色々な要素が必要になって、気づいたらあれもこれも・・・な状態。
以下のような読者を対象にしてます。
前回の記事 > UE5 でアニメーションアセットの作成 。
全部書くと膨大な量になりそうなので一つずつ。
Gameplay Abilities System ですが、ざっくり言えばゲーム内で使用される「スキル」や「状態異常」などを管理することを目的に用意されている機能です。
ただし、私の理解が浅いせいで、いまいち利便性がわかりません( ゚д゚)
比較的簡単に排他処理ができるので、例えばA、B、CというスキルがあったとしてAの次にB、その次にCが来れば技を出し、それ以外なら通常の攻撃、といったコンボ技などの制御ができたりします。
現状では必要なさそうかなとも思いましたが、とりあえず、ダッシュをGameplay Abilitiesで実装して見ることにしました。
Gameplay Abilitiesは公式プラグインですが、デフォルトで有効になっていないので、有効にしてUEを再起動します。
新規作成でブループリントからGameplay Abilitiesブループリントを選びます。
親クラスとして「Gameplay Abilities」を選択します。
名前はわかりやすく「GA_Sprint」にしました。
新規作成したGameplay Abilitiesブループリントを開いて、クラスの詳細を編集します。
Gameplay Abilitiesはゲームプレイタグという文字列で制御するため、まずはそれを登録しなければいけません。
タグ欄にあるドロップダウンリストを開くと「ゲームプレイタグを管理」という項目があるのでそれをポチります。
ゲームプレイタグマネージャーが表示されるので、タグを追加していきます。
タグは階層構造が可能で、入力時に階層構造を表すためにはカンマで区切って入力します。
最上位のカテゴリを「Ability」その下に「Action」その下に「Sprint」というタグを作るのであれば
「Ability.Action.Sprint」といった感じで入力します。
イベントグラフ内で目的のGameplay Abilitiesを呼び出すときにはこのタグを使用します。
タグを追加して階層構造ができたあとにタグを追加する場合は追加したいタグの親になるタグを選んで右クリックして「サブタグを追加」を選べば、親タグまでの階層構造が入力欄に追加されるので、少し楽ができます。
Sprintタグを選んで、その下にCancelタグを追加します(実際の入力値は「Ability.Action.Sprint.Cancel」になると思います)
だいたい察しはつくと思いますが「Sprint」タグでダッシュ機能を呼んだ後「Sprint.Cancel」タグを使ってダッシュの終了処理を呼ぶ、という流れです。
ゲームプレイタグが設定できたら先ほどのタグ設定欄に戻ってタグを設定します。
必須なのは「Ability Tags」です。ここに指定がないとAbilityを呼び出せません。
「Ability Tags」に新規追加したSprintタグを設定します。
タグの一覧からSprintをチェックすれば自動的に親の階層「Action」その親の「Ability」にもチェックが入ります。
タグは複数指定することも出来ます。
次に指定するのは「Activation Owned Tags」です。Ability 発動中はここに指定したタグを保持した状態になります。
その他に
「Cancel Abilities with Tag」ここに指定したタグが発動中であればキャンセルさせます。
「Block Abilities with Tag」ここに指定したタグの発動をブロックさせます。
自身をキャンセル、ブロックするのではなく、指定したタグの発動に関して作用するので注意してください。
以上のタグで排他処理を実現できます。
例えば、AというAbilityを出している間はBというAbilityをだせない、とか、AというAbilityの最中にCというAbilityを使うとAがキャンセルされる、などです。
今回はしゃがみ状態のAbility(未実装だけど)として「Ability.Action.Crouch」も追加してSprintと排他になるようにしてみました(未実装だけど)。
ちなみに
「Activation Required Tags」ここに指定したタグはAbility発動の前提条件となります。ここの指定したタグが発動中でなければAbilityが発動しません。
「Activation Blocked Tags」ここに指定したタグはAbility未発動の前提条件となります。ここの指定したタグが発動中であればAbilityが発動しません。
これらを使うとAというAbilityの発動中であればBというAbilityが発動可能で、Bの発動中であればCが発動できる、といったコンボ技が実現できます(たぶん)。
次に作成した Ability をプレイヤーキャラクターで使用できるように準備します。
プレイヤー用のキャラクターBPを編集します(サンプルプロジェクトであればBP_ThirdPersonCharacter)。
コンポーネントの追加から「AbilitySystem」を選択して追加します。
追加するAbilityを列挙するための変数(Gameplay Ability クラス参照型)を追加します。ここでは「AbilityClass」としました。追加した変数の詳細で変数の型を配列に変更します。
ダッシュ状態、しゃがみ状態を判定するための変数(Boolean型)を追加します。ここでは「isSprint」「isCrouch」としました。
一旦キャラクターBPをコンパイルして、追加した「AbilityClass」に初期値を設定します。
新規に作成したAbility classを初期値として列挙しておきます。
次に作成した Ability の使用権限をプレイヤーキャラクターに付与する処理を追加します。
キャラクターBPのイベントグラフで「Event BeginPlay」処理の最後にAbilityの付与処理を追加します。
スパゲッティ化を緩和するために処理をサブ関数にまとめてあります。
関数の中身はこんな感じ。
Gameplay Ability Systemの「Give Ability」関数を使って「AbilitySystem」コンポーネントにAbilityClassの使用許可を与えていきます。
前述したAbilityClass変数に列挙した内容(自作したAbility)をForEachで回して処理します。
これでAbilitySystemコンポーネント(を持ってるプレイヤーキャラクタ)にAbilityの使用許可が与えられます。
Give Abilityの説明を読む限り、ネットワーク上での使用を想定している模様です。処理次第でホストやゲストといったプレイヤーごとに権限を変えるといったことができるのかもしれません。
Ability の発動処理を追加します。
発動のトリガーとなるイベントは今回は「Shiftキーの押下」です。
事前に Input Action と Input Mapping Context の設定をしておきます。
Ability の発動(有効化)にはいくつかの方法がありますが、ここではClassを使って有効化しています。TargetはキャラクタBPに追加したAbilitySystemComponentです。
Try Activate Ability 関数は、指定されたAbilityが発動(有効化)可能かどうか評価します。
ここで設定されているAbilityTagsや排他タグによって、発動の可否が評価されていると思われます。
終了のトリガー(ここではShiftキーの解放)が発生したら、Send Gameplay Event to Actor 関数を使ってメッセージ(任意のゲームプレイタグ、ここでは「Ability.Action.Sprint.Cancel」)を投げます。ターゲットはActor(ここではキャラクタBP=Self)
トリガーによって該当Abilityが有効化できたら(Abilityの中身がなくてもTry Activate Ability 関数でTrueが返ってくれば有効化出来ています)Ability側のイベントを作っていきます。
概要はこんな感じ。
なにやってるか自分でもわかりません( ゚д゚)
まあこのあたりは実装する機能によって変わってくるのであまり気にしなくていいと思います。
ともかくAbilityが有効化されると「Event ActivateAbility」イベントが発生します。
そこから処理を繋げて、Abilityの発動条件などをチェックします。今回のSprintであれば、キャラクタの状態が空中(isFalling)であればダッシュは出来ない(させない)ので空中状態であれば「End Ability」関数を呼んで処理を抜けます。
その他今回は本筋ではないので解説してませんが実装したスタミナの値をチェックして0であれば発動を出来ないようにしています。発動中はSet Timer by Event で経過時間ごとにスタミナを減らし0であれば発動終了(処理を抜ける)としています。
Ability側のイベントで重要なのは「Wait Gameplay Event」処理で、ここで任意のゲームプレイタグを指定することで、外部から投げられてくるメッセージ(ゲームプレイタグ)に対応する処理を走らせることが出来ます。
メッセージを投げてくるのは Input イベントの Shift キーの解放だけなので、ここでは単純に「Ability.Action.Sprint.Cancel」メッセージを受けたら「End Ability」関数を呼んで処理を抜けるようにしておきます。
Sprint 発動後にCharacterMovementの「Max Walk Speed」を500に設定してダッシュを表現しています。
「Event OnEndAbility」イベントが発生したら終了処理(フラグの設定や「Max Walk Speed」を戻す処理)をおこなって処理を抜けます。
これでAbilitySystemによるSprintスキルの実装(ダッシュのスキル化)が出来ます。
同じようにCrouch(しゃがみ)もスキル化したのですが、単純にキーのON・OFF処理でもいいので、AbilitySystemを使うメリットが感じられない(´・ω・`)
続きっぽいもの > User Interface の実装