clusterでローカルギミックをつくる
VRChatとかでよく見るミラーのローカルでのON/OFFなどをclusterでも実装する方法を解説します。
2025.2.18 更新
PlayerScriptを使用したローカルギミックについての記事を新しく書きました。
Cluster Creator Kit のアップデートについては以下
2024/9/17のCluster Creator Kit v2.24.0アップデートでLocalUIのワールド設置が入りました。
Render ModeをWorldSpaceに設定することでParentConstraint、ScaleConstraintの設定は不要になりました。
ローカルギミックの作成方法
clusterにはLocalPlayerトリガーがありますが、PlayerLocalUI階層下のみしかこのトリガーを使用するギミックは設定できません。(一部ギミックを除く)
Cluster Creator Kit v2.24.0から公式にワールド設置に対応したのでPlayerLocalUI配下に置くだけでOKです。(Constraintは不要)
PlayerLocalUIのRender ModeをWorldSpaceに設定します。
この制限を回避するには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なら非表示となるため、表示/非表示を切り替えることができます。
サンプル
今回解説したサンプルギミックはこちらのリンクからダウンロードできます。
ローカルギミックのコライダー
Cluster Creator Kit v2.24.0以降、PlayerLocalUIのWorld設置に対応したため、こちらの問題は起きません。コライダーはVRでも反応します。
VR環境ではPlayerLocalUI階層下の物理コライダーが反応しなくなります。(デスクトップやスマホユーザーは反応します。)
この制限を回避するには、IsTriggerでないコライダーを含むオブジェクトはPlayerLocalUIの外に置いてConstraintなどで設置する必要があります。
また、コライダーをON/OFFさせることが不可能になるので、この場合はAnimationを使ってスケールや位置を変更させることで対応します。(ONならスケール1、OFFならスケール0にするなど)
コライダーを動かす際もAnimationを使って設置位置だけを動かし、コライダーはConstraintで固定するという方法を取る必要があります。
具体的にはPlayerLocalUI階層下のAnimatorをConstraitでワールド固定、動かすコライダーもConstraintでAnimatorオブジェクト階層下の動くオブジェクトに固定という構造になります。
Timeline式
W@さんのTimeline方式のローカルギミック
さいごに
clusterはVRChatと違ってローカルトリガーに制限があるため、今回のような回りくどい面倒な方法を取る必要があります。
(以下は個人的な要望)
正直ローカルトリガーが自由に使えた方がローカルで処理すべきところはローカルで処理できるようになり、効率的だと思うので個人的には実装してほしい…(Owner遷移をいちいち考慮しないといけないのも大変)
