見出し画像

Clusterワールドでドアの開閉状態を他ユーザと共有する方法

勝手に非公式Clusterワールド制作部をやっています。
どうも、なっとうまきです。

さて、ワールドを作っていると扉を付けたくなるのが人情というものです。しかし、ドアに付けるのは開閉するだけの「アニメーション」だけでいいのでしょうか。

アニメーション:正式には、アニメーションクリップとUnity上では呼ばれています。この記事内では、アニメーション、もしくはアニメーションクリップと呼びます。

ドア開閉アニメーションだけでよいのか

結論から言うと、駄目です。
他のユーザと同期をするための仕組みが必要です。

同期をしないとどうなるの?

ワールドの初期状態:扉が閉まっている(Close)

例えば、「なっとうまき」と「読者の方」が同じワールドに行くとします。

「読者の方」が先にワールドに入り、ドアを開けます
「なっとうまき」が後からワールドに入って、ドアを見ると閉まっています。

「読者の方」視点:自分でドアを閉めてから、閉まったドアを貫通して入ってくる「なっとうまき」が見える。

画像1

こんなイメージ。

せっかくドアが開いたり閉じたりする表現を付けているのに、もったいないですね。
そして、世の中のゲームはちゃんと扉の状態がユーザ間で同期されています。
Clusterの限界はこんなものではないはず!

どんな仕組みにすればいいか。

まぁ、とりあえずアニメーションを作りましょう。
Animation・Animatorを使ってワールドに動きを与える
このページでドアの開閉アニメーションを作ったら
ロジックやアニメーションの遷移の設定をします。

が、、全体像を見ずに手順だけ見ても理解しづらいので、ロジックの動きを見てみましょう!

オブジェクト同士のブロック図です。
ここで言うオブジェクトとは、「ドア」のオブジェクトも含みますし「Interact Item Trigger」や「Item Logic」といったロジックすらも含みます。さらに、「ユーザ」(自分や他の人)すら含む意味になります(!)

オブジェクトの相互影響を図解したブロック図

ある意味設計図ですね。

設計図1

ここで大事なのは、ドアが開いているか(door_is_open)を示すフラグがtrueであればドアが開いているので、door_is_open=trueならば、ドアを閉じるアニメーションを動かします。

矢印の方向は、影響を与える向きです。
A→B なら、AがBに影響を与える というように読んでください。

つまり、ItemLogicはdoor_is_open変数に影響を与え、door_is_open変数もItemLogicに影響を与えます。さらに、door_is_open変数はSet Animator Value Gimmickに影響を与え、Animatorを動かし、Animatorに設定しているアニメータコントローラ(以降コントローラ)を動作させ、コントローラはdoor_is_open変数を読み取った上で状態を遷移させアニメーションを最終的に再生しています。

・・・・みたいな。

楽しくなってきましたね!!!!!

ロジックを作る

先程のブロック図の、この部分を作ります。

設計図2

というわけでこんな雰囲気になりました。

画像4

この画像内で、ItemLogicに設定している変数のタイプがRoomStateとなっています。
これは、今いるワールド全体の状態としてdoor_is_openを管理してますよ。ということを意味しています。

つまり、RoomStateはユーザ全員から参照され、変更可能な変数となります。

次、残りの部分を作っていきます

設計図3

アニメーション自体の作り方は、「Animation・Animatorを使ってワールドに動きを与える」を参照してください。

このページで作ったアニメーションがドアの種類分だけザーッと揃うとこんな雰囲気になります。
(全てのドア分モーションを作るのはちょっと面倒なので、一つのドアで相対座標を計算させるモーションを一定の箇所だけ記録して横展開しています。)
この方法の詳細についてはまた別の記事を書こうと思います。
書けるかな?誰か書いてくれるかな?

アニメーションクリップとアニメータコントローラ

黄色い四角で囲った、三角形のアイコン(左)と、四角形が3個重なっているようなアイコン(右)があります。

これらはそれぞれ、左側の三角形を「アニメーションクリップ 」右側の四角形が3個重なっているようなものを「アニメータコントローラ」と呼びます。

画像6

ここでは、アニメーションを作った上で、状態遷移をさせるロジックをコントローラに付けます。

その前に、アニメーションクリップに対して、最低限の準備をします。

アニメーションクリップに対する準備

もし、画像のようにチェックが入ってしまっていたら、チェックを外しましょう!アニメーションがループしてドアがパタパタ開いたり閉じたりします。

画像8

チェックを外す!

画像7

これが正しい状態です。

アニメータコントローラの設定

全体像を見るとこういうふうになっていればOKです。
ひとつひとつ見ていきましょう。

画像9

ワールドで管理しているdoor_is_open変数を使うために、「パラメータ」一覧に「door_is_open」を追加します。

追加の方法は以下の手順です。

画像10

New Boolという名前を、

画像11

以下のように、door_is_openに変更します。

画像12

これで、「door_is_open」を使う準備はできました。

状態遷移の設定

アニメータコントローラには「デフォルトの状態」が存在します。
つまり、ユーザが何もしていない時の状態を持っています。
言い方を変えると、「ワールドに降り立った瞬間にどんなアニメーションするか」というステートです。

それが、Entryというステートから伸びているオレンジ色のステートです。
基本的にワールドに降り立った時、の挙動は「何もしない」状態が好ましいので、アニメーションは何も設定しない状態にしておきましょう。
「何もしない」という意味合いで、ここではIdleと命名しています。

画像13

そして、このIdleというオレンジ色の箱をクリックすると、右側のインスペクターにはMotionが設定されていると思います。
「何もしない」ので、Motionを「なし(モーション)」に設定します。

画像14

これで、ワールドに入っても何も起こらない(扉が閉まったままなら閉まったまま)の状態遷移が出来ました!

扉を開け閉めする状態遷移を作る

このままでは、扉を開けることが出来ません。
そのため、状態遷移をいい感じに設定してあげます。

これから作るのは状態遷移図(ステートマシンダイアグラム)とも言います。とはいえ、まぁあまり細かいことを気にしてもワールドは作れないので作っていきましょう。

口で言うのはかんたんですが、設定するのもかんたんです。

とりあえずおもむろに、以下の三角形のアニメーションクリップを

画像16

ステートマシン図を描く画面にドラッグ&ドロップします。
そうすると、以下のようにドラッグ&ドロップした場所に、灰色のブロック(ステート)が追加されるはずです。(2個追加していますが、それぞれ「開く」アニメーションクリップと「閉じる」アニメーションクリップをドラッグ&ドロップしました)

画像16

AnyStateを右クリックして、遷移を作成をクリックします。

画像17

すると矢印が出るので、こんな感じにぴょいっとつなげます。

画像18

両方つなげるとこうなります。

画像19

遷移条件の設定 その1

はい、ではラストスパートです。
先程つないだ「矢印」をクリックします。(手順1)
(矢印のことをエッジともいいます。)

画像20

そして、インスペクタのSettingsをクリックします(手順2)
さらに、自身に遷移チェックを外します

画像21

こうなっていればOKです。
もう片方の矢印も同じように設定します。
これをしないと、自分自身に遷移してしまって、これまたドアがパタパタと開いたり閉じたりしてしまう原因になります。

状態遷移条件の設定 その2

上記の設定をしたら、更にインスペクタに注目します。
※もし以下の画像と同じようなインスペクタが表示されていなければ、開くアニメーションか、閉じるアニメーションにつながっている「矢印」をクリックしてみると開くことが出来ますよ。

画像22

黄色い四角で囲った部分が「遷移条件」になります(Condition:条件)
この部分の、+で囲った部分をクリックすると

画像23

このように、door_is_openとtrue が出てきます(もしかするとfalseかも知れません)

画像24

これらが意味するところは、
「もし、door_is_openが、trueならば、この遷移を辿りなさい」
という意味合いですので、もっと日本語に意訳すると
「もし、ドアが開いていたならば、この遷移を辿りなさい」
となります。

door_is_openがtrueならば、ドアが開いているので、ドアを閉める遷移へ
door_is_openがfalseならば、ドアが閉じているので、ドアを開ける遷移へ

というようにそれぞれの矢印を設定します。

そして完成へ。。。

お疲れさまでした!動作を確認して正しく動くか見てみてください。

ぐおー疲れた。
今日はここまで。

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