左のオーブを持って(1)、右の装置の上に置くためのノードを下のように組みました(2)
1
2
オーブを持っており、且つコリジョンの中にいる時にEを押せば、左の装置の上部にオーブを置けるという感じのノード(のつもり)です。
この状態でテストプレイすると確かに思い通りに動くのですが、時々以下のエラーを吐いてきます。
なぜこんなことになるのでしょうか?ノード通り動いてくれるならいいじゃん。と思うかもしれませんがよろしくお願いします
左のオーブを持って(1)、右の装置の上に置くためのノードを下のように組みました(2)
1
2
オーブを持っており、且つコリジョンの中にいる時にEを押せば、左の装置の上部にオーブを置けるという感じのノード(のつもり)です。
この状態でテストプレイすると確かに思い通りに動くのですが、時々以下のエラーを吐いてきます。
なぜこんなことになるのでしょうか?ノード通り動いてくれるならいいじゃん。と思うかもしれませんがよろしくお願いします
謎ではありません。当然そうなる、という組み方をしています
まず1のグラフですが、Eキーを押す前にBeginOverlap側に接続されたCastが成功していない場合、変数にセットされるもの(Castノードから取得している参照)がNoneになり、その後のAttachActorToComponentがエラーにより失敗します
2も同様に、Eキーが押される前にEndOverlapに接続されたCastが成功しない場合、Castノードにある参照がNoneであるため、 As BP Orbs
は取得できずエラーになります
ノードはどこからでも接続できるように見えますが、正しく構築するために守るべきルールがあります
別の実行ライン(イベント)のノードの出力を拾うべきではありません
各イベントノード、非Pureの関数ノードは最後に実行されたときの実行結果を保持しますが、実行されていない場合は初期値(オブジェクト参照であればNone)です
逆に、実行されてしまえば値が変わるということでもあります
BeginOverlap、EndOverlapなどは特に、何度も発生する可能性があるイベントであり、保持している値もその度に変更されるため、変数と同列に見るには非常に不安定です
イベントや入力は絶対に順番通りであり、特定の状況しか起こり得ない、と断言できるのであれば、画像のような組み方は許容されますが、そうでないのであれば、変数を使うなどして実行ラインを分離し、実行が前後しても問題ない作りにする必要があります
おっしゃられたようにノードの順番を変えたり、分離したらエラーを吐くことなく、さらにスムーズに実行してくれるようになりました。(実は偶にEの入力を受け付けてくれなかった)
これからは一気に書かずに時々分離させることにします。ありがとうございました
残念ながら、問題点を理解されていないように思います
流れの違う処理の出力ノードを拾ってはいけません
画像に問題点を描き込みました
緑の線とオレンジの線は別の処理であり、異なるタイミングで、独立して実行されるものです
オレンジ線の処理が一度でも流れてからでないと、問題の参照は取得できないので、先に緑線の処理が実行されるとエラーになります
また、仕様にもよりますが、CollisionにOverlapするのは目的のActor(この場合はプレイヤーキャラ)だけとは限りません
イベントや関数の出力は、最後に実行されたものを保持するため、最後に検知されたものがプレイヤーキャラ以外だった場合、この処理は破綻します
擬似コードですが、本来こうあるべき、という組み方を示しておきます
1つ目の処理に似せてあります
比べてみてください
再三悩んだ結果『Is Validノード』ではなく、『Branchノード』を使うことにより
T_Sumisaki
氏に教えて頂けた「流れの違う処理の出力ノードを拾わないノード」が(多分)組みあがりました。
今のところはエラーもなく順調に動いています。ありがとうございました。
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.