【cluster】Logic使ったゲームワールドを作ろう パターン編2

12 min read読了の目安(約11600字

Cluster Creator Kit Advent Calendar 2020の5日目の記事です。

(※この記事は「パターン編2」です。よくあるLogicのパターンとかを説明します。「準備編」「本編」ほど丁寧な解説ではないです。。。)

できたワールド

PlayerLocalUIつかったワールド
この記事は12/5に書いたのですが、12/14にこの記事のワールドをclusterにアップロードしました。

PlayerLocalUIつかったワールド
↑こちらからどうぞ。

ただし、改変に使えるように素材をぜんぶ自作かCC0のモノに差し替えた上、「ボールを取ってもGet表示が出る」「UIの位置を変更」とかビミョーな変更をしています。

ダウンロードして改変できます

Googleドライブ - 改変できるUnityプロジェクト本体
↑こちらからダウンロードしてください。改変OK。

こういう画面になったら、右上の赤くマルをしたとこのボタンでダウンロード

こんな画面になることもありますが、構わず「ダウンロード」ボタンを

導入方法

zipファイルを解凍 → 解凍したフォルダをUnityで開いてください。

上に書いてあるダウンロードのURL以外は、公式記事のテンプレートワールド『シューター』のススメ!をマネすればOK。
解凍方法まで説明してくださっているんで親切。

その他


無事Unityで開けても最初はカラのシーンが表示されるんで、↑の画像の場所にあるGameSceneを開いてください。

使っている素材はぜんぶ自作かCC0なんで、好きに改変して、clusterにワールドをアップロードして頂いて構いません


この記事で作るのは……

ここまで使っていなかったPlayerLogicGlobalLogicを使ってみましょう。
さらに、ワールドの中にUIがあるんじゃなくて、フツーのゲームみたいにHPとかが画面の固定された位置に表示されている新タイプのUIも作ります。

長丁場になるんで、まずは流し読みして、ジワジワと進んでいくといいです。

  • ボタンを押すとゲームスタート
  • Playerはトゲに当たるとダメージを受け、HP0になるとスタート地点に戻される
  • をとると、Playerはスピードアップする
  • ワールドにあるボールを全部とるとクリア。ボールを取るのは誰でもいい(複数人プレイ対応)。
    ゲームの中身は↑って感じです。

なお、この記事を書いたのは12/5で、動画に使っている12/14バージョンとはビミョーに中身が違うことをご了解ください。。。Kusuriの形とか、ボールを取ってもGetが出るとか……

まずはモノを作る

トゲ(Toge)、薬(Kusuri)、ボール(Boru)を用意します(ボタンは後で)。
Unity Asset Storeで何か無料のを探してくると良いでしょう。

ちなみに、モノを配置したときPrefabになっている(水色で表示される)なら、

これのTogeとか

UnpackPrefabCompletelyをして、PrefabではなくしておくとUnityからゴチャゴチャ言われることが減るので良いです。

右クリックでこれを選びます

ギミックとか付けたあとで、改めてPrefabにもどしますが。
あと、今回はあえて、どれもこれも日本語っぽい名前でいきます。
別にそれでも問題ないということを見せたかったので。

トリガー・ギミック・Logicをつけていく


つけるモノはこんな感じ。

SetGameObjectActiveGimmick とは

SetGameObjectActiveGimmickは、表示させたり消したりするギミック。
なお、このギミックはSignalではなくBoolのメッセージを送るというちょっと変わったスタイルになっています。
BoolでONを送れば表示される。OFFを送れば消える。

だから、OnCollideItemTriggerから送られているKusiriHyojiBoruHyojiTogeHyojiBoolになっているわけです。

こういう風に、Signalではないメッセージを送れるギミックは地味にあったりします。

コライダーとか

さて、もしToge・Kusuri・BoruBoxColliderとかのコライダー(当たり判定)が付いていなかったら付けましょう。
そうしないと、OnCollideItemTriggerが発動しませんからね。
このとき、MeshColliderは重いのでオススメできません。Box(箱)かSphere(球)かCapsule(カプセル型)で十分です。

コライダーのサイズは適当に調整しましょう。
「1人称視点」でプレイしている場合、かなり近づいたつもりでもアイテムに当たらないことがあるのでいくらかサイズを大きくしたほうがいいかもしれません。

そして、RigidBodyからUseGravityをOFFに。
コライダーのIsTriggerをONにします。

今のclusterだと……

今のclusterだと、IsTriggerがOFFのオブジェクトがPlayerに当たってもUnity上だとトリガーが発動してくれないっぽいのです……
clusterにアップロードしてプレイすると大丈夫なんですけどね。

Globalから呼ばれるItemLogic!

さて、Kusuri・BoruにはItemLogicがついてます。これは前回もありましたが……
今回はTargetGlobalになってます!


再掲。Globalは初めてですね

やりたいことは、「ゲーム開始時に全てのクスリとボールとトゲを表示させる」です。
これがどうやって呼ばれるのかは、また後で説明します。

GlobalLogicを付けるんじゃないことに注意してください!
あくまでItemLogicで、TargetGlobalにするんです。

アイテムをPrefabにする

さて、Toge・Kusuri・BoruをPrefabにしましょう。
Prefabにするやり方は、[cluster公式の的当てゲーム]((https://creator.cluster.mu/2020/06/11/howto_shootinggame/)の弾と全く変わりません。

その後で、ワールドに好きなようにコピペしてステージを作ってみましょう。
ただ、Boruの数は10個にしておいてください。

こんな感じにしました

なお、変なアイコンがアイテムについていて見づらい場合は、上のほうにあるGizmosボタンをクリックするとスッキリして見やすいかもしれません。

Prefabにしなくても、普通に動くことは動きます。
ただ、例えば「Kusuriのアイテムにミスがあった!」ってなったとき、Prefabにしていないと全部のKusuriを修正・配置し直すことになってしまいます……
でもPrefabにしておけば、Assetsの中のKusuriをいじるだけで配置したKusuri全部が修正できます。

そして、アイテムを非表示に!

配置が済んだら、ぜんぶアイテムを非表示にしてしまいます!
ゲーム開始ボタンを押したら、それが全部表示されるという仕組みにするからです。

こんな風に

ボタンを作る

次はゲーム開始のボタンを作ります。今回はCylinder(円柱)を太め・低めの形にしただけです。
これはワールド内に1つだけなんで、Prefabにする必要はありません


中身はこんな感じ!
クリックするとゲーム開始のメッセージを送り、ボタン自体は非表示にします(で、ゲームが終わったらまた表示)。

Kanri系のオブジェクトを作る

つづいて、Kanri系のオブジェクトを作ります。
これは、Logicとかだけ付けたEmptyObject(カラッポのオブジェクト)です。

こうやってメニューから作ればOK

GemuKanriを作る

まずはGemuKanri。ゲーム開始時、終了時の処理を担当します。
あまり大したことはしてないですが。


中身はこんな風になっています。
ゲーム全体を管理するんで、GlobalLogicばかりついていますね。

これまでのようにItemごとに変数とかを保存するんじゃなく、Globalというゲーム全体を仕切っているトコに変数を保存したりメッセージを送受信したりします。

もちろん、GemuKanriという名前はテキトーなんで、どういう名前でもいいです。
英語ならGameManagerとかすることが多いですかね。

PlayerKanriを作る

つぎはPlayerKanriです。
ここにはPlayerLogicPlayerTimerを書きます!
初めてですね。
作り方はGemuKanriと全く同じ、EmptyObjectを作ってLogicとかをつけていきます。


中身はこんな感じ。
さらに、ちょっと長すぎるのでクスリに関する処理は分けてPlayerKanri2を作りました。

PlayerLogicを使っているので、Playerごとに保存されたHPや速さを使って色々できるわけです。
OnJoinPlayerTriggerは、プレイヤーがワールドに入ったときに呼ばれるトリガーです。すでにゲームが始まった後に誰かが入ってくるとその人のHPや速さの初期化がされないので、このトリガーも入れました。

最初はPlayerLogicってどこに書けばいいの? って思うかもしれませんが、適当なEmptyObjectを作り、ソコにつけておけば問題ありません。

OtoKanriを作る

さて、音についても管理しましょう。
といっても、OtoKanriはゲームスタート・終了のLogicが入っているだけのEmptyObject
その子もEmptyObjectで、AudioSourcePlayAudioSourceGimmickのセットが5つ入っているだけですが。

こんな構造

ならす音もAudioSourceから適当に選んでおきましょう。
Togeなら痛そうな音、KusuriBoruなら嬉しそうな音がいいですね。
BGMOtoだけ、AudioSourceのLoopをONに。ParameterTypeBoolにしときましょう(再生・停止ができるようになります)。

あと、AudioSourcePlayOnAwakeがONだとゲーム開始直後に音がなっちゃうのでOFFにしておきましょう。

それから実は、PlayAudioSourceGimmickはItemがなくても付けられるんです。
テンプレートワールド「シューター」ではじめて知りました……

PlayerLocalUIを作る

今回の本題ですかね?
つい最近clusterに加わったばかりのPlayerLocalUIを作ります。
これまでのようにワールド内にLVとかHPバーが表示されているんじゃなくて、フツーのゲームみたいに「常に画面の左上にHPが表示」とかできる奴ですね。

ベースの作り方


まず、ヒエラルキーで右クリックして「UI」「PlayerLocalUI cluster」を選びます。


すると、こうなります
↑のようにPlayerLocalUIというのができるんですが、その子にSafeAreaというのもできます。

このSafeAreaの子に、UIを付け加えていってください!

そうじゃないと、スマホとかVRとか、環境によってはUIが画面からハミでちゃいます!

テキストをつけていく

SafeAreaを右クリックし、「UI」「Text」を選んでテキストを追加します。


HPとボールと速さについて、それぞれこんな風に設定

SetTextGimmickTargetLocalPlayerがあるのが新しいトコですね。
ただBoruSuujiGlobalなので注意。

画像をつけていく

同じように、SafeAreaを右クリックし、「UI」「Image」を選んで画像を追加します。
今回はトゲに当たったときの画像、アイテムを取ったときの「Get!」という画像を追加しています。


なおUIの画像は、Unityに読み込んだ後、↑のように「Sprite(2D and UI)」にする必要があるので気をつけて!


設定はこんな風になってます。
で、これもTogeとかと同じく非表示にしておきます。ゲーム開始時にダメージとかGetとかの画像が出てたらおかしいですからね。

SafeAreaの設定

ひととおり設定したら、SafeAreaをクリックし、「Anchor自動設定」ボタンを押します。
コレでUIの位置をいい感じに調整してくれる……はずです。

UIの位置をいじった後はもっかい「Anchor自動設定」ボタンを押したほうがいいです。

じゃあ、動かしてみよう

これで↓のように動く……はずです。

ですが、やっぱりトリガー・ギミック・ロジックとかのつけ忘れ、Keyの書き間違え、そしてすっごく多いParameterTypeとかTargetの設定ミスなどなどでヘンな動きになることも多い。

Signalじゃないとダメなところ。逆にSignalだとダメなところ。
Thisじゃないとダメなところ。Globalじゃないとダメなところ。などなど……
よーく見てチェックしていってみてください!

1つずつバグをつぶしていきましょう。

そもそもどういう流れなの?

今回はやることがすごく多かったんで、流れが後回しになってました。
全体の流れはこういう感じです。

ゲーム開始ボタンを押したとき

GlobalGemuKaisiメッセージが送られます。
ボタンが非表示になります。

GameKaisiが送られると
Toge・Kusuri・Boruが全部表示されます。
PlayerのHPや速さが初期値に戻ります。これはワールド内にいる全てのPlayerに発生します。(また、誰かが途中でワールドに入ってきたときもこれは行われます)
GlobalBoruKazuが10になります。
BGMがなり始めます。

Togeに当たったとき

そのPlayerのTogeMutekiがOFFなら、GlobalTogeButuメッセージが送られます。

TogeButuが送られると
痛そうな音がなります。
PlayerのHPが1減ります。TogeMutekiがONになります。これは1秒後にOFFになります。
tiという画像がしばらく表示されます。TogeMutekiがOFFになると消えます。
HPが0になったらSinuTaimaメッセージが送られます。
SinuTaimaが送られると(その0.3秒後に)
そのPlayerが初期位置にワープします。
ダメっぽい音がなります。
そのとき、PlayerのHPを3に戻します。

Kusuriに当たったとき

GlobalKusuriButuメッセージが送られます。
クスリは非表示になります。

TogeButuが送られると
いい感じの音がなります。
クスリを取ったという画像がしばらく表示されます。
PlayerのHayasaが+1され、実際にスピードが速くなります。

Boruに当たったとき

GlobalBoruButuメッセージが送られます。
ボールは非表示になります。
(この記事の終わりにあるオマケを実装すると)エフェクトが出ます。

BoruButuが送られると
楽しそうな音がなります。
GlobalBoruKazuが-1されます。
もしBoruKazuが0以下になると、GlobalGemuOwariメッセージが送られます。
GemuOwariが送られると
BGMが止まります。
クリアしたっぽい音がなります。
Togeが全部消えます。
ボタンが再び表示されます。

その他の知識

その他の知識として……

Player関係やGlobal(Logic)について他に知っておくべきこと

よく混乱するんですが、
GlobalのメッセージをItemが受けて、そのItemに変数とか保存したい」ならItemLogicを使い、TargetGlobalにします。
↑のときはGlobalLogicは使えません。

  • PlayerLogicからItemやGlobalに何かメッセージを送ることは今のところできないようです。
  • ItemLogicからGlobalに何かメッセージを送ることは今のところできないようです。

この辺の制限で、地味にできないことがあります。

オマケ・エフェクトをつける

ちょっと長い上にしょぼいエフェクトなのでオマケに。

「GameObject」「Effects」「ParticleSystem」でパーティクルを作ります。


パラメータはこんな風

ポイント
DurationとStart LifeTimeは0.5くらいに
Start Speedはいくらか速く
Loopingさせない(重要)
Stop ActionをDestroyに(重要)
EmissionはRate over Timeを0にして BurstsのほうでCount30~50くらいにする
ShapeのShapeをSphereにして、Radius Radius Thicknessを0に(実際にはRadiusは0.0001とかになります)
Limit Velocity over LifetimeのSpeedを1くらいに、Dampenを0.1くらいに

で、Itemコンポーネントをくっつけて、Prefabにします。
そのPrefabを、BoruにつけたCreateItemGimmickから呼べばOKです。

まあ、Unity Asset Storeとかでエフェクト探したほうがいいとは思いますが。

これであなたもLogic初心者を脱出!

さあ、長らく書いてきましたが、これくらいのモノが作れればあなたもLogic初心者脱出と言っていいでしょう!
冬のGameJamとかにも参加して、じゃんじゃんゲームワールドを作っちゃってください!

最後まで読んでくれてありがとうございました!!