Posted Articles

検証's articles. (6)

わんころのUE5勉強会 May/22/2025 20:27

【UE5:検証】Common Action Widgetで画像が表示されない

皆様、お疲れ様です!

今回は CommonUI の機能の1つ Common Action Widget に加えて、編集> プロジェクト設定> ゲーム - Common Input Settings の Enable Enhanced Input Support を有効にした際の検証です。

Common Action Widget で表示する画像ですが、ある条件で画像が表示されない問題があったためそれを検証していた記事になります。

UE5.5.4 で確認した内容です。


Common Action Widget とは


専用のアセットで設定したキーやボタンに対応した画像を表示するための Widget です。キーボード ⇋ ゲームパッドに操作を切り換えた時に表示する画像を変えたりできます。

利用するための準備

プラグインとプロジェクト設定


編集> プラグイン から Common UI Plugin を有効にし、プロジェクトを再起動します。


さらに、編集> プロジェクト設定> Common Input Settings の Enable Enhanced Input Support を有効し、プロジェクトを再起動します。

※ CommonUI を利用する際、プロジェクト設定の "ゲームのビューポートクラス" に[CommonGameViewportClient]を設定することが多いですが、今回の検証は画像の表示を確認するだけなのでこの設定は不要です。


Input MappingContext, Input Actionを作成


IMC_UI_InputTest
IA_MenuTest01, IA_MenuTest02, IA_MenuTest03 を作成しました。

画像を表示するために利用する
Input Mapping Context(IMC)になります。画像はそれぞれキーをマッピングしたものです。
今回は W, E, Enter の3つのキーを設定しています。


UI の作成

その後、コンテンツブラウザで右クリック> ユーザーインターフェース> ウィジェットブループリントから CommonUserWidget を選択して作成します。ここでは CUI_MenuTest としておきました。

※ User Widget(いつもの) を選んで作成しても Common Action Widget は利用できるのでこの例だとどちらでもOK。


CUI_MenuTest を開き、Vertical Box に Common Action Widget を3つ追加しました。


Common Action Widget のプロパティで Enhanced Input Action に Input Action を設定します。
今回は Common Action Widget を3つ使っているので、それぞれに IA_MenuTest01, IA_MenuTest02, IA_MenuTest03 を設定しています。

UI 側の設定はこれだけです。


表示する画像を設定する


CommonInputBaseControllerData を選択してブループリントを作成します。名前を KeyboardIcon としました。


これを開き "Input Type" を[Mouse and Keyboard]にします(デフォルトでこれになってます)

"Input Brush Data Map" の「+」を押してキーと画像を割り当てます。W, E, Enter のキーを設定していますが、IMC_UI_InputTest で設定したキーと一致させる必要があります。

キーの画像には KENNEY 氏が公開されているアイコン をお借りしています!


検証開始


いつもの IMC_Default はそのままに、後ろに IMC_UI_InputTest を Priority 0 で追加しています。


適当な場所で Create Widget から CUI_MenuTest を作成し、「Add to Viewport」しました。

検証1:期待した挙動


3つのキーが Common Action Widget によって表示されました!
やったー!なんですが次の検証を行います。

検証2:Add Mapping Context しない場合


IMC_UI_InputTest を「Add Mapping Context」しない場合は画像が表示されません。

利用する場合は「Add Mapping Context」する必要があります。


検証3:Priorityを変える


IMC_Default の Priority が高くなるように設定してプレイしてみます。


W が表示されなくなりました。
これは、IMC_Default のキャラ移動 W とかぶっているからだと思います。


先程は W が表示されていましたが、「Add Mapping Context」する際、同じ Priority が設定されている場合、後から追加した方が Priority が高くなります。

Common Action Widget に設定した Input Action は Priority の設定に影響するということが分かりました。


検証4:Consume Input はどうなる?


今は IMC_Default の方が Priority が高いので、W を利用している IA_Move を開きます。
その中の "Consume Lower Priority Enhanced Input Mappings" という設定があります。

IA_Move よりも Priority が低いキーもトリガーさせるかの設定です。
この設定を OFF にします。



また W が表示されたので Consume Input の設定に影響するということも分かりました。

まとめ

Common Action Widget で設定した Input Action を「Add Mapping Context」された IMC から探し、そこにマッピングされたキーと一致する画像を CommonInputBaseControllerData から参照して表示。

同じキーが見つかった場合は、Priority が高い IMC があると画像が表示されない。

Consume Input の影響も受けるという結果になりました。

キーコンフィグに利用できないかなと思ってここ数日検証していたんですが、画像が表示されないキーがあったので原因を探っておりました。


おわりに

連携出来るのはいいな~と思ったんですが、キーコンフィグに利用しようとすると、Prioroty や「Add Mapping Context」されてないといけないので一工夫いるかもと思いました。

なかなかややこしいですね。

If you liked this article, support the creator with a tip!

Sending tips requires user registration.Find details about tips here.

わんころのUE5勉強会 Apr/28/2025 21:37

【UE5:検証】CommonUIとGame PadのFace Button Bottom(Aボタン)

皆様、こんばんは!

以前 X で検証した内容ですが、解決できずこんな仕様なんだというのが分かっただけの記事です。


▼ 以前色々試して撃沈した様子
https://x.com/UE5wancoro/status/1884024134549790825


この記事の内容

CommonUI + Input Key Selector を使ってキーコンフィグを実装しようとした時に、Face Button Bottom(以降Aボタン)がマウス左クリックとして扱われたのを検証していた時のお話です。


プロジェクト設定

CommonUI プラグインを有効にすると、プロジェクト設定の「GameViewportClientClassName(ゲームのビューポートクライアントクラス)」で "CommonGameViewportClient" を選択できます。

以降はこの設定にしてる場合の Input Key Selector の挙動です。


どういう挙動なのか


UI 作成時に "Common User Widget" を親にし、
Canvas Panel, Input Key Selector を配置しました。


ゲームパッドで A, B, X, Y ボタンを押した動画です。
分かりづらいですが Aボタンの部分が「マウスの左ボタン」となっています。


Aボタンが左クリックとして扱われる

CommonUI の入力等に関しては 入力技術ガイド に色々書いてありました。

一部抜粋:
FCommonAnalogCursor では、現在のウィジェットで 結合アクション によってキャプチャされていないゲームパッド上の標準的な「Accept」アクションの入力は処理しません。代わりに、その入力が FAnalogCursor::HandleKeyDownEvent に送信されて、FAnalogCursor によって FSlateApplication で処理する合成マウス クリック イベントが作成されます。
この時点で、このマウス イベントは通常のクリックと同じような入力処理プロセスを経て、最終的なクリックをトリガーします。

自分には難しい内容だったので誤った解釈をしている可能性はありますが、ゲームパッド操作時に内部的にマウスカーソルで操作してるような動きに置き換えられているので、Hovered や Clicked イベントが利用できるのかなと思いました。

また、ゲームパッド上の標準的な「Accept」というのがAボタンのことなら、Input Key Selector でAボタンを押すと通常のクリック(左クリック)として扱われるという説明に納得できます。


特定の操作時はAボタンとして扱われる


この動画は Input Key Selector を先にマウスでクリックして入力受付状態にし、ゲームパッドでAボタンを押した時の挙動です。

この場合はAボタンとして扱われるようです。
ゲームパッドで Accept(Aボタン) を利用しなかったので、通常のゲームパッドとして認識されたのかなと思いました。

また、Input Key Selector の On Key Selected イベント時に入力されたキーの種類を判別する Blueprint も作成し、入力がマウスであることも確認出来ました。


※ チェック用の処理


ちなみに Common Input Subsystem> Get Current Input Type の方で確認すると GamePad と表示されます。

この結果で、Input Key Selector 選択時はゲームパッド入力の判断が出来ていて、内部でマウスイベントに置き換えられているということが分かりました。

なるほど~とは思いましたがAボタンで返ってきて欲しかったんですよね...


C++ を使えば回避できるかも?

私はこの時点でお手上げだったので解決はできませんでした。
UE5.4 以降ならこういう方法があるそうです。

https://forums.unrealengine.com/t/why-does-left-mouse-click-register-when-i-press-gamepad-face-button-bottom-on-gamepad/1809814/3


他の機能で代用しようか検討中

CommonUI を使うとボタンやスライダ含め、ゲームパッドでのUIナビゲーションに利用できそうでいいな~と思ってたんですが、ゲーム制作にキーコンフィグを入れようと確認していた時にこの内容にぶつかってしまったのが今回の経緯でした。

プロジェクト設定で "GameViewportClient" にしていればこの挙動は発生しなかったので CommonUI をやめて UI Navigation 3.0 を代わりに使う方法も検証してたのですが、エディタが高頻度で落ちるようになったのでやむなく断念しました。

代わりにボタン+テキストの構成で、キー入力があったらキーの名前をテキストにセットしてそれっぽく見せる方法でどうにか出来ないかなと考えています。

キー入力の取得やキーコンフィグは Enhanced Input User Settings を使って色々検証出来ているので UI のナビゲーションが出来れば行けそうな気はしています(フラグ)


最後に

やっぱり UI 周りかなり難しいなと感じますね...
もうそろそろ UE5.6 もリリースになると思いますが何かしらアップデートがあると嬉しいですね。

UE5.6 の新テンプレートも結構楽しみにしています。


それではまた!

If you liked this article, support the creator with a tip!

Sending tips requires user registration.Find details about tips here.

わんころのUE5勉強会 Feb/28/2025 21:32

【UE5:検証】Actor Componentでタイムラインを使ってみる

皆様、こんばんは!

最近 UE5 に触れる時間が少し出てきたのでまた楽しんでおります。

今回は「Add Component by Class(クラスごとにコンポーネントを追加)」ノードを利用した時にたまたま見かけた "Timeline Component" というコンポーネント。

Actor Component で「Add Timeline」は利用できないけどコンポーネント経由ならもしかして利用できたりするのかな...という疑問から始まった久々の検証記事です。

結果的に利用できたという内容なのですが、Actor Component で「Add Timeline」ノードは普通の方法で利用できず、使い方的に大丈夫なのかは一切不明なため利用の際は十分ご注意下さい!

UE5.3.2 を利用しました。


この記事で行う事

Actor Component 内で Timeline Component を利用したタイムラインの挙動を作成し、この Actor Component を別の Actor(BP_Cube) で利用してキューブの位置を動かすだけのサンプルを作成します(Blueprint のみです)

始める前に

既にそういう機能が Fab で販売されているので興味のある方は是非!
Component Timeline


Actor Component では検索してもヒットしない


タイムラインの追加はグラフ上で右クリックし、add timeline など検索すると見つかりますが、Actor Component では "状況に合わせた表示" のチェックを外しても見つかりません。

パレットからドラッグ、別の Actor BP からコピペして張るとかも禁止されています。

そこで今回の趣旨である "Timeline Component" を使ってタイムラインを作成し、必要なイベントをバインドして利用するというのが目的です。


Actor Component の作成


コンテンツブラウザから右クリック> ブループリントクラス> Actor Component をクリックし、名前を "AC_TimelineSample" で作成しました(AC = Actor Component)

Timeline Component の追加


"AC_TimelineSample" のイベントグラフで、「BeginPlay」から「Add Component by Class」を繋ぎ、"Target"ピンに「Get Owner(Actor Component)」、"Class"ピンに [Timeline Component] を指定します。

そして "Return Value"ピンから変数へ昇格(Promote to variable)します。
いつもならここで変数名を決めるんですが、変数名を変えてもデフォルトの New Var に戻ってしまうのでそのまま New Var として扱います(理由は分かりません)



タイムラインエディタ内の [+トラック]ボタンからトラックを追加することができますが、そのトラックは関数が用意されています。

画像にも載せましたが「Add Interp Float」「Add Interp Vector」「Add Interp Linear Color」「Add Event」となっています。
今回はキューブの位置を動かすだけなので「Add Interp Float」を利用します。


「Add Interp Float」とイベントのバインド


先程の New Var を作成した続きです。
New Var から引っ張り「Add Interp Float」を出します。

"Float Curve"ピンから引っ張り、これも変数へ昇格しました。後ほどカーブアセットを作成して指定します。

"Interp Func"ピンにはカスタムイベントを繋ぎ、名前はタイムラインノードに合わせて Update としました。

例えばタイムラインの「Play from Start」を呼ぶと、Update が再生~終了まで継続的に呼ばれます。

"Output"ピンには後ほど作成するカーブアセットに基づいた Float値が流れてきます。後ほどキューブの位置を動かす処理で追記します。

"Property Name" / "Track Name"ピンに必要に応じて名前を付けます。
プロパティ名・トラック名それぞれ None でもバインド先の Update はちゃんと機能していたので必須ではないようです。


「Set Timeline Finished Func」とイベントのバインド

キューブを動かすだけなので終了後に何かすることはないのですが、タイムラインの再生終了後に何かしたい時の備忘録として記載しました。
(おまけの項目で簡単に触れています)



先程の「Add Interp Float」からの続きです。
今度は New Var から引っ張り「Set Timeline Finished Func」を出します。これはタイムラインの "Finished" 実行ピンと同じくタイムラインの再生終了時にバインドしたイベントが呼ばれます。

"New Timeline Finished Func"ピンにカスタムイベントを繋ぎ、名前を「FinishedTimeline」としました。

必須ではないですが、イベントディスパッチャー(OnFinished としました)を作成し、「FinishedTimeline」の後に呼び出しておくと今回作成した AC_TimelineSample を BP で利用する際、"OnFinished” というイベントで利用できるので便利になるかもしれません。



カーブアセットの作成


コンテンツブラウザから右クリックし、その他> カーブをクリックします。「カーブクラスを選択」のウインドウが出たら Curve Float を選択ます。名前は CA_Cube としました(CA = Curve Asset)


CA_Cube を開き、右クリック> キーを追加から2つキーを追加します(マウスホイールをクリックでもキーの追加は可能です)

追加されると △ アイコンがタイムライン上に作成されます。



1つキーをクリックし、左上の入力欄へ直接数値を入力します。
記載がないので分かりづらいですが、左側が時間、右側が値になります。それぞれ 0, 0 のキーと、1, 1 のキーが出来ればOKです。

これは1秒かけて0~1へ値が変化するという意味になります。
Float値は先程「Add Interp Float」で作成したカスタムイベント(Update)の "Output"ピンから受け取ることが出来ます。


カーブアセットをセットして残りの処理を完成させる

AC_TimelineSample に戻り、変数 "Float Curve" の初期値に CA_Cube をセットします(表示がない場合は AC_TimelineSample のコンパイルが必要です)



AC_TimelineSample の「BeginPlay」に追加の処理を入れていきます。New Var の変数を昇格した後くらいに、「Get Owner」>「Get Actor Location」を出し、"Return Value" を変数に昇格します。

名前を "Start Location" としました。
この位置から適当な距離移動させるために利用します。



次は「Add Interp Float」で作成したカスタムイベント(Update)に追加の処理を入れていきます。

Lerp(Vector) の "Alpha"ピンと "Output"ピンを繋ぎ、 "Start Location" から Y軸方向に適当な距離動かすような処理にしました。

これで1秒かけて初期位置から250動く挙動が完成です。


BP_Cube で AC_TimelineSample を利用する

コンテンツブラウザで右クリックから、ブループリントクラスをクリックし、Actor を選択して作成します。名前を BP_Cube としました。



BP_Cube を開き、「コンポーネント」パネルからキューブと、AC_TimelineSample を追加したのが画像の左側です。

BP_Cube のイベントグラフより、"AC_TimelineSample"> "Get New Var(Timeline Component)"> 「Play from Start」を出し、「BeginPlay」と繋いだのが画像の右側です。



余談ですが、「Play from Start」はタイムラインの入力実行ピンの1つです。これは最初からタイムラインを再生したい時に利用できます。


これで BP_Cube をレベルに配置してプレイすると、キューブの位置が1秒間Y軸方向に250動きます。
簡単な挙動ですが、タイムラインの機能は利用出来てそうな雰囲気です。

おまけ:タイムラインの再生終了時に何かしたい場合


「Set Timeline Finished Func」の所でちらっと書いた Finished ですが、使い方は BP_Cube 内だとこんな感じになります。

また、タイムラインで利用可能な関数はイベントグラフで右クリックから「コンポーネント>タイムライン」カテゴリで確認してみて下さい。


最後に

冒頭にも書きましたが、Actor Component ではタイムラインノードが使えないので無理やり使ってるような気がしなくもないです。

利用できると便利なのに...と感じることがちょくちょくあったので今回はとても勉強になりました。

それでは、また!

If you liked this article, support the creator with a tip!

Sending tips requires user registration.Find details about tips here.

わんころのUE5勉強会 Jul/25/2024 22:02

【UE5:検証】レベルシーケンサの再生と逆再生をBlueprintで制御する検証

皆様、こんばんは!

以前、レベルシーケンサの再生や逆再生など、再生周りの操作を Blueprint を使って遊んでた時のプロジェクトを改めて起動し、機能追加とかしてみようと思ってたのですが、個人的によく分からない部分もあったため備忘録として残しておきます。

やることはレベルシーケンサにアニメーションシーケンスを入れて再生などしたものです。

本記事はただの検証とその結果を書いた記事なので、いつも以上によく分からないことが沢山書かれているので注意して下さい!

UE 5.1.1 で作成してます。


適当なレベルシーケンスを用意


シーケンサの作成が本題ではないので詳しい内容は割愛しますが、 MF_Run_Fwd(走りアニメ) を使って左から右に移動させるものを作成してます。

再生をコントロールする UI を作成


コンテンツブラウザで右クリック> ユーザーインターフェース> ウィジェットブループリント と選択し WBP_Sequence というものを作成しました。

UI の構成はこんな感じにしています。
ボタンの見た目や名前と内部の処理が一致してませんが、各UIの役割は以下の通りです。

Stop(Button):押すと一時停止します。

Play(Button):押すと再生します。一時停止中の場合、その場から再生を再開します。

PlayBack(Button):押すと逆再生します

PlayForward(Button):押すと通常再生に戻します(機能は Play と同じですが、実装に使った関数が違い、挙動の違いが確認出来ました。後述しています。)

Seekbar(Slider):スライダを動かすことでスクラブ(再生位置を調整)する機能です。


レベルシーケンスを変数にして使いやすくする


WBP_Sequence のグラフで右クリックし「On Initialized」を出し、「Set Input Mode UI Only」+「Set Show Mouse Cursor」で UI 専用の操作にしてみました。

※ 今回の例だと「On Initialized」ではなく「Construct」でも同じですが、初期化の処理は1回実行されればいいので「On Initialized」を利用しました。

更に「Create Level Sequence Player」の Return Value から変数へ昇格し、以降シーケンサのあれこれはこの変数を利用します。
(最初スクラブのテストをしていたので変数名は Scrub Sequence としています)



「On Initialized」の続きの部分です。

先程変数へ昇格した Scrub Sequence から引っ張り「Get End Time」を出します。この Return Value は "Qualified Frame Time 構造体" になっており、構造体を分割をすると表示される Value(Integer型)でシーケンサの最終フレーム(時間?)を取得できます。
これも変数に昇格し "End Frame" という名前にしました。

最後に Seekbar から引っ張り「Set Max Value」の "In Value" ピンに「Get End Time」で取得した値を渡し、スライダの最大値をシーケンサの最終フレームと同じにします。


"End Frame" に入る具体的な値ですが、この例だと 72 になります。


そしてレベルブループリントで「Create Widget」から「Add to Viewport」し、開始時にシーケンサを再生する冒頭の動画の挙動ができます。後は UI の操作と連動する部分を作成していきます。

再生・一時停止



再生は「Play」、一時停止は「Pause」を利用するだけなので簡単です。「Stop」という関数もありますが、これは停止後に「Play」すると最初から再生されるので挙動が違います。

また、シーケンサが最後まで再生された後にもう一度「Play」を呼ぶと最初から再生になります。


余談ですが、再生ボタンをクリックすると一時停止のアイコンに変わり、もう一回クリックすると再生のアイコンに変わるような、1ボタンで「Play」⇋「Pause」を切り替えれる UI がいいかなと思いました。


逆再生・順再生



逆再生は「Play Reverse」という関数が用意されており、呼ぶと現在の再生位置から逆再生が始まります。

順再生は普通の再生と同じく「Play」を呼んでいるため、現在の再生位置から普通に再生を再開しているという挙動です。

気になる点がありまして、この動画の5秒あたりで「Play Reverse」を呼んでシーケンサの最初に戻った所に注目すると、開始位置に戻っているのにピタッと止まってないことに気づきました(少し長めにアニメーションが再生されている)

また、順再生の方も同じくシーケンサの最後まで再生された時にピタッと止まってませんでした。

理由はよく分からないが原因は分かった


MF_Run_Fwd の0フレーム目(開始時)に Anim Notify を仕込み、アニメーションが開始した瞬間が分かるようにしました。

なぜそういう挙動になっているのかは分かりませんでしたが「Play Reverse」でシーケンサの最初に戻った時に MF_Run_Fwd(走りアニメ)が再生されていたのが原因でした。

画像にはないですが、同じ手法で MF_Run_Fwd 終了時にも Anim Notify を仕込んでシーケンサを最後まで再生させると同じくアニメーションが再生され続け、その終わりで Anim Notify が実行されました(シーケンサの終了より少し遅れて Anim Notify が実行された)

細かい所ですが仕様的にそういうもんじゃないか...という気持ちを抑え、どうにかシーケンサと連動してアニメーションがピタッと止めれないかと色々確認してみました。


検証1:When Finished で挙動が変わる


この挙動ですが、レベルシーケンス上に追加したアニメーションを右クリック> セクションの編集> When Finished を "Keep State" にしているとこうなるようでした。

これはシーケンサの再生が終わった時に固定したいものがある時に利用するプロパティです。例えばドアを開けるカットシーンがあった時に、ドアを開きっぱなしにしておくなどが出来ます。

"Keep State" を "Restore State" に変更した時の挙動がこちらです。

ピタッと止まりましたが Idle になりました。走りアニメーション中に止まって欲しかったので想定してた結果にはなりませんでした。

"Restore State" は再生する前の状態に戻ります。
ドアの例だと、シーケンサの再生が終わったらドアが閉まった状態に戻ります。

検証2:「Play To」を使って解決


※上記の「Play Reverse」「Play」を「Play To」に置き換えた画像


※元の「Movie Scene Sequence Playback Params を作成」

When Finished を "Keep State" にしている挙動の方が理想だったので "Keep State" のままで何か出来ないかも確認していると「Play To」を使うことで解決出来ました。

「Play To」の "Playback Params" 入力ピンから引っ張り、「Movie Scene Sequence Playback Params を作成」を出して構造体ピンを分割した状態の画像です。

「Movie Scene Sequence Playback Params を作成」の "Position Type" が [Frame] の場合、Frame Number の Value の値を利用するようです。


この数値はレベルシーケンサ上のフレームと同じ扱いのようです。
UI の逆再生ボタンを押すと「Play To」で現在の再生位置から 0フレームへ向けて再生されるので実質逆再生になります。

順再生ボタンを押すと、今回 End Time が 72 のシーケンサなので、現在の再生位置から72フレームへ向けて再生されるので順再生になりますが、「Play」と違い 72フレーム目に来た時ピタッと止まります。

▼ それがこの動画です

動画の最後に、逆再生後に普通の再生(「Play」を呼ぶ)ボタンを押した時は最後がピタッと止まってないことが確認できます。


検証結果:「Play」「PlayTo」


なにかの設定等で回避出来たのかもしれませんが、とりあえず今回の検証で分かったことは、再生するアニメーションを Keep State にして「Play」でシーケンサの最後まで再生した場合そのアニメーションの1サイクルが終わってないとそのまま再生され続けることが分かりました。

「Play Reverse」で逆再生した時、0フレームに戻ったタイミングでそのアニメーションを再度再生して止まるという結果になりました。


アニメーションの1サイクルとは画像で示したシーケンサ上の「|」こんなアイコンの所です。今回のシーケンサでは2サイクル目のアニメーションが再生されますが、2サイクル目が終わる前にシーケンサが終了してしまうため、残りのアニメーション終了まで再生されたということだと思います。

「Play」と「PlayTo」で何か処理が違うんですかね...
今まで「Play」「Stop」「Pause」くらいしか使ったことなかったので色々知れて勉強になりました。


スライダを使ったスクラブで再生位置を調整


こんな感じでスライダを使って再生位置を変更できます。
再生中のスライダが連動して動いていませんが、シーケンサの現在の再生位置を取得し続けるような仕組みをどう実装すればいいか分からなかったため今回は未実装になりました。

後述する「Set Playback Position」を WBP_Sequence の Tick で使えばそれっぽい挙動は出来たのですが、一時停止中などシーケンサを止めている場合でも常に実行され続けるため余分な処理が続くな...と思いました。



完成した Blueprint を先に貼っておきます。
先程スライダ(変数Seekbar)の「Set Max Value」を End Time である 72 に設定したのでスライダの値は 0~72 の間になっています。

スライダの値をそのままシーケンサのフレームへセットすることで実現できます。


「On Value Changed」はスライダの値が変更される度に呼ばれます。スライダを左右に動かしている間も値が変わるので呼ばれます。

Scrub Sequence から引っ張り「Set Playback Position」を出します。これがシーケンサの再生位置を直接変更できる関数のようです。

これも構造体ピンを分割していき、Frame Number の Value に「On Value Changed」で変更された値 Value を繋ぎます(Float から Integer への変更のため、切り捨ての Truncate が使用されています)

「Play To」の時も出てきましたが、"Position Type" が [Frame] の場合、Frame Number の Value の値を利用するようです。


「On Mouse Capture Begin」はスライダ上をクリックした時に1度呼ばれます。そのままスライダを動かしている間は呼ばれません。
こちらはスライダをクリックした時に「Is Playing」でシーケンサが再生されているかチェックし、再生中であれば「Pause」を使って一時停止させています。

「On Mouse Capture Begin」の方が先に処理されますが、スライダ上をクリックした = 値が変わったという事でもあるのでその後「On Value Changed」も処理されます。

スライダの値を再生位置の指定にそのまま使えるので処理自体は結構簡単ですね。

おわりに

この検証ですがネットで調べても全然情報がなく色々なノードや設定を変更してこういうことなのかな...というのが分かったのですが個人的にかなり苦戦してました。

例えば「Get End Time」で取得した 72 という数値。これは記事にあったシーケンサの最終フレームを取得出来ます。

しかし「Play To」や「Set Playback Position」で値をセットしたのは Frame の Value が使われています。取得は Time でセットが Frame だったので混乱してました。

そして "Position Type" の [Frame] で、[Time] を選ぶこともできるんですが、その場合は Time の値が利用されます。Frame の Value に何を指定していても関係なくこれも混乱していた原因の一つです。

しかも構造体ピンを分割とかしないと見つけられないこともあり、最初これを何に使うのか?むしろ使わない?ということも含め全然わかりませんでした...

そしてシーケンサの0フレーム・最終フレームへ到達した時のアニメーションがピタッと止まらない等々、分からないことが続いていたとは言えかなり勉強になりました。

場合によっては「Play To」での再生もいいかもしれないなということで今回は終わりにします。


それではまた!

If you liked this article, support the creator with a tip!

Sending tips requires user registration.Find details about tips here.

わんころのUE5勉強会 Jan/01/2023 00:00

【UE5:検証】Enhanced Input:Priority や Consume Input

皆様、あけましておめでとうございます!!
今年も一年宜しくお願い致します!

2022年で一番触ったはずの Enhanced Input が未だによく分かっていません。
すべての始まりである「Add Mapping Context」も初心者の私にはややこしかったため、色々確認したことをまとめた記事になります。

【この記事の内容を YouTube の動画で公開】
https://youtu.be/j8pUpNu8CuE


「Input Mapping Context」を記載するのが長いので、以降 IMC と記載しています。

Add Mapping Context


Enhanced Input を触った時に一番最初にお世話になるノードだと思います。

機能としては "Mapping Context" で指定した IMC を追加し、入力を使えるように準備します。

"Priority" で入力の優先度をつけることができます。
数字の大きい方が優先度が高くなります。


2023-01-02 追記:
"Options" ですが、とても重要なオプションであることが分かったため追記致しました。
どういうオプションなのかについてページ下部の「Ignore All Pressed Keys Until Release」に追記しております。


抑えておくメインの機能についてはたったこれだけです。
これだけなんですが、どういう挙動を示すのかを見ていくと意外とややこしいです。

しかも Enhanced Input を使う上で絶対理解した方がいい挙動ばかりでした。


▼ Enhanced Input の公式ドキュメント
https://docs.unrealengine.com/5.0/ja/enhanced-input-in-unreal-engine/

公式ドキュメントにこのような記載がされています。

適用したコンテキストに優先順位を付けることで、同じ入力を受け取る複数のアクション間の競合を解決できます。

複数の IMC があり、それぞれで IA_Jump という同じ入力アクションを設定した場合、ジャンプボタンを押した時にトリガーされるのは1回なのか、複数回なのか気になりますよね。

この記事はその優先順位に注目しています。
そんなわけで下記いくつか検証を行ってみました。

検証の前に

今回の検証ではジャンプのトリガーを基準に見てみます。


まず IMC_A と IMC_B の2つを用意し、両方に入力アクションの「IA_Jump:スペースバー」を割り当てています。

IMC_A は Triggers に Pressed を指定しています。
(Pressed はキーを押した瞬間トリガーされます)

IMC_B は Triggers に Released を指定しています。
(Released はキーを離した瞬間トリガーされます)

また、入力アクション IA_Jump には Triggers/Modifiers は設定していませんが、大事な設定なので "Consume Input" に赤枠をつけています。
最初は ON の状態で確認します。



トリガーの確認方法ですが、ジャンプがトリガーされた時「Print String」で "Jump" と出力するようにしました。

押した離したでどうなるか見ていきます。

検証1:IMC_A の優先度を高くする


「Add Mapping Context」の Priority を IMC_A が高くなるようにしました。

プレイして確認すると IMC_A の Pressed 入力が優先され、スペースバーを押した瞬間に1回トリガーされます。

IMC_B の Released はトリガーされません。


検証2:IMC_B の優先度を高くする


今度は IMC_B の Priority が高くなるようにしました。

プレイして確認すると IMC_B の Released 入力が優先され、スペースバーを離した瞬間に1回トリガーされます。

IMC_A の Pressed はトリガーされません。


検証3:同じ Priority にする


今度は両方の Priority を同じにしました。

プレイして確認すると後で追加された IMC_B の Released 入力が優先されスペースバーを離した瞬間に1回トリガーされます。

IMC_A の Pressed はトリガーされません。
同じ Priority の場合は後から追加したものが優先されます。


ここまでの結果で、入力が被った場合は Priority の高い方が優先され、同じ場合は「Add Mapping Context」で後から追加したものが優先された入力になることが分かりました。


検証4:割り当てるキーが違う場合


今度は IMC_B のスペースバーの代わりにマウスの右クリックを割り当てました。

入力の被りがなくなった場合はどう処理されるかも見てみます。
結果は Priority に関係なく両方ともトリガーの対象になります。

IMC_A のスペースバー(Pressed)と、IMC_B の右クリック(Released)が両方とも利用できるということです。

同じ IA_Jump を使ってるので Priority の高い方が優先されるのかなと思いましたが、キー入力も完全に一致してる時じゃないと効果はないようですね。


この設定をちぐはぐにしておくメリットがあるのか分かりませんが、入力があっちもこっちも反応してる場合はこの辺りを見直したほうが良いかもしれません。

検証5:Consume Input とは?

※ IMC_A と IMC_B 両方ともスペースバーの入力に戻しました


ここまでの検証は "Consume Input" が ON でした。
OFF にするとどういう挙動になるかも見ていきます。

結果は Priority に関係なく両方ともトリガーの対象になります。

入力はどちらもスペースバーですが、押した瞬間、離した瞬間それぞれでトリガーされるということです。

"Consume Input" は入力が被ったキーがあった場合、優先度が低い入力も処理するか?という設定になることがわかりました。

2023-01-03 追記:検証6:複数の IMC で入力アクションは異なるが同じキーを割り当てた場合


今度は IMC_B に違う入力アクション IA_Jump2 を割り当て、キーはスペースバーで同じキーを割り当てました。

入力イベントは異なっているが、割り当てたキーは同じというシチュエーションです。

この結果は Priority の高い方が優先されます。
それぞれの入力イベントでトリガーされるだろうと思っていたので意外でした。

検証の結果

ここまでの結果で、Enhanced Input の入力は、入力アクション(IA_○○)よりも割り当てたキーが被っているかどうかを優先的に判断し、その結果を Priority や Consume Input に準じて処理するという結果になっています。

入力が競合しないようにと、簡単に書いてましたが、
細かい挙動はドキュメントを見ただけでは分からない内容ばかりでした。



ただ追加するだけですが、設定によって色々なパターンがあることが知れて非常に勉強になりました。


IMC はキャラ移動用や UI 操作用など、ゲーム内で必要な新しい入力を追加することができるので、優先度について知っておくことは今後必要になると思います。


おまけ1:Remove Mapping Context


"Mapping Context" で指定した IMC を削除します。
IMC がなかった場合はエラーや警告もなさそうでした。

主に「Add Mapping Context」で追加した IMC を削除する時に利用することになると思います。

一例ですが、インベントリを開いた時に 「Add Mapping Context」で UI用の入力を追加し、閉じる時に「Remove Mapping Context」で削除するような使い方が出来ます。

IMC がアセット単位のためこういう付け替えが容易にできるのは非常に嬉しい機能です。


おまけ2:Clear All Mappings


追加したすべての IMC を削除できます。

ゲーム中タイトル画面に戻ることを想定した時、色々な IMC が追加されていることも予想されるため「Clear All Mappings」で綺麗にしてから必要な IMC だけ「Add Mapping Context」をするなどの初期化系の処理に使えそうです。

2023-01-02 追記:"Options"ピンの Ignore All Pressed Keys Until Release

先に Twitter へのリンクを貼っておきます。
https://twitter.com/UE5wancoro/status/1609488690421837825

どういうシチュエーションなのかというと
IMC_A に IA_OpenPauseMenu という入力アクションを用意し、Escキー(Pressed)で Pauseメニューを開くという実装をしました。

Pauseメニューを開く際、Pauseメニュー専用の IMC_Pause を「Add Mapping Context」で追加します。

IMC_Pause には、IA_ClosePauseMenu という入力アクションを用意し、同じく Escキー(Pressed)で Pauseメニューを閉じるという実装しました。

Pauseメニューを閉じる際、IMC_Pause を「Remove Mapping Context」で削除します。


こういうシチュエーションで、IMC も入力アクションも Open/Close で違うけど、両方同じキーを割り当てたという内容です。

Escキーで Pauseメニューを開くと、なんとメニューが開く→ 閉じる→ 開く...と Escキーを押しっぱなしの間これがループします。

「Add Mapping Context」で違う IMC を追加したにも関わらず、入力アクション(入力イベント)も違うのに、入力はフラッシュされず押した状態が継続しているということになり普通にまずい挙動です。

期待していた動作は Escキーを押せばメニューがちゃんと開き、もう一回押したら閉じるという動作です。


その前に、この動作については historia 様が公開して下さっているこの記事で解決できます!
本当にありがとうございます!!

▼ [UE5][C++]EnhancedInputで独自のInputTriggerを作る~UIカーソル高速移動編~
https://historia.co.jp/archives/26608/




補足となりますが「Add Mapping Context」「Remove Mapping Context」の "Options" は「Modify Context Options 構造体」となっていて、画像のようにピンを分割することができます。


右側のようにピンを分割するか、「ModifyContextOptionsを作成」ノードを使うと出てくる "Ignore All Pressed Keys Until Release" のフラグにチェックを入れれば先程のメニューが開いて閉じてのループはなくなります。

注意したい点は "Options" ピンが結合されている状態だと先程のループする症状が発生するということです。

"Options" ピンを分割するとデフォルトでチェックが入っておりループはしません。

恐らくデフォルトで "Ignore All Pressed Keys Until Release" が False になっていると思われるので、明示的に True にしておく必要があるようです。

今まで使った事がなかった "Options" ですがこんな大事な設定が隠れているなんて思いませんでした。
これを知らずにデバッグしても解決策は見つからなかったと思いました。


押しっぱなしで反応してもいいケースや、そういう挙動にならないケースであれば False でいいと思いますが、これからは「Add Mapping Context」と「Remove Mapping Context」の "Options" ピンは分割し、True でも False でも明示的に設定しようと思いました。

年明けからまた勉強になりました。


「Add Mapping Context」は追加と Priority を決めるだけで簡単に利用できるためか、細かい検証をしている情報には辿り着かなかったためこの記事を公開してみました。


今年は一本ゲーム完成を目指したい所です!!

If you liked this article, support the creator with a tip!

Sending tips requires user registration.Find details about tips here.

« 1 2

Search by Article Tags

Monthly Archive

Search by Exclusive Perks

Search Articles