すぎしーのXRと3DCG

主にXR, Unity, 3DCG系の記事を投稿していきます。

【Unity】Boltなどのビジュアルスクリプティングで気づきにくいミスパターン

f:id:tsgcpp:20200723161652j:plain

概要

Boltが正式に無償化したということで、今回はBoltなどのビジュアルスクリプティングで気を付けたいことを1つ共有したいと思います。
この話はBoltに限らずUE4のBluePrintなどでも当てはまると思います!

Boltについて

Bolt

Boltの参考動画

以下の動画が参考になると思います!

www.youtube.com

補足

Unit (Boltにおけるノード) は <Unit名> で表現します。

以下のSet Variable Unitは <Set Variable> として記載します。

f:id:tsgcpp:20200723162048j:plain

問題

早速ですが私がぶち当たった問題を簡単に表現したグラフを見てみましょう。
以下のグラフには問題があります!

f:id:tsgcpp:20200723145542j:plain

良かったらちょっと考えてみて下さい!
処理の流れとしては以下を想定して実装しています。

  1. TimeCount + deltaTime の結果をTimeCountに格納
  2. Set Variableした値をDebug.Logで出力
  3. やりたいことは更新後の TimeCount の確認

答え

初期変数を以下とすると、ログには何が出力されるでしょうか?

  • TimeCount = 2.96
  • deltaTime = 0.02

答えは 3.00 です!
deltaTimeが2回足されたものになっています!

f:id:tsgcpp:20200723150003j:plain

※理由がわかっている人はこの後の話はつまらないと思いますw

要注意ポイント

おそらくほとんどの人が気にしたと思いますが、以下の赤色と橙色の丸で囲った部分が要注意ポイントです!

f:id:tsgcpp:20200723152046j:plain

Unitは「そのUnitのOutputが要求されたときに、そのUnitが処理してOutputを出力」します。

そして、今回の<Add><Set Variable><Debug Log>の2つからOutputが要求されているため、 1フレームに2回<Add>が動くことになります。

<Add> は処理したときのOutputの値を所持することはなく、要求毎にOutputを出力します。

処理の流れ

1. Set Variableが実施

  • <Set Variable><Add>のOutputを要求
  • <Add>が自身の処理を実施
    • Outputは <Time>deltaTime <Get Variable>TimeCountを取得して加算したもの
  • <Add>がOutputを<Set Variable>に渡す
  • <Set Variable>がOutputをTimeCountに格納

2. Debug.Logが実施

  • <Debug.Log>`のOutputを要求
  • <Add>が自身の処理を実施
    • Outputは <Time>deltaTime<Get Variable>TimeCountを取得して加算したもの
    • この時点で取得されたTimeCountは「1.」でdeltaTimeが加算されたものになっている
  • <Add>がOutputを<Set Variable>に渡す
  • <Debug.Log>がOputputをコンソールに出力

詳細に処理の流れを説明するとこんな感じでしょうか 。

f:id:tsgcpp:20200723161652j:plain

<Add>が2回動く」、「2回目の<Add>が使用するTimeCountが加算済みのものになっている」ことで、ログには2回加算されたTimeCountの値が出力されたんですね。

解決策

Set Variable のOutput から取得

<Set Variable>のOutputは処理した時のものが保持されるようです。

f:id:tsgcpp:20200723153952j:plain

ついでに以下のように、<Set Variable>が保持されているかの確認もしてみました。

変数から直接取得

今回やりたいことは更新されたTimeCountの値を知りたいだけです。
よって単純に変数から取得すれば問題ありません。

f:id:tsgcpp:20200723154636j:plain

プログラマーはコーディングしているときは意識することなくこの形を取っていると思います。
今回紹介したパターンはビジュアルスクリプティング特有かもしれませんね。

複雑なグラフでの例

今回はシンプルな例で紹介しましたが、実際は以下のようにたくさんのUnitから成るグラフでも発生すると思います。

f:id:tsgcpp:20200723165225j:plain

こちらの例でも<Add>から2回Outputの要求が発生するため、同様の問題が起きます。

雑感

いよいよBoltが無償化しましたね。
実は自分、2年ほど前にBoltを買ってたんですが1回も使ってませんでした。。。(無償化してから使うというUnityユーザのプチあるあるw)。

Playmakerとかもちょいちょい触っていたんですが、これからはBoltも触っていこうと思います。

UE4のBluePrintを触ったことがあったせいか、わりとすんなり扱うことができました。
(ちなみにBoltのControl Schemeという設定のデフォルト名は「Unreal」だったりしますw)

Bolt2というものも予定されているようなので、Unityでもノードベースのビジュアルスクリプティングがもっと盛り上がりそうですね!
BluePrintにもあるInterfaceとかも導入されると個人的にはうれしいです。

それでは~。