見出し画像

cluster で複数ユーザ同時に時間計測してみた

メタバースプラットフォーム「cluster」向けに、一つのスペースに複数のユーザが居る状態で、各人の端末で同時並列にタイム(プレイ時間)計測を実現してみた話


はじめに

cluster には多くのゲームワールドがあり、中でも足場を飛んだり跳ねたりして飛び移りながらゴールを目指す、いわゆる「アスレチック」と呼ばれるゲームがたくさんあります。
ここで、ゲーム性をより高めるためにクリアに要した時間を計りたいと考えたのですが、一つのスペースに複数のユーザがいる場合にユーザごとにタイム計測をしようとするとトリッキーな作りにする必要があったので、備忘録としてまとめるものです。

ワールドの構成

全体配置・ゲームのルール

ワールド内の全体配置は以下のような形としました。

ワールドの鳥観図

ワールドに入ると、まず右下に見える「開始ボタン」だけが置いてある足場に降り立ちます。
ここでボタンを押すと、左下にあるアスレチックのスタート地点の足場に飛ばされます。スタート地点の足場から右上に向かってアスレチック本体部が伸びており、その終点にはゴール地点の足場があります。

スタート地点の足場を離れたときから、ゴール地点の足場に到達するまでの時間を計測し、ゴールに着くと各自の画面にクリアタイムが表示されます。
なお、アスレチックのプレー中に下に落下した場合は、スタート地点に戻され、タイムも改めて 0 から計測するものとします。

実現上の課題

上記の要件の実現のためには、各ユーザごとに独立して「プレー時間の計測開始」「プレー時間の計測停止」「プレー時間のリセット」を行う必要があります。

cluster で時間計測を行う場合、基本的には Cluster Script を用います。これは JavaScript でイベントごとの処理を記述するものです。
Cluster Script は「アイテム」と呼ばれるオブジェクトの上でのみ動作します。また、各アイテムには「オーナ」の概念があり、Cluster Script はアイテムのオーナとなっているユーザの端末上でのみ実行されます。

ここで、初期状態では最初からワールド上に配置されているすべてのアイテムは、スペースのホストがオーナとなります。
このため、各ユーザの端末で Cluster Script を走らせるためには何らかの方法で各ユーザがオーナとなるようなアイテムを用意し、その上で動かす必要が生じます。

具体的には、

  • ユーザが、アイテムを使う・掴む・座るなどの行動を取ることで、アイテムのオーナを移行させる

  • アイテムが別のアイテムを動的に作成することで、元のアイテムのオーナを作成されたアイテムに継承させる

といった方法でオーナを設定する必要があります。

設計

以上を踏まえて設計を行います。

上記の図内に黄枠で示している、以下のオブジェクトを用意しました。

  • 開始ボタン」… ワールド入口

    • 本オブジェクトはユーザが見ることが出来ます。

    • 本オブジェクトはアイテムであり、「使う」ことでオーナが移行します。
      また、その状態でタイマー用のアイテム(後述)を動的作成することで、各ユーザの端末上でタイマー用スクリプトが動くようになります。

  • タイムをクリアするコライダ」… スタート地点の着地ポイント

    • ユーザ個別の状態変数にタイマーのリセット指令を書き込みます。

  • タイム測定開始するコライダ」… スタート地点の、アスレチック本体部との接続部

    • ユーザ個別の状態変数にタイマー動作状態を書き込みます。

  • タイム測定終了するコライダ」… ゴール地点の、アスレチック本体部との接続部

    • ユーザ個別の状態変数にタイマー停止状態を書き込みます。

  • スタート地点にワープさせるコライダ」… アスレチック本体部の下の方

    • 落下したときにスタート地点に戻すためのワープギミックですが、ワープ先にタイムをクリアするコライダがあるため、連続実行されます。

上記以外に、必要に応じて動的生成する「ユーザ個別のタイマー用アイテム」を Unity の Prefab として用意しておきます。
本アイテムに設定された Cluster Script で、ユーザ個別の状態変数に応じてタイマーを動かすかどうか、あるいはリセットするかを制御します。

複数のユーザが同時に遊ぶケースを想定した具体的なシーケンス図は以下のようになります。

二人のユーザが相次いでプレー開始した場合の、開始ボタンおよびユーザ個別のアイテム間の処理とオーナの遷移
二人のユーザがプレーしていて、そのうち一人がスペースから退出した場合の、開始ボタンおよびユーザ個別のアイテムのオーナの遷移

「開始ボタン」では、以下のような処理フローのスクリプト・ギミックを実行します。
基本的には、「タイマー用アイテムをまだ作っていないならば作成する」という責務を担います。

「開始ボタン」のスクリプトの処理フロー
「開始ボタン」のギミック

「ユーザ個別のタイマー用アイテム」では、以下のような処理フローのスクリプト・ギミックを実行します。
ユーザ個別の状態変数を見ながら、タイマーが有効ならば onUpdate の deltaTime のぶんだけ数値をカウントアップする・タイマーリセット指令が来ていたら 0 にする、またオーナが居なくなった時に自分自身の破棄を行います。

「ユーザ個別のタイマー用アイテム」のスクリプトの処理フロー
「ユーザ個別のタイマー用アイテム」のギミック

成果物

以上の検討結果を基に、複数人が同時に遊べてタイム計測も行われるアスレチックワールドを作成しました。
各ユーザの画面左上にタイムが出ますので、みんなで競争してみてね!

補足

本ページの内容は、参考文献、実クライアントでの動作状況などを基に検討した結果となりますが、記載内容の正確性・信頼性などについて筆者は責任を負いません。

本記載内容は 2024 年 1 月時点のものとなります。

参考文献

この記事が気に入ったらサポートをしてみませんか?