ARPG開発 004 コンボ

通常攻撃のXXXコンボと強攻撃のY攻撃を実装しました。

XXXコンボ(□□□コンボ)を作成する

三人称視点でのアクションゲームにおいて、最も王道的な仕様のコンボ攻撃を作成します。先行入力で次のコンボに繋がるのが確定し、連打しても不自然なモーションにならないXXXコンボ(□□□コンボ)。

Mixamoで攻撃アニメーションを入手

Mixamoで攻撃用のアニメーションを4つ入手しました。
XXXコンボの3つと、強攻撃となる野球のフルスイングアニメーションです。
Mixamo → Mixamo Converter → UE5.2 | 経験値0からのUE5

AnimMontageの作成

Mixamoのアニメーションはリターゲットせずに使えますから、AnimMontageだけの作成で良いです。
4つのアニメーションシーケンスを選択した状態で右クリックして、作成する > AnimMontageを作成。

アニメーション中に移動できないようにするために、各アニメーションシーケンスのルートモーション > EnableRootMotionにチェックを入れておきました。

プラグインの導入

編集 > プラグインで検索欄にGameplay Abilityと入力して探し、Gameplay Abilityにチェックを入れて再起動。

Gameplay Ability ブループリントの作成と編集

親となるGameplay Ability ブループリントを作成します。
GASというフォルダを作成し、GAS内で右クリックしてブループリント > Gameplay Ability ブループリントを選択し、親クラスはGameplay Ability。
名前は名前はGA_ComboBaseにしました。
GA_ComboBaseの編集

左メニューの変数を+して、IsFirstAttack(Boolean)を作成。これはコンボの1発目の攻撃であるかどうかの変数。

ノードを組む
Abilityが発動した時にMontageを再生するノード。

IsFirstAttack(Boolean)をドラッグ&ドロップでGet。
IsFirstAttackから線を伸ばしてブランチを配置。
イベント ActivateAbilityからブランチへ線を繋ぐ。BranchのTrueから線を伸ばしてPlayMontageAndWaitを配置。
Montage to Playから線を引いて「変数に昇格」を選択。
On Completedから線を引いてEnd Abilityを配置。
End AbilityとOn Blend Out、On Interrupted、On Cancelledにも繋ぐ。BranchのFalseから線を伸ばしてWait Gameplay Eventを配置。
Event ReceivedからPlayMontageAndWaitへと線を繋ぐ。
Event Tagの編集から新しいゲームプレイ タグを追加で名前欄に「Attack.Next」と入力。
Only Trigger Once(トリガーは1回のみ)にチェックを入れる。
このノードはボタンを押すとAbilityが発動して呼ばれるノードです。
まずIsFirstAttackであるかどうか確認して、True(1発目の攻撃である)であるならそのままMontageを再生。False(1発目の攻撃ではない)であるならTagのAtk.Nextを付与してからMontageの再生へ。

子ブループリント クラスの作成と編集

GA_ComboBase(Gameplay Ability ブループリント)は親であり、これを継承して子ブループリントを作ります。
GA_ComboBaseで右クリックして「子ブループリント クラスを作成します」を選択。
名前はGA_ComboX1にしました。ゲームパッドのXボタンのコンボの1発目にするからです。

GA_ComboX1の編集
詳細の編集
Gameplay Abilityの子ブループリントは詳細のみ編集します。

まずこの攻撃は1発目ですからIs First Attackにチェックを入れる。
Montage To Playにコンボ攻撃の1発目となるAnimMontageを選択する。
■Tag(タグ)
Gameplay AbilityはTagで管理します。
Ability Tagsは名前です。
タグ > Ability Tags > 編集で「新しいゲームプレイ タグを追加」を選択。名前欄に「Attack.X」と入力して「新しいタグを追加」を選択。
Ability TagsにAttack.Xと表示されます。
Activation Owned Tagsは、このAbilityを実行中に付与されるTagです。Abilityが終了した時点で消えます。この欄にAttack.X.1というTagを追加します。
Activation Blocked Tagsは、このAbilityが発動中に無効化するTagを入れます。
ここにはAttackを指定。Attack.XもAttack.Yも全て無効化されます。つまり、Xボタンを連打しても重複して発動するのを防げます。ここを空欄にしているとXボタンを連打すると何度も発動してしまい、攻撃モーションの最初にリセットされてしまう。
GA_ComboX2の編集

GA_ComboX1を複製して名前をGA_ComboX2にします。

詳細の編集

2発目の攻撃ですからIs First Attackのチェックを外す。
Montage To Playにコンボ攻撃の2発目となるAnimMontageを指定。
■Tag
Ability Tagsは1発目と同じAttack.X
Activation Owned Tagsは、Attack.X.2になります。2発目の2です。
Activation Required Tagsは、このAbility(Attack.X.2)を発動するのに必要となるTagです。新たにAttack.Ready.X2を追加します。このTagは1発目の攻撃中に付与されるようにします。
Activation Blocked Tagsは、Attack.X.2です。
この瞬間、Attack.X.2以外のコンボ攻撃は発動条件外となっているので指定する必要がありません。重複発動する可能性があるのはAttack.X.2のみです。

GA_ComboX2を複製して名前をGA_ComboX3にします
コンボ3発目の作り方はコンボ2発目の応用です。Tagは数字の2が3になるだけ。

プレイヤーブループリントにAbility Systemを追加

BP_Playerの編集

コンポーネントのBP_Player (Self)を選択した状態で+追加を押してAbilitySystemを追加する。

イベントグラフを開く。

ノードを組む
アビリティを登録するシステムを作ります。

イベント BeginPlayから線を繋げますが、既にいくつかの線とノードが繋がっているかと思います。その最後のノードからFor Each Loopを繋げる。
コンポーネントのAbilitySystemをドラッグ&ドロップで配置。
AbilitySystemから線を伸ばしてGive Abilityを配置。
Give AbilityAbility Classから線を伸ばして変数へ昇格。左メニューの変数に出現したAbility Classを選択し、詳細の変数の型の一番右のvをクリックして配列を選択。注意書きが出ますが「変数の型を変更」を選択。

Give AbilityAbility Classのノードの線を切ってから再び線を伸ばしてFor Each LoopのArrayと繋ぐ。線を切る時はAltキーを押しながらクリック。
For Each LoopのLoop Bodyから線を伸ばしてGive Abilityに繋ぐ。
Array Elementから線を伸ばしてGive AbilityAbility Classに繋ぐ。
このノードはGive AbilityでAbilityを登録しています。Gameplay AbilityはGive Abilityに登録しないと実行できません。

コンパイルしましょう。

配列化したAbility Classに作成したアビリティを登録します。
左メニューの変数のAbility Classを選択し、右の詳細のデフォルト値 > Ability Classの+を選択。出現したインデックス[0]のNone欄にGA_ComboX1を指定。
同様にインデックス[1]を追加してGA_ComboX2を指定。インデックス[2]を追加してGA_ComboX3を指定。

ノードを組む
インプットアクションでAbilityを発動させます。

イベントグラフの空いているところにインプットアクションを配置。Stated (Pressed)から線を伸ばしてTry Activate Abilities by Tagを配置。
Gameplay Tag Containerから線を伸ばしてMake Literal Gameplay Tag Containerを配置。
その編集を選択してAttack.Xを指定。
Xボタンを押すと、AbilityのAttack.Xが有効化されるわけです。
Attack.X.1~3まで全て有効化されていますが、Activation Required Tagsで制御されていて2と3は発動しません。つまり1発目の攻撃モーションが発動します。

AnimNotifyStateの作成と編集

AnimNotifyStateフォルダを作成し、右クリックメニューからブループリント クラスを選択。すべてのクラスの検索欄に「AnimNotifyState」と入力してAnimNotifyStateを選択。
名前はANS_ReadyAttackにしました。この通知ステートは次のコンボに繋げられるボタンの入力期間となります。
同じ手順でもう1つAnimNotifyStateを作ります。名前はANS_BranchAttackにしました。こちらは先行入力後、どの地点で次のMontageに切り替えるかの通知ステートになります。

ANS_ReadyAttackの編集

ANS_ReadyAttackを開き、左メニューの関数オーバーライドの欄でReceived Notify Beginを選択。
NotifyStateは始点と終点の2つの点で管理します。Received Notify Beginは始点にあたります。

ノードを組む Received Notify Begin

Received Notify Beginから線を伸ばしてAdd Loose Gameplayを配置。
Received Notify BeginMesh Compから線を伸ばしてGet Ownerを配置。そのReturn ValueActorに繋ぐ。
Add Loose GameplayGameplay Tagsから線を伸ばしてMake Literal Gameplay Tag Containerを配置。そのValueから線を伸ばして変数に昇格。変数の名前はAttackBeginTagにして、目玉アイコンをオープンにする。

Add Loose Gameplayから線を伸ばしてリターンノードと繋ぐ。
このノードは通知ステートの始点でAttackBeginTagを付与しています。
関数オーバーライドでReceived Notify Beginを選択した時と同じように今度はReceived Notify Endを選択する。こちらは終点の設定になります。
ノードを組む Received Notify End

Received Notify Endから線を伸ばしてRemove Loose Gameplay Tagsを配置。
Received Notify EndMesh Compから線を伸ばしてGet Ownerを配置。そのReturn ValueActorに繋ぐ。
Add Loose GameplayのGameplay Tagsから線を伸ばしてMake Literal Gameplay Tag Containerを配置。
変数のAttackBeginTagをドラッグ&ドロップでGet配置してValueに繋げる。
Remove Loose Gameplay Tagsから線を伸ばしてリターンノードと繋ぐ。
このノードはReceived Notify Beginという始点で付与(Add)されたAttackBeginTagをReceived Notify Endという始点で削除(Remove)しています。
ANS_BranchAttackの編集

ANS_BranchAttackを開く。
左メニューの関数オーバーライドの欄でReceived Notify Tickを選択。

ノードを組む Received Notify Tick

Received Notify Tickから線を伸ばしてSend Gameplay Event to Actorを配置。
Received Notify TickMesh Compから線を伸ばしてGet Ownerを配置。そのReturn ValueActorに繋ぐ。
Send Gameplay Event to ActorのEvent TagはAttack.Nextを指定。
Send Gameplay Event to Actorから線を伸ばしてリターンノードと繋ぐ。

AnimMontageにStateを配置

AnimMontageにANS_ReadyAttackを追加します。
通知1の右スペースで右クリックして通知ステートを追加を選択。先ほど作成したANS_ReadyAttackを選択。
ANS_ReadyAttackという通知ステートは、次のコンボに繋げられるボタンの入力期間です。始点を武器の振り始め、終点を武器の振り終わりぐらいに設定します。

追加したANS_ReadyAttackを選択した状態で詳細を見る。Attack Begin TagにAttack.Ready.X2を指定します。
このTagを付与することで、次にコンボ2発目が出せるようになりました。

通知1の▼トラックで左クリックして通知トラックを挿入。通知2が出現します。
通知2の右スペースで右クリックして通知ステートを追加を選択。今度はANS_BranchAttackを選択。
ANS_BranchAttackという通知ステートは、先行入力確定後に次のMontageに切り替わるポイントです。ですから重要なのは始点です。武器の振り終わり、次のアニメーションに切り替わってもいいタイミングに始点を設置しましょう。早めに設置すればテンポよく剣を振りますし、遅ければ振り終わってから待ちがあります。
終点はANS_ReadyAttackより後ろなら良いです。

同じようにコンボ2とコンボ3にも設定します。現時点では、コンボ3の設定は不要ですけどね。コンボ3発目までを設定してテストプレイして、3発目までコンボが出たのを確認。

武器の振りが遅かったので、AnimMontageのアセット詳細 > Animation > Rate Scaleを1.5にしました。
アニメーションの速度は簡単に調節できますから、Mixamoでダウンロード時に設定に悩む必要はありません。

Y攻撃を作成する

Y攻撃は野球のフルスイングにします。

GA_ComboYの作成と編集

GA_ComboX1を複製して名前をGA_ComboY1にします。

GA_ComboY1の編集
詳細の編集
1発目の攻撃ですからIs First Attackのチェックを入れる。
フルスイングのAnimMontageを選択。
Ability TagsAttack.Y
Activation Owned TagsAttack.Y.1
Activation Blocked TagsAttack

AnimMontageにStateを配置

ANS_ReadyAttackとANS_BranchAttackの配置。
Y攻撃の後には続けませんから、Tagの付与は不要です。

プレイヤーブループリントを編集

まず忘れないように配列化したAbility Classに作成したアビリティを登録します。
左メニューのAbility Classを選択し、右の詳細のデフォルト値 > Ability Classの+を選択。出現したインデックス[3]のNone欄にGA_ComboY1を指定。

ノードを組む
ゲームパッドYボタンを押したらAbilityを発動させます。

イベントグラフの空いているところにインプットアクションを配置。
Started (Pressed)から線を伸ばしてTry Activate Abilities by Tagを配置。
Gameplay Tag Containerから線を伸ばしてMake Literal Gameplay Tag Containerを配置。その編集を選択してAttack.Yを指定。

XY、XXY、XXXYコンボ

XY、XXY、XXXYという繋ぎ方もできるようにしておきます。
ComboY1を複製して、名前をComboXYにします。

ComboXYの編集
詳細の編集
2発目以降の攻撃ですからIs First Attackのチェックを外す。
Y1と同じフルスイングのAnimMontageを選択。
■タグ
Ability TagsはAttack.XY。
Activation Owned TagsはAttack.XY。
Activation Required Tagsは、Attack.Ready.XY
Activation Blocked TagsはAttack.XY。
ComboX1~ComboX3の編集

Attack.Ready.XYのTagがないとXYコンボは出せませんから、ComboX1~ComboX3で使用しているAnimMontageのANS_ReadyAttackのTagにAttack.Ready.XYを入れます。
Tagは2つ以上付与できるわけです。

プレイヤーブループリントを編集

忘れがちなAbility Classへの登録をしておきます。

ノードを組む

Attack.Yで作った部分をコピペしてAttack.XYに変更するだけです。
注意点として、Make Literal Gameplay Tag Containerは2つ以上のTagを記入できますが、Attack.YとAttack.XYを1にまとめたら無効になりました。

コンボ中に武器の持ち替え

通常攻撃は右手に武器を持って行います。しかし、Y攻撃は野球のフルスイングであり、フォロースルーは左手にバットを持っている必要があります。そこで、Y攻撃の時だけ左手に武器をアタッチするステートを作りました。

まずスケルトンツリーのmiddle_01_lにgrippoint_r_batとgrippoint_l_axeを作成します。

ANS_ReadyAttackを複製して、名前をANS_GripChangeにしました。

ノードを組む Received_NotifyBegin

Attach Component To ComponentSocket Nameはローカル変数にしています。
ノードを組む Received_NotifyEnd

Attach Component To ComponentSocket Nameはローカル変数にしています。

このステートの始点で左手にアタッチさせ、終点で右手に戻しています。
これをY攻撃のAnimMontageの最初に始点、最後に終点を置けば良いです。

スイングに音を入れる

武器を振った時の音を入れます。これもAnimMontageで簡単です。
Unreal Engineの音はWAV形式のみ対応です。音の無料配布サイトはMP3形式が多いですから、変換サイト等でWAV形式に変換する必要があります

無料効果音で遊ぼう!様の打撃・攻撃から、素振り1~3をダウンロードしてWAV形式に変換しました。
WAV形式ならコンテンツブラウザにドラッグ&ドロップでインポートできます。

AnimMontageを開き、通知トラックを増やす。
右クリックして通知を追加 > Play Sound。

詳細のSoundで音を選択する。
Volume Multiplierでボリュームを変更できます。値が大きいと音も大きい。
Pitch Multiplierで音の速さを変更できます。値が大きいと音が速い。
Followにチェックを入れてAttach Nameにボーン名を入れると、その場所に音がついていきます。

これで攻撃モーションは完成。

 

 

コメント

タイトルとURLをコピーしました