先日ヒストリア社さん主催のもくもく勉強会へ参加してきました。
Engineのソースを読む。充実した会でした。ありがたいです。
自分はペーペーなので精進せねばと実感しました。
さて、本日は「Delay」についてです。
この子、すごく便利です。
検証Verは4.7.1になります。
【概要】
「Delay」、「RetriggerableDelay」の2種類が存在。処理の待ち時間を設定する。
つまり、Durationに入力した時間だけWaitが発生します。
【動作】
・Delay・・・入力した時間(秒)の後、次の処理を行う。Delay中に再要求が合った場合、Delay待ち時間はリセットされない。
・RetriggerableDelay・・・入力した時間(秒)の後、次の処理を行う。Delay中に再要求が合った場合、Delay待ち時間はリセットされる。
つまり、以下の動作となります。
・1キーを押すと、1キーを押してから2.0秒後に「Hello」と出力されます。
・1キーを押した後2キーを押すと、1キーを押してから2.0秒後に「Hello」と出力されます。
・3キーを押すと、3キーを押してから3.0秒後に「Hello」と出力されます。
・3キーを押した後4キーを押すと、4キーを押してから3.0秒後に「Hello」と出力されます。
【特性】
ClassBlueprint、LevelBlueprintのEventGraphでは使用可。
ClassBlueprint、LevelBlueprintの関数内では使用不可。
関数内でのDelay呼び出しはできません。公式回答的には「関数でもDelay使っちゃうと、処理順が複雑になっちゃうよね。だからできないんだ。でもいずれ対応するかもね」とのこと。
たしかに。
で、基本的な使い方は以上。
ここからは調査編。
(1) ソースコードからDelayを使用できるか?
→できない。関数の利用範囲(BlueprintType)が"BlueprintCallable"なのでBlueprintからのアクセスしかできない。
(2) 同一Class内で複数Delayを同時に走らせることはできるか?
→できる。FLatentActionManagerという構造体にAddされてDelay毎に管理されている。
(3) DelayTime=0.0は本当に0.0なのか?
→0.0。以下コードで検証した結果、遅延なしの10.0という結果が得られた。ただし、float型なので厳密には0では無いのかもしれないが、許容範囲内であると思われる。
では、上記を踏まえて以下のケースではどのような結果が得られるか。
(A)
→BeginPlayから0.2秒後に「Hello2」出力、0.5秒後に「Hello1」出力となる
(B)
→(A)と同様、BeginPlayから0.2秒後に「Hello2」出力、0.5秒後に「Hello1」出力となる
勘違いしがちだが、Delayも一種の関数であり、FLatentActionManagerにイベント登録するだけで関数内処理は完了する。SequenceはThen0の処理完了後にThen1を行う振る舞いとなるため、Delay0.5の登録が完了した時点でThen1の処理に移行する。
forloopも同様、3回Delay0.5の登録を行っているが、初回の登録のみ有効、その後の2回の処理は破棄されCompletedを実行する。そのため「Hello2」が先に出力される。
以上。
Delayは「中断処理」として解釈すべきでなく、「登録処理」として解釈しておくと混乱しないかもしれない。