Hummerkey
(Hummerkey)
1
AbilitySystemでアクションゲームのコンボ攻撃を作りました。ほぼ完成していたのですが、特定のタイミングでドッジロールして攻撃をキャンセルした時に不具合がありました。
仕組みとしては、
Xボタンを押すとGameplay Abilityが発動し、1発目の攻撃が出ます。
■Gameplay Ability ブループリント
■BP_ThirdPersonCharacter
Xボタンを押すことで1発目の攻撃のAnimMontageが再生され、そこに配置してあるAnimNotifyStateにより、再びXボタンを押すとAttack Begin TagにReady.2というTagが付与されて、コンボの2発目のAnimMontageの再生条件が決まります。
と同時にGameplay Ability ブループリントでWait Gamaplay Eventのノードが実行待機状態になっているはずです。
■AnimNotifyState ブループリント ANS_ReadyAttack
■AnimMontage X攻撃1発目
この時点で、2発目の攻撃が発動する準備が整っており、AnimMontageにもう1つ配置してあるANS_BranchAttackというAnimNotifyState内のSend Gameplay Event to Actorでイベントが実行されます。
■AnimNotifyState ブループリント ANS_BranchAttack
■コンボ1発目と2発目のタグ
この仕組みでコンボ4発目まで完璧に動作していると思っていましたが、1発目の攻撃中にANS_ReadyAttackでボタンを押して、2発目の攻撃が待機している状態で、ANS_BranchAttackに到達する前にドッジロールでキャンセルすると、その後Xボタンの攻撃が無効になりました。
原因もわかりかけていて、これとは別にYボタンのコンボがあり、それを発動すると、そのYボタンコンボのAnimMontageのANS_BranchAttackで思い出したようにXボタンコンボの2発目が自動発動します。
Xボタンコンボは、ずっと2発目の待機状態のままだったようです。そのためXボタンを押しても無効になっていたようです。
Wait Gamaplay Event→PlayMontageAndWaitで待機状態になっているイベントをキャンセルし、Xボタンが無効にならず、再びコンボ1発目が発動できるようにしたいです。
エンジンのバージョンは5.3です。
長文でごちゃこちゃしていて申し訳ございませんが、よろしくお願いします。
T_Sumisaki
(T_Sumisaki)
2
GameplayTaskを終了させる場合、明示的に EndTask
を呼ぶ必要があります
EndAbilityは実行されていますが、Ability内部の終了処理はきちんと実装しなければなりません
Wait Gameplay Event
のAsyncTaskを変数に保存しておき、 Event OnEndAbility
の時点で GameplayTaskの EndTask
を呼ぶと良いでしょう
Hummerkey
(Hummerkey)
3
返信ありがとうございます。
Wait Gameplay EventのAsyncTaskを変数へ昇格させ、
新たに配置したイベント OnEndAbilityからEndTaskに繋ぎました。
EndTaskに変数化したAsyncTaskをGetして繋ぐとテストプレイ後に「プロパティ AsyncTask_WaitGameplayEvent の読み取りを試行するためのアクセスはありません」「アクセスしようとしましたが、AbilityTask_WaitGameplayEvent_*** は無効(強制終了またはガーベージの保留中)」というエラーが出ました。
検証済Getに変更して確認してみると毎回「は有効ではない」になっていました。
どこか間違っておりますでしょうか?
T_Sumisaki
(T_Sumisaki)
4
Receivedではなく無印の実行ピンで取得する必要があります
Receivedを待つのであれば結局 Wait Gameplay Event
の完了(GameplayEventの発行)を待つことになるので、問題が解決しません
Hummerkey
(Hummerkey)
5
度々返信していただきありがとうございます。
なんとなく理屈が理解できて上手くいきそうだと思ったのですがダメでした。
不具合が発生するタイミングははっきりしました。
上記図のAsyncTaskがセットされた時の「AsyncTaskSet」がPrintStringで表示されてから、「EventReceived」が表示されるより早いタイミングでドッジしてキャンセルすると攻撃不能になります。
この不具合が起こるタイミングでのキャンセルでも上記図の最後にある「EndTask_PlayMontage」は表示されていました。
Wait Gameplay Eventの方だけが常に「は有効ではない」になっています。
「EventReceived」に届いていないのだからAsyncTaskが存在してEnd Taskできそうなのにできないところがわかりません。
それでいてこの状態でY攻撃をすると、Y攻撃のAnimMontageに配置してあるANS_BranchAttackに反応してX攻撃の2発目が自動発動します。
T_Sumisaki
(T_Sumisaki)
6
ドッジしてキャンセル
Abilityそのものをキャンセルしているのか、それともMontageの割り込みでキャンセル扱いとしているのかによりますが
後者である場合、Montageの割り込みで1段目は解決されますが、2段目の解決はなされない(Montageが実行されていないので割り込みが起こらない => EndAbilityまでいかない)ので、2段目のAbilityが実行されたまま( WaitGameplayEvent
を待ち受けたまま) になりますね
なので、2段目のOwnedTagである Attack.X.2
を保持したままの状態になります
1段目は Attack.X
という上位タグでBlock判定しているので実行できず、2段目は必要なタグ Attack.Ready.2
がない、かつ Attack.X.2
をブロックしているので実行できない、というデッドロックが発生していると思われます
Y攻撃のGameplayEventでようやくWaitが解かれるので、そこからXの2段目が再実行される、という流れです
上記の状態であれば、PrintStringの状況は満たされます
1段目と2段目、どちらのPrintStringであるかを判別できる情報を足すことをおすすめします
また、競合するアクション(回避)があるのなら、Abilityそのものをキャンセルするようにしてください
Hummerkey
(Hummerkey)
7
いろいろ教えていただいたおけげで
Wait Gamaplay Eventが原因ではない可能性があると思えています。
2発目のコンボに繋げるタイミングであるANS_ReadyAttackで、ボタンを押した時にAttack.Ready.2が付与されて、これが2発目発動前にドッジでキャンセルされていても残り続けているのが原因かもしれません。
Hummerkey
(Hummerkey)
8
申し訳ありません、
返信を読む前の同時投稿になってしまいました。
Hummerkey
(Hummerkey)
9
いろいろありがとうございます。
おそらくこの状態かと思いました。
いじってみます。
【追記】解決しました。
これまでドッジにはGameplay Abilityを使っていなかったのですが、ドッジにもGameplayAbilityを使用し、Cancel Abilities with Tagに「Attack」を指定することで、ドッジが発動すると同時に攻撃アビリティのTagが全てキャンセルされる状態になったと思われます。
これによりX攻撃の詰まりはなくなり、不具合が完全解消となりました。
WaitGameplayEventが原因だと思ってしまってお手間をとらせて申し訳ございません。こちらの仕組みも深く学べて勉強になりました。
初めての質問を丁寧に答えていただき、ありがとうございました。
system
(system)
Closed
10
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.