「ゴースト専用」ギミックの話 ～ハロクラ会場の裏側～

この記事は[クラスター Adovent Calender 2024](https://qiita.com/advent-calendar/2024/cluster)の15日目の記事です。昨日はSwanmanさんの「当日までに何か思いつくはず」でした。

---

こんにちは、滝竜三といいます。普段はクラスターでテクニカルアーティスト（TA）として働いています。
もともとは会場制作担当として入社し、[Creators Guide](https://creator.cluster.mu/)担当などを経て現在はこのポジションに落ち着きました。
そういった経緯もあり、TAとしての通常業務からは少し外れるのですが、今も一部の公式イベント会場でギミック制作を手伝っていたりします。

さて、今年3月頃から**公式番組「Hello Cluster」（ハロクラ）の会場がリニューアルしました**。焚火を囲んで語り合う感じの旧会場から、軌道エレベータのようなSFっぽい新会場になっています。
この会場に仕込まれている各種ギミックの実装も僕が担当しており、今回はそこで使っている工夫について解説したいと思います。

# ゴーストのみ入れる客席
この手のイベント会場では、「**なるべくステージの近くで見たい**」「**ステージ近くに人が集まると見づらい**」という、ある種矛盾した課題があります。
そのあたりの対策として、一昨年のハロクラ年末SPあたりから「**ステージ前には直接歩いて入れないようにしておき、離れた場所のボタンで前列の座席に座れる**」という仕組みを導入していました。
今回の新会場ではその仕組みをさらに発展させ、座席表パネルから前列の座席に座れるだけでなく、（他の人の視界の邪魔にならない）**ゴーストの参加者は前列に歩いて入れる**ようにしています。
※ここでいう「ゴースト」にはグループビューイングの参加者も含みます。

これはいわゆる**ローカルギミック**という仕組みを使っています。オブジェクトをPlayer Local UIの中に配置し、プレイヤーごとにオンオフを切り替える方法です。
実はこの会場の制作当時はまだローカルギミックの実現にやや特殊な方法が必要だったのですが、現在は[**Player Local UIをWorld Space、つまりHUD上のUIとしてではなく空間上に配置できるようになった**](https://note.com/cluster_official/n/n4ed32df15e0f)ため、以前より素直に実現できるようになりました。

このローカルギミックで、**「一般参加者」「ゴースト」及び「スタッフ」の各ロールによって異なる挙動をする**ようにします。

まずは「ゴースト」とそれ以外との識別です。ゴーストになった参加者には「（そのプレイヤーの行動によって発火する）**トリガーが動作しない**」という仕様があるので、それを利用します。

一般参加者だけ通れないようにしたいコライダをWorld SpaceのPlayer Local UIの子階層に配置し、エディタ上で**初期状態を非アクティブ**（つまりゴースト視点の状態）にしておきます。
このとき、オブジェクトのレイヤが勝手に「UI」になった場合は「Default」に変更するのを忘れないようにしてください（忘れるとコライダが反応しなくなったりします）。
また、Transformの代わりにUI用のRect Transformが付くことがありますが、こちらもRemove Componentして普通のTransformに戻してしまって大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2398274/9d66c297-866a-b19b-ec48-be827b04e201.png)

そのうえで、 **TargetをPlayerにしたOn Join Player Trigger**によってギミックを呼び出し、そのオブジェクトをアクティブに切り替えるようにします。
こうすることにより、**ゴーストではOn Join Player Triggerが発火しないため初期状態のまま**になり、**ゴースト以外では入室した瞬間にOn Join Player Triggerが発火してオブジェクトがアクティブになります**。
逆にゴーストにだけ見えるオブジェクトをつくりたい場合も同様に、初期状態をアクティブにしてOn Join Player Triggerで非アクティブにすることで実現できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2398274/72c5568c-f09c-c31c-79a3-b1ab37558af9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2398274/f2c61c7d-bd0f-4320-6e2b-203beddb1b1d.png)

# スタッフにのみ見えるオブジェクト
スタッフが進行のために見るスクリーンや、打ち上げギミックの操作パネルなどはスタッフにのみ見えるようにして、一般参加者が触れないようになっています。

こちらも同様にPlayer Local UIを利用したギミックになっていますが、スタッフの判定には「**スタッフのスポーン位置を一般参加者と変えられる**」機能を利用しています。

まずは先ほどと同様にスタッフ専用のオブジェクトをPlayer Local UIに配置し、初期状態を非アクティブ（逆にスタッフにだけ見えないオブジェクトは初期状態をアクティブ）にしておきます。つまり一般参加者視点の状態ですね。

続いて、スタッフのスポーン位置を**控室ではなく見えない場所にある別の空間**にしておき、そこにボタンをひとつだけ置いておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2398274/28805601-c663-ae80-b568-3362943174cf.png)

このボタンを押したときに、Warp Player Gimmickにより本来の控室（通常スタッフスポーンを置きたい場所）へワープすると同時に、Player Local UI上のオブジェクトのアクティブを切り替えます。こうすると、このボタンを押した人＝**スタッフスポーンから入室した人にだけ状態が切り替わる**仕組みを実現できます。**スタッフが必ずこのボタンを押さないといけない**（逆に一般参加者はこのボタンを触ることがない）ようにすることで「スタッフ専用」ギミックを動かします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2398274/6cc4c87c-1c8a-6aa1-04fd-6aa7776bff89.png)

ちなみにボタン（Interact Item Trigger）の代わりにスポーン地点に置いたOn Collide Item Triggerでもいいのですが、超巨大アバターなどを使うと一般参加者でも反応してしまう可能性があるので、ひと手間増えますがボタン式を推奨します。

なお、入室後にボタンを押して発動する仕様上、**必ず「ゴースト専用」の方の処理より後に実行**されます。そのため、例えば「一般参加者はぶつかる・ゴーストはぶつからない・**スタッフもぶつからない**」コライダをつくる場合などは、ここで一緒に「ゴーストには見えない」オブジェクトのアクティブを切り替えることで対応できます。

---

というわけで、ハロクラ会場で利用している「ゴースト専用」ギミックの話でした。Player Local UIは本来はUI表示のためのもので、World Spaceでの設置も例えば看板型のUIのようなものが主に想定されていますが、応用するとこういった工夫にも使えます。

明日はEliza_lnさんの「DifyやAIアシスタントについて書く」です。クラスターではメタ研を中心としてAIの活用についても積極的に取り組んでいるので、その辺の話になりそうですね。