👓

【cluster】Logic使ったゲームワールドを作ろう 本編

2020/12/04に公開

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

(※この記事は「本編」です。トリガー・ギミックもまだちょっと怪しい……とか、シッカリ準備してから読みたい、って人は「準備編」からどうぞ~)


銃の連射速度を制限する例

準備編からの流れで……
Logicを使って、連射速度が制限された銃を作ってみます。

準備編にも動画を載せましたが、こんな感じの銃です。

連射すると音はたくさん鳴りますが、弾は0.5秒に1回しか出ません

銃はこんな感じ

いきなり見ても???となるかもしれませんが、

とりあえずメインになる銃は↑の感じです。

トリガー・ギミックを知ってたら分かるとこをまず見ていきましょう。

名前 何をするか
Audio Source 撃ったときの音を指定
Item clusterのアイテムに必ずつけるもの
Movable Item しかも、動くアイテムだ
Grabbable Item しかも、持てるアイテムだ
Use Item Trigger 「使う」ボタンを押すとOnUseメッセージを自分(This)に送る
Play Audio Source Gimmick OnUseメッセージが来ると音を鳴らす
ここまではトリガーとギミックを使える人ならわかるはず!

そしてこっからが本番!
Logicです


最終的にやりたい流れはこんなとこです

名前 何をするか
Item Logic OnUseメッセージが来たとき、FireWaitFlagがOFFならFireExecメッセージを送る。その後で、FireWaitFlagをONにする
Item Timer FireExecメッセージが来たら、0.5秒後にFireWaitFlagをOFFにする
Create Item Gimmick FireExecメッセージが来たら、弾を出す


???

初見の人はぜんぜんわからないかもしれませんが、1つずつ説明していきます。

Logicの流れを見てみよう

まず、まさに「Logic」の名前がついたItemLogic

その部分だけ抜き出した画像がコレです。


なんじゃこりゃ

まあ、そう言わずに1つずつ見ていきましょう。

※自分でUnity動かしながら読んでいる人へ


ItemLogic は最初つけたとき、こんな見た目です。
この記事の画像とぜんぜん違うじゃん! って思うかもしれませんが、「+」のボタンを押すと下に伸びて、同じ感じになりますよ~

キホンの部分

まず一番上のほう……
KeyにOnUseと書いてある。
なので、ワールド内で銃のボタンを押してUseItemTriggerからOnUseメッセージを受け取るとLogicが動き始めます。

Logicの中でなにしてる?

で、何をするか。
「連打しても、0.5秒に1回しか弾が出ない」ってのをやりたかったわけです。
そこでFireWaitFlagという「変数」を作ります!

FireWaitFlagBoolの変数。
Boolの変数には、ONとOFFを入れることができます。

これがONになっているときは弾を出さないようにする。
そして、0.5秒たったら自動でOFFになるようにしていきます!

変数を作るってどうすればいいの?

さて、変数を作ると言ったのはいいですが。

変数なんてclusterのページにのってたっけ

そう。実は「変数」というのは、Cluster Creator Kit ドキュメントの中には出てきません……
あくまで「メッセージ」という名前しか出てこないのです。

Signalではない、BoolIntegerFloatのメッセージを送れば、そのデータは自動で保存されます。そのワールドを出るまで残ります
それがプログラミングの「変数」みたいなので、私が勝手に「変数」と呼んでいるだけです。


勝手に呼ぶな

……ですが、

  • 「ボタン押したよ! Signalのメッセージ送ったよ!」
  • 「受け取ったから弾出したよ!」
  • 「よし、Signalのメッセージは処理おわったから捨てるね!」

……っていう普通の「メッセージ」と、HPとかMPとかのデータを保存するものが同じ名前だとすごく分かりにくいんです……

なので、この記事では「変数」と呼ぶことにします。。。
HPやMPを保存したり、フラグを保存したりできるイイやつです!

じゃあ、改めてLogic見てみよう


というわけで、改めてLogicのとこの画像です。
赤い文字で書いてあるとこを見てください。

一番上、FireExecと書いてあります。
その下は、=Equals(イコール)。

FireExecのメッセージは毎回送られるとは限りません。
ここのLogicでは、=Equalsが選ばれているからです。
その下に書いてある「条件」がOKのときだけ、メッセージが送られます!

では、「条件」はどうなっているか?

  • RoomState This」の「FireWaitFlag
  • Constant Bool」の「OFF」(チェックが入っていないから!)
    これがイコール、同じときにOKと判定されます。

    ………

まあ、ここも1つずつ見ていきましょう。
やりたいことは、FireWaitFlagがOFFのときだけFireExecメッセージを送る、です。
(んで、FireExecメッセージが来たらCreateItemGimmickで弾を出すわけですね)

条件の書き方

まず、「変数」を見たいときはRoomStateを選びます。
:::message:::
なんでRoomStateって名前になったのかちょっと謎ですが、とりあえず選んでください……
:::

で、今回は銃にデータを保存するので、Thisを選びます。
そして「FireWaitFlag」と記入!
これが「変数」の名前になります。

そして、今回は「OFFかどうか?」をチェックしたいので……
ConstantBoolを選び、チェックボックスはOFFにします。


つまりどーいうことだ

FireWaitFlag」が「OFF」と「=Equals(イコール)」。
つまり、「FireWaitFlagがオフかどうか?」ってことです!

これがOK(FireWaitFlagがOFFだ!)のときだけ、FireExecメッセージを送ってくれるようになります。
↓にまた同じ画像が出てきているので、確認してみてください。

まだまだ続くよLogic


さて、その次の部分(青い文字のとこです)。

今度はFireWaitFlagが指定されてて、その右はBool
次のとこに「=」が選ばれてますね。
そして、「Constant Bool」でチェックボックスがONになってます。
これは……FireWaitFlagをONにしろ、という意味になります!

=Equals」と「=」はパッと見に「同じじゃね?」と思ってしまいそうなんですが、実はゼンゼンちがう

=」は、その下にある値をそのまま送れ! って意味です。
今回の場合、「Constant Bool」でONが指定されているので、この「ON」という値をそのままFireWaitFlagの中に入れてくれます。

そして重大な注意ポイント!

FireWaitFlagの右のほうが、SignalじゃなくてBoolなんです!
ON/OFFが設定できるBoolの値を入れたいので、Boolを指定するんです!

Constant Bool」のほうにBoolあるのにもっかい指定すんの? と思うかもしれませんが、そうです! 2カ所で指定してください!

よくわからない人は、「変数に値を入れたいときはSignal以外で!」と覚えましょう!

このLogicで、何が起きるか?

で……、こうすると結局なにが起きるんでしょうか?

変数は初期状態だとは0とかOFF(False)とかが入っています。
なのでFireWaitFlagも、最初はOFFになってます。

  1. さて、銃のボタンが押されました! OnUseメッセージが発動し、ItemLogicが呼び出されます!
  2. FireWaitFlagはOFFです、だからFireExecメッセージが発動します!
  3. その後で、FireWaitFlagがONになります。


これの水色の部分ができました!

その後、何が起きるのか?

ItemLogicさんによるキビシイ(?)チェックを通り、FireExecメッセージが無事発動しました。
こっからどうなるでしょう。

フツーに弾を出す

まずCreateItemGimmickが呼ばれて、弾が出る部分はcluster公式の的当てゲームを作る記事と何も変わりませんね。

やっていることは「的当てゲーム」と全く同じ

Timerを使う

一方、ItemTimerのほうはまだ使ったことがないという人もいるかもしれません。
でもそんなにムズカシイもんじゃないです。
指定した時間だけ待ってから、メッセージを送ったり変数を設定したりできるもんです。

今回はこんな感じです

TargetとKeyは弾を出すギミックと同じ。
なので、このItemTimerFireExecメッセージが発動したときに呼ばれます。
で、Delay Time Secondsで何秒遅らせるか指定してます。今回は0.5秒ですね。

そしてTriggersで、0.5秒後にやりたいことを書いていきます!

Triggers部分
今回やりたいことは1つなのでSizeは1。
Targetは、Item Timerの場合Thisで固定です。
そしてKeyFireWaitFlagを指定。
ParameterTypeBoolFireWaitFlagはONとOFFだけ入れたい変数だからですね。
そしてBool Valueと書いてあるチェックボックスはOFFにしておく。

これで、「0.5秒後にFireWaitFlagをOFFにしろ!」という意味になります!


ついにこれで、全部できました!


これだけやって、まだ連射制限するだけか……

まあ、丁寧に説明しすぎたかもしれません。。。
これを出発点に、Logicで色々できるようになりますよ!

ほかに、Timerで知っておくと良いこと

  • 待ち時間以内(今回なら0.5秒以内)にまたFireExecが来るとタイマーは0秒から数え直しになります。今回は弾を出した後はFireExecが発動しないようにItemLogicを書いてあるから問題ないですが、Timerが短い時間で何度も呼ばれるようにするといつまで経っても何も起きません。
  • カン違いしがちなのですが、「Timer発動→○秒経過→何か起きる」は自動でループしません。「1秒たったら弾を出す→また1秒たったら弾を出す→また1秒たったら……」みたいのをやりたい場合は、TriggersSizeを2以上にして、ItemTimerを再発動させると良いでしょう。
  • Triggersで変数の値を設定するのではなく、Signalのメッセージをどっかに送って弾を出すとか音を出すとかしても全然OKです(というかそっちのがメイン?)

これだけじゃ物足りない! という人へ

  • LogicにたくさんあるLessThanとかSubtractとかみたいのがなんかわかんない
  • Logicって、ItemだけじゃなくてGlobalPlayerもあるけどそっちは?
  • 最近できた、新しいUIでHPやMPの表示とかしたいんだけど!

……と、そんな人向けに「【cluster】Logic使ったゲームワールドを作ろう パターン編」も書きました。

止まらず前へ

ただし、「準備編」「本編」ほど細かく丁寧には書いてないです。。。

あと、オマケ知識

オペレーションとは

Timerは、Logicと一緒にまとめて「オペレーション」という名前でセットにされてます。
ちなみにLotteryってのも「オペレーション」です。
Logic Timer Lotteryのオペレーション3兄弟。

でも、特にTimerはLogicとやることが結構ちがうし、LogicよりTimerのほうが直感的に理解しやすいので「TimerはTimer」として別におぼえたほうがスムーズなような気がしてます。

Discussion