
grabbableItemがバグでどこかに行ってしまう悲劇を防ごう【cluster】
こんにちは。VR-TRPGクリエイターの逆凪と申します。
clusterでイベントやゲームワールドを作っていて、grabbableItemが原点にワープしてしまったり、壁に埋まったりして進行不能になった経験はありませんか?
バグ対策自体はすごく簡単なんですが、初心者がやりがちなミスの他にもcluster特有のバグがあるので、躓いてもやもやしないようにこの場でしっかり解説していきます!
1.アイテムが何故か原点にあるor表示されない
非表示にしていたgrabbableItemを表示しようと、ボタンを押したが何故かそのgrabbableItemが原点にある・表示されていない!というケースです。
Unity上では発生しないのにcluster上では発生し、負荷が高いゲームやイベントで発生しやすい厄介なバグです。これは確率で起こるバグなので、一度デバッグで大丈夫だったからと言って信用してはいけません。
grabbableItemが表示されないという場合は、一度原点(座標が0,0,0の所)を確認しましょう。アイテムが原点に無い場合は今回の対策では解決しないので、2.アイテムが確かに表示されていない を確認して下さい。
【詳説】
▼まず、掴めるようにしたいオブジェクトに適当なコライダーとSetGameObjectActiveGimmickをつけます。そして非表示にするのもお忘れなく。

▼そしてHierarchyでオブジェクトを右クリック。「Create Empty Parent」を押します。

▼アイテムの親にEmptyが追加されましたね。このEmptyに対してgrabbableItemをつけましょう。その後Rigidbodyの設定を弄る事もお忘れなく。これでバグ対策は完了です。

【おまけ】
元々あるアイテムを途中で掴めるようにしたい場合のやり方もおまけで解説しましょう。
▼まず、掴めるようにしたいオブジェクトにgrabbableItemをつけます。Rigidbodyの設定を弄る事もお忘れなく。

▼斧(本体)の子にEmptyを配置し、適当な当たり判定をつけます。更にSetGameObjectActiveGimmickをつけて状態でオブジェクトを非表示にしましょう。これで完成です。

【簡易解説】
まとめると、以下のように親子関係を組めばOKです。
親(表示):grabbableItem
子(非表示):Collider・SetGameObjectActiveGimmick
2.アイテムが確かに表示されていない
この場合、まずはトリガーとSetGameObjectActiveGimmickとの繋ぎがしっかり出来ているかを確認しましょう(Keyのスペルが違う・Targetが違うなど)。こちらの記事が参考になるでしょう。
それでもダメで、Unity上では正常に動いているのにcluster上では確率でバグってしまうという場合は、使っているKeyの文字数を減らすと直るかもしれません。
3.アイテムを壁に埋めてしまった
進行に必要なアイテムをプレイヤーが壁に埋まった状態で手放してしまったというケースです。スマホ・PCのプレイヤーは壁の向こうのアイテムを取れないので、ワールド制作者側で何かしら対策をする必要がありますね。
【その1:アイテムをワープさせるボタンを置く】
TRPGのダイスパネルのように、プレイヤーがアイテムを携行する場合に有効です。やり方を解説していきましょう。
▼まずはEmptyを作成し、座標をアイテムのワープ先に設定します。

▼次はクリックでgrabbableItemをワープさせるボタンを作ります。CubeやQuadを作成してInteractItemTriggerを付けます。TargetはSpecifiedItemにして対象のgrabbableItemを指定していますが、別にGlobalでも良いです。Keyも適当にWarpAxeとしておきます。

▼最後に対象のgrabbableItemにWarpItemGimmickというコンポーネントをつけます。Targetは先程SpecifiedItemにしたならThis、GlobalにしたならGlobalを指定してください。KeyをWarpAxeに、TargetTransformを最初に作ったEmptyに設定して完成です。

【その2:手放されたアイテムが元々あった位置に戻るようにする】
謎解きワールドのアイテムのように、プレイヤーが狭い部屋で様々なアイテムを持ち替える場合に有効です。やり方を解説していきましょう。
▼まず、grabbableItemと同じ座標のEmptyを作成。RigidbodyとFixedJointというコンポーネントを付けます。Rigidbody内のUseGravityはオフに、IsKinematicはオンに。FixedJointのConnectedBodyには対象のgrabbableItemを指定しましょう。

▼次に、対象のgrabbableItemのRigidbodyを開いてUseGravityをオフに、IsKinematicをオフにしましょう。これで完成です。

ゲームワールドで扱う時は、アイテムを手放したプレイヤーが勘違いしないように、事前に仕様をしっかり説明する事もお忘れなく。
4.手放したアイテムがどこかに飛んで行った
移動中に手放したアイテムが慣性でそのままどこかに飛んでいくケースです。RigidbodyのIsKinematicをオンにすれば解決します。

終わりに
如何だったでしょうか。バグ対策に悩まされる事が少しでも減ったら幸いです。いくつかのバグ対策はハスさんに教えて貰った方法なので皆でハスさんを崇めましょう。
ということでお相手は、逆凪でした!