XXXコンボやXYYコンボの作り方です。
Unreal Engineのバージョンは5.2.1です。
説明の仕方は、まず画像で「こういう形になります」というのを見せて、その下に説明を書いていきます。
XXXコンボ(□□□コンボ)を作成する
三人称視点でのアクションゲームにおいて、最も王道的な仕様のコンボ攻撃を作成します。先行入力で次のコンボに繋がるのが確定し、連打しても不自然なモーションにならないXXXコンボ(□□□コンボ)。
プロジェクトの作成
ゲーム > サードパーソンでプロジェクトを作成します。
マーケットプレイスで攻撃アニメーションを入手
今回はマーケットプレイスにある無料のFrank Action RPG Sword 1 (Basic Set)をプロジェクトに導入しました。
攻撃アニメーションの準備
Frank Action RPG Sword 1 (Basic Set)のアニメーションはMannequin_UE4用ですので、これをUE5のSKM_Quinnにリターゲットします。
コンテンツ > Frank_RPG_Sword1 > Animationsにある47_Frank_ActionRPG_Sword_Combo_A1、48_Frank_ActionRPG_Sword_Combo_A2、49_Frank_ActionRPG_Sword_Combo_A3を3つとも選択した状態で右クリックしてアニメーションアセットのリターゲティング > アニメーション アセット / ブループリントを複製してリターゲティングを選択。
PCの基本操作ではありますが、複数選択する時はCtrlキーを押したまま選択していきます。Shiftキーを押したままだと、最初に選択したところから最後に選択したところまでを全部選択します。
IK リターゲッタの設定
IK リターゲッタにRTG_UE4Manny_UE5Mannyを指定。これはUE4マネキンからUE5マネキンへのIK リターゲッタです。
ターゲット スケルタル メッシュはアニメーションを使わせたいスケルタル メッシュを指定します。ここではUE5マネキンであるSKM_Quinnを指定。
新規アセットの名前変更は空欄でも良いですが、入力した方がわかりやすくなります。
プレフィックスは頭に加える文字列。例えば「ComboX_」と入力すれば、ComboX_47_Frank_ActionRPG_Sword_Combo_A1という名前になります。
サフィックスはお尻に加える文字列。例えば「_UE5」と入力すれば47_Frank_ActionRPG_Sword_Combo_A1_UE5という名前になります。
今回はサフィックスの「_UE5」のみ入力しました。
フォルダはわかりやすい場所を指定しましょう。
今回は/Game/Characters/Mannequins/Animationsを指定しました。
リターゲットを押す。
アニメーションシーケンスのままではコンボに使えません。AnimMontageを作成する必要があります。
リターゲットされた47_Frank_ActionRPG_Sword_Combo_A1_UE5、48_Frank_ActionRPG_Sword_Combo_A2_UE5、49_Frank_ActionRPG_Sword_Combo_A3_UE5を3つとも選択した状態で右クリックして、作成する > AnimMontageを作成。
AnimMontageにも自動反映されます。
プラグインの導入
Gameplay Ability ブループリントの作成
親となるGameplay Ability ブループリントを作成します。
フォルダは自分の管理しやすいように作成してください。
ここではコンテンツ > Blueprints > GASとしました。
GAS内で右クリックしてブループリント > Gameplay Ability ブループリントを選択し、親クラスはGameplay Ability。
名前はGA_ComboBaseにします。
GA_ComboBase(Gameplay Ability ブループリント・親)の編集
Abilityが発動した時にMontageを再生します。
IsFirstAttack(Boolean)をドラッグ&ドロップでGet配置。
IsFirstAttackから線を伸ばしてBranchを配置。
イベントActivateAbilityからBranchへ線を繋ぐ。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の編集から新しいゲームプレイ タグを追加で名前欄に「Atk.X.Next」と入力。※コンボYを追加する事を考えたらAtk.Nextでも良いです。
Only Trigger Once(トリガーは1回のみ)にチェックを入れる。
まずIsFirstAttackであるかどうか確認して、True(1発目の攻撃である)であるならそのままMontageを再生。False(1発目の攻撃ではない)であるならTagのAtk.X.Next(Atk.Next)を付与してからMontageの再生へ。
子ブループリント クラスを作成
GA_ComboBase(Gameplay Ability ブループリント)は親であり、これを継承して子ブループリントを作ります。
GA_ComboBase(Gameplay Ability ブループリント)で右クリックして「子ブループリント クラスを作成します」を選択。
名前はGA_ComboX1にしました。ゲームパッドのXボタンのコンボにするからです。
GA_ComboX1(Gameplay Ability ブループリント・子)の編集
Gameplay Abilityの子ブループリントは詳細欄のみ編集します。
まずMontage To Playにコンボ攻撃の1発目となる47_Frank_ActionRPG_Sword_Combo_A1_UE5_Montageを指定。
Is First Attackにチェックを入れる。これは1発目の攻撃ですから。
Gameplay AbilityはTag(タグ)で管理します。
Ability Tagsは名前です。
タグ > Ability Tags > 編集で「新しいゲームプレイ タグを追加」を選択。名前欄に「Atk.X」と入力して「新しいタグを追加」を選択。
Ability TagsにAtk.Xと表示されます。
名前は好きに決めて良いです。これはAttackのXボタンという意味でこうしています。
Activation Owned Tagsは、このAbilityを実行中に付与されるTagです。Abilityが終了した時点で消えます。この欄にAtk.X.1というTagを追加します。
Activation Blocked Tagsは、このAbility(Atk.X.1)が発動中に無効化するTagを入れます。
ここにはAtk.Xを指定。Atk.Xと入力すればAtk.X.1もAtk.X.2も全て無効化されます。
つまり、Xボタンを連打しても重複して発動するのを防げます。ここを空欄にしているとXボタンを連打すると何度も発動してしまい、攻撃モーションの最初にリセットされてしまう。
※コンボYを追加する事を考えたら、ここはAtkのみでも良いです。AtkならAtk.XもAtk.Yもブロックします。
GA_ComboX2(Gameplay Ability ブループリント・子)の編集
GA_ComboX1を複製して名前をGA_ComboX2にします。
Montage To Playにコンボ攻撃の2発目となる48_Frank_ActionRPG_Sword_Combo_A2_UE5_UE5_Montageを指定。
2発目の攻撃ですからIs First Attackのチェックを外す。
Ability Tagsは1発目と同じAtk.X。
Activation Owned Tagsは、Atk.X.2になります。2発目の2です。
Activation Required Tagsは、このAbility(Atk.X.2)を発動するのに必要となるTagです。新たにAtk.Ready.X2を追加します。
Activation Blocked Tagsは、Atk.X.2です。
この瞬間、Atk.X.2以外のコンボ攻撃は発動条件外となっているので指定する必要がありません。重複発動する可能性があるのはAtk.X.2のみです。
コンボ3発目以降の作り方は、コンボ2発目の応用です。
GA_ComboX2を複製して名前をGA_ComboX3にします。
Ability Tagsは2発目と同じAtk.X。Activation Owned TagsをAtk.X.3、Activation Required TagsをAtk.Ready.X3、Activation Blocked TagsをAtk.X.3です。
プレイヤーキャラクターのブループリントを編集
プレイヤーキャラクターのブループリントは自分が使っているものを使ってください。
今回はThirdPerson > Blueprints > BP_ThirdPersonCharacterをコピーしてBP_Playerという名前に変更して使いました。
コンテンツ > Characters > Player内に入れています。
Levelのワールドセッティング > Game Mode > 選択したゲームモード > Default Pawn Classに自分のプレイヤーキャラクターのブループリントを指定しておくのも忘れないように。
BP_Playerの編集
イベントグラフを開いてください。
アビリティを登録するシステムを作ります。
イベント BeginPlayから線を繋げますが、既にいくつかの線とノードが繋がっているかと思います。その最後のノードからFor Each Loopを繋げる。
コンポーネントのAbilitySystemをドラッグ&ドロップで配置。
AbilitySystemから線を伸ばしてGive Abilityを配置。
Ability Classを変数へ昇格→変数の型を変更
Ability Classから線を伸ばして「変数へ昇格」。左メニューに出現したAbility Classを選択し、右の詳細の変数の型の一番右のvをクリックして配列を選択。注意書きが出ますが「変数の型を変更」を選択。
Give AbilityのAbility Classのノードの線を切ってから再び線を伸ばしてFor Each LoopのArray Elementと繋ぐ。線を切る時はAltキーを押しながらクリック。
For Each Loopの Bodyから線を伸ばしてGive Abilityに繋ぐ。
Array Elementから線を伸ばしてGive AbilityのAbility Classに繋ぐ。
コンパイルしましょう。
配列化したAbility Classに作成したアビリティを登録します。
左メニューのAbility Classを選択し、右の詳細のデフォルト値 > Ability Classの+を選択。出現したインデックス[0]のNone欄にGA_ComboX1を指定。
同様にインデックス[1]を追加してGA_ComboX2を指定。
3発目を作っている場合はGA_ComboX3も追加します。
今後もGameplay Ability ブループリントを作成したら、ここに追加する必要があります。
これは忘れがちです。「ノードもMontageも完璧にやったのになんでAbilityが発動しないの?」となった時、登録忘れしていないか確認しましょう。
ゲームパッドXボタンを押したらAbilityを発動させます。
イベントグラフの空いているところにゲームパッドXボタンを配置。これは各自好きなキーを割り当てて構いません。
ゲームパッドXボタンのPressedから線を伸ばしてTry Activate Abilities by Tagを配置。
Gameplay Tag Containerから線を伸ばしてMake Literal Gameplay Tag Containerを配置。
その編集を選択してAtk.Xを指定。
Atk.X.1~3まで全て有効化されていますが、Activation Required Tagsで制御されていて2と3は発動しません。つまり1発目の攻撃モーションが発動します。
この時点でテストプレイすると1発目の攻撃しか出ません。AnimMontageに通知ステートを登録していないからです。AbilityはTagで管理しているわけですが、そのTagが攻撃アニメーション中のどの時点で通知されるかを設定する必用があります。
AnimNotifyStateの作成
自分の管理しやすい場所にAnimNotifyStateフォルダを作ります。
私はコンテンツ > Character > Mannequins > Animations > AnimNotifyStateというフォルダを作成しました。
2つの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から線を伸ばしてAdd Loose Gameplayを配置。
Received Notify BeginのMesh Compから線を伸ばしてGet Ownerを配置。そのReturn ValueをActorに繋ぐ。
Add Loose GameplayのGameplay Tagsから線を伸ばしてMake Literal Gameplay Tag Containerを配置。そのValueから線を伸ばして「変数に昇格」。変数の名前はAttackBeginTagにして、目玉アイコンをオープンにする。
Add Loose Gameplayから線を伸ばしてリターンノードと繋ぐ。
Received Notify Beginを選択した時と同じように今度はReceived Notify Endを選択する。こちらは終点の設定になります。
Received Notify Endから線を伸ばしてRemove Loose Gameplay Tagsを配置。
Received Notify EndのMesh Compから線を伸ばしてGet Ownerを配置。そのReturn ValueをActorに繋ぐ。
Add Loose GameplayのGameplay Tagsから線を伸ばしてMake Literal Gameplay Tag Containerを配置。
変数のAttackBeginTagをドラッグ&ドロップでGet配置してValueに繋げる。
Remove Loose Gameplay Tagsから線を伸ばしてリターンノードと繋ぐ。
ANS_BranchAttackの編集
ANS_BranchAttackを開く。
左メニューの関数オーバーライドの欄でReceived Notify Tickを選択。
Received Notify Tickから線を伸ばしてSend Gameplay Event to Actorを配置。
Received Notify TickのMesh Compから線を伸ばしてGet Ownerを配置。そのReturn ValueをActorに繋ぐ。
Send Gameplay Event to ActorのEvent TagはAtk.X.Next(Atk.Next)を指定。
Send Gameplay Event to Actorから線を伸ばしてリターンノードと繋ぐ。
AnimMontageにStateを配置
47_Frank_ActionRPG_Sword_Combo_A1_UE5_Montageの編集
AnimMontageにANS_ReadyAttackを追加します
コンボ1発目のAnimMontageである47_Frank_ActionRPG_Sword_Combo_A1_UE5_Montageを開く。
通知1の右スペースで右クリックして「通知ステートを追加」を選択。先ほど作成したANS_ReadyAttackを選択。
ANS_ReadyAttackという通知ステートは次のコンボに繋げられるボタンの入力期間です。始点を剣の振り始め、終点を剣の振り終わりぐらいに設定しましょう。もちろん、こういう調整は個人のこだわりで自由にやって良いです。
追加したANS_ReadyAttackを選択した状態で詳細を見る。Attack Begin TagにAtk.Ready.X2を指定します。
この通知ステートの始点でAtk.Ready.X2というタグが付与されて、終点で削除されます。Atk.Ready.X2はコンボ2発目の発動条件ですから、この間にボタンを押すとコンボ2発目の発動が確定する。
AnimMontageにANS_BranchAttackを追加します。
通知1の▼トラックで左クリックして通知トラックを挿入。通知2が出現します。
通知2の右スペースで右クリックして「通知ステートを追加」を選択。今度はANS_BranchAttackを選択。
ANS_BranchAttackという通知ステートは、先行入力確定後に次のMontageに切り替わるポイントです。ですから重要なのは始点です。剣の振り終わり、次のモーションに切り替わってもいいタイミングに始点を設置しましょう。早めに設置すればテンポよく剣を振りますし、遅ければ振り終わってから待ちがあります。
終点はANS_ReadyAttackより後ろなら良いです。
同じようにコンボ2発目の48_Frank_ActionRPG_Sword_Combo_A2_UE5_Montageとコンボ3発目の49_Frank_ActionRPG_Sword_Combo_A3_UE5_MontageにもANS_ReadyAttackとANS_BranchAttackを追加します。
ANS_ReadyAttackで付与するTagはAtk.Ready.X3→Atk.Ready.X4と数字が増えていきます。
厳密に言えばコンボの最後は通知ステートはいりませんが、後で4発目を作る時に楽ですし、AnimMontageの使いまわしもしやすいです。
コンボ3発目までを設定してテストプレイして、3発目までコンボが出れば成功です。
XYYコンボを作成する。
1発目のXボタンの後、2発目をYボタンで別のコンボが繋がるようにします。
攻撃アニメーションの準備
コンテンツ > Frank_RPG_Sword1 > Animationsにある59_Frank_ActionRPG_Sword_ShieldAtkと60_Frank_ActionRPG_Sword_DashAtkをYボタン攻撃にします。
2つとも選択して右クリックでアニメーションアセットのリターゲティング > アニメーション アセット / ブループリントを複製してリターゲティングを選択。
IK リターゲッタの設定
IK リターゲッタにRTG_UE4Manny_UE5Mannyを指定。これはUE4マネキンからUE5マネキンへのIK リターゲッタです。
ターゲット スケルタル メッシュはSKM_Quinnを指定。
サフィックスは_UE5にしました。
フォルダは前回と同じ/Game/Characters/Mannequins/Animationsを指定しました。
リターゲットを押す。
リターゲットされた59_Frank_ActionRPG_Sword_ShieldAtk_UE5と60_Frank_ActionRPG_Sword_DashAtk_UE5を選択した状態で右クリックして、作成する > AnimMontageを作成。
Gameplay Ability ブループリントの作成
GA_ComboX2を複製して名前をGA_ComboXY2にします。
GA_ComboXY2を複製して名前をGA_ComboXY3にします。
GA_ComboXY2の編集
Montage To Playに60_Frank_ActionRPG_Sword_DashAtk_Montageを指定。59ではなく60です。単に違いがわかりやすいモーションだからこうしています。
2発目の攻撃ですからIs First Attackのチェックを外す。
Ability TagsはAtk.XY。
Activation Owned TagsはAtk.XY.2。
Activation Required TagsはAtk.Ready.X2。X攻撃から派生しますので、発動条件TagはXコンボの1発目中に付与されているAtk.Ready.X2になります。
Activation Blocked TagsはAtk.XY.2。
GA_ComboXY3の編集
Montage To Playに59_Frank_ActionRPG_Sword_ShieldAtk_UE5_Montageを指定。
3発目の攻撃ですからIs First Attackのチェックを外す。
Ability TagsはAtk.XY。
Activation Owned TagsはAtk.XY.3。
Activation Required TagsはAtk.Ready.XY3。こちらはXY攻撃から続きますので、発動条件TagはXYコンボ中に付与されているAtk.Ready.XY3になります。
Activation Blocked TagsはAtk.XY.3。
AnimMontageにStateを配置
詳細のAttack Begin Tagは、
GA_ComboXY2に使っている60_Frank_ActionRPG_Sword_DashAtk_MontageはAtk.Ready.XY3を指定します。
GA_ComboXY3に使っている59_Frank_ActionRPG_Sword_ShieldAtk_UE5_MontageはAtk.Ready.XY4を指定します。
通知2に追加するだけです。
プレイヤーキャラクターのブループリントを編集
配列化したAbility Classに作成したアビリティを登録します。
左メニューのAbility Classを選択し、右の詳細のデフォルト値 > Ability Classの+を選択。出現したインデックス[*]のNone欄にGA_ComboXY2を指定。
続けてGA_ComboXY3も追加する。
ゲームパッドYボタンを押したらAbilityを発動させます。
イベントグラフの空いているところにゲームパッドYボタンを配置。
ゲームパッドYボタンのPressedから線を伸ばしてTry Activate Abilities by Tagを配置。
Gameplay Tag Containerから線を伸ばしてMake Literal Gameplay Tag Containerを配置。
その編集を選択してAtk.XYを指定。
これで完成です。
完璧に覚える必要はありません。ある程度の理解だけで良いのです。
勉強=試験の印象が強い人が大半かと思いますが、ゲーム作りはマニュアルを見ながら作っていいのですから、反復して完璧に覚えようとするのは時間の無駄です。必要な時に、こういう情報を引っ張り出して作れれば良いです。
コメント