clusterでローカルギミックをつくる
VRChatとかでよく見るミラーのローカルでのON/OFFなどをclusterでも実装する方法を解説します。
ローカルギミックの作成方法
clusterにはLocalPlayerトリガーがありますが、PlayerLocalUI階層下のみしかこのトリガーを使用するギミックは設定できません。(一部ギミックを除く)
この制限を回避するにはLocalUI階層化にギミックを置き、ParentConstraint+ScaleConstraintでギミックの位置をワールドに固定するという方法があります。
この方法を用いてローカルミラーを設置してみましょう。
ミラーの設置位置として空のオブジェクトMirrorPosを設置します。
次にミラーをLocalUI階層化に置きます。(今回使用したミラーはこちらで配布しています)
次はワールドへの固定です。
上の図のようにParentConstraintとScaleConstraintを使用して先程のMirrorPosオブジェクトと同じ位置と向き、同じサイズになるようにします。
PlayerLocalUI階層化は画面サイズ変更でスケールも変わるので、ScaleConstraintでサイズを強制固定するのがポイントです。
次はミラーをON/OFFするギミックを実装します。ミラーにはSetGameObjectActiveGimmickを付け、Mirorr(LocalPlayer)トリガーで表示/非表示を切り替えるようにします。
表示/非表示はキューブを押すと切り替わるようにします。
InteractItemTriggerでキューブにインタラクトしたらOwnerに対してOnInteractトリガー(Signal)を送ります。インタラクトしたユーザーがOwnerになるのでそのユーザーに対してのみの操作になります。
OnInteractトリガーが送られたらPlayerLogicで表示/非表示を切り替えます。MirrorトリガーはBool型のため「=Not」で反転させることでTrue/Falseがインタラクトするたびに切り替わります。
SetGameObjectActiveGimmickは指定したトリガーの値がTrueなら表示、Falseなら非表示となるため、表示/非表示を切り替えることができます。
今回解説したサンプルシーンは以下からダウンロードできます。
ローカルギミックのコライダーの注意点
VR環境ではPlayerLocalUI階層化の物理コライダーが反応しなくなります。(デスクトップやスマホユーザーは反応します。)
この制限を回避するには、IsTriggerでないコライダーを含むオブジェクトはPlayerLocalUIの外に置いてConstraintなどで設置する必要があります。
また、コライダーをON/OFFさせることが不可能になるので、この場合はAnimationを使ってスケールや位置を変更させることで対応します。(ONならスケール1、OFFならスケール0にするなど)
コライダーを動かす際もAnimationを使って設置位置だけを動かし、コライダーはConstraintで固定するという方法を取る必要があります。
具体的にはPlayerLocalUI階層化のAnimatorをConstraitでワールド固定、動かすコライダーもConstraintでAnimatorオブジェクト階層化の動くオブジェクトに固定という構造になります。
さいごに
clusterはVRChatと違ってローカルトリガーに制限があるため、今回のような回りくどい面倒な方法を取る必要があります。
(以下は個人的な要望)
正直ローカルトリガーが自由に使えた方がローカルで処理すべきところはローカルで処理できるようになり、効率的だと思うので個人的には実装してほしい…(Owner遷移をいちいち考慮しないといけないのも大変)