【cluster】 手を離すと一定時間で消えるアイテムを作る
ワールド内でユーザーがアイテムを自分で生成できるようにしたいけど、再現なく生成されるとすぐにワールドが散らかってしまうので、持っているアイテム以外は一定時間で消えるようにしたい・・・という状況は多いと思います。
clusterには「持っていたアイテムが手を離れる」と発動するトリガー(OnReleaseItemTrigger)があるので、
アイテムが手から離れたらタイマーを発動
一定時間が経過したらアイテムを削除(DestroyItemGimmick)する
というのが基本の考え方です。
ただ、これだけだと
生成されてから誰も手に持たないままのアイテムは消えてくれない
アイテムを手から離したあともう一度持ったとしても、最初に手放してから一定時間で消えてしまう
といった問題が起きるので、もう少し工夫をしていきます。
Grabbable Itemのついたアイテムを用意して、ここに必要なギミックを組み込んでいきましょう。ここから先、解説するコンポーネントはすべて同じGameObjectに組み込んで下さい。
https://scrapbox.io/files/62dd747127107a001e5df40b.png
まず、アイテムを手から離すと発動する OnReleaseItemTrigger を付けます。
ここでは2つのことを行います。
一つは、アイテムを削除するタイマーを起動するためのシグナルを出すこと。ここではStartDestroyTimerという名前のシグナルにしました。
もう一つは、「アイテムが手から離れたまま」だということを確認するためのフラグを立てることです。Bool型の値を用意して、Trueにセットしておきます(=Value Bool のとなりのチェックボックスを有効にする)。ここではReleasedという名前にしました。
https://scrapbox.io/files/62dd7441f40b7a002212699b.png
次は、一定時間経過でアイテムを削除するタイマーです。
上で説明したトリガーから StartDestroyTimer シグナルが送られてくると発動するタイマーを作ります。ここではカウント秒数は30秒としてあります。
30秒のカウントが終了したらアイテムの削除を行うわけですが、ここでは直接アイテムを削除するのではなく、一旦「ほんとうに削除していいかどうかをチェックするロジック」を挟みます。ここではCheckDestroy という名前を付けました。
https://scrapbox.io/files/62dd75eb57ffd50022fb907c.png
「ほんとうに削除していいかどうかのチェック」で何をしたいかというと、「このアイテムをその後また誰かが持ったりしていないか?」をチェックしたい、ということです。誰も持っていないようなら削除してよいし、誰かが持っていれば削除するのをやめなくてはなりません。
ここでItem Logicを使います。Item Logicを使うと様々な条件判断を行うことができます。上に書いたような判断をLogic流に言い直すと
「(前の処理でTrueにセットしておいた)Releasedというフラグが、Trueのままかどうか」をチェックして、Trueのまま維持されていいればアイテムを削除する(Destroy)シグナルを発生させる
ということになります。
このような判断を挟んだ上で、
「一度手を離れたアイテムを再び誰かが持ったらReleasedの値をFalseに変更する」
ようにしておけば、「誰かが持っていれば削除するのをやめる」ができます(この部分はあとで書きます)。
フラグの値がTrueかどうかを判断するには Equals というロジックを使います。下図のようにすることで
このItemのReleasedという値が True (チェックが入っている状態)ならば
このItemに向けてDestroyというシグナルを発する
ことができます。
https://scrapbox.io/files/62dd76afec708f002385faaf.png
最後に、Destroyというシグナルが送られてきたらアイテムを削除するのがDestroyItemGimmickでです。
https://scrapbox.io/files/62dd7951c2669d001dc860a8.png
さて、上に「一度手を離れたアイテムを再び誰かが持ったとき、Releasedの値をFalseに変更する」と書きました。この処理は、OnGrabItemTriggerを使うことで実現できます。OnGrabItemTriggerはOnReleaseItemTriggerの逆で、アイテムを持ったときに発動するトリガーです。
このアイテムを手に持った人がいるときは、Releasedの値をFalse(=チェックがついていない状態)にする、という処理を書きます。
https://scrapbox.io/files/62dd79f4a9435f0020a4c018.png
ここまででほぼ完成ですが、最後に「生成したあと誰も手に持たなかった場合も一定秒数で消える」ようにしましょう。
これは、「このアイテムが生成された時点で削除タイマーを発動する」ことで実現できます。もしも30秒のカウントダウン中に誰かが手に持った場合は、上に書いた仕組みで削除がキャンセルされるので問題ありません。
アイテムが生成された時に発動する OnCreateItemTrigger を使い、
削除タイマーを発動するための StartDestroyTimer シグナルを送る
ReleasedフラグをTrueにセットしておく
の2つの処理を書きます。
https://scrapbox.io/files/62dd7aeaffa449001df768bd.png
上で説明した処理の流れを図にするとこのような感じになります。
https://scrapbox.io/files/62dd7ea64d0de30023aa5eab.png
これで
誰も手にもっていない状態が一定時間つづくと自動で消えるアイテム
が実現できます。
解説は以上です!よきclusterライフを!