ClusterCreatorKitのトリガーギミックチョット分かる

この記事は
[1月のお題企画「記事求ム！クリエイターキットライターズ」｜バーチャルSNS cluster \(クラスター）｜note](https://note.com/cluster_official/n/nf0c0fe5ec0e9)
のお題記事です。

# ClusterCreatorKit
バーチャルSNS Clusterでワールドを作ったりゲームを作ったり、あるいはアイテムを作ったりできるSDKです。
詳しくは [Cluster Creators Guide – バーチャルワールドをつくろう！](https://creator.cluster.mu/) 見てみてください

# トリガーギミック（＋オペレーション）
Clusterでは、通常のユーザスクリプト（.cs）は使うことが出来ません。
なので、何か「仕組み」的なものを作りたい場合、ClusterCreatorKitで用意されている

- アイテム
- トリガー
- ギミック
- オペレーション

の組み合わせで実現する必要があります。
いわゆるノンコーディングというやつですが、チョイチョイ罠があったりして、よくわからないという声をGAMEJAM中にも多く見かけたので、入門解説的に説明してみようと思います。

なるべく誰にでも分かるように書きますが、プログラマ寄りの目線なので、プログラムっぽくなるのはご容赦を。

なお、著者の理解の範囲で書いていますので、間違ってるよ！とかあればガンガン突っ込んでください:yum:

# Item

基本中の基本。
Clusterで何かしらの仕組みを持つものは基本的に「Item」である必要があります。
とはいえ、TriggerとかGimmickを付ければ、勝手に付いてくるのであんまり意識する必要は無い……のですが、
**Itemは親子関係を持てない** 超重要。
**Itemは親子関係を持てない** 重要なことなので二回言った。
つまり、親子関係のあるItem間で何か作用させる、という仕組みは実現できないので、別の方法を探す必要があります。
なんか2つ以上連動させたいなー、ってときは親のGameObjectで包むか、Constraintとか使って兄弟的に扱うのが定番っぽい。
（どちらもUnityの標準の機能です）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/92dbf9b9-b138-3019-25a2-163e287b9162.png)

# Trigger/Gimmick
これは基本的にセットで考えましょう。
イベントを発火するのがTrigger、実際に動作するのがGimmickです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/dc96921d-7221-e225-abf5-f8862172916c.png)
TriggerとGimmickは同じアイテム内に同居することもあるので、紛らわしいのですが、
Triggerはテレビのリモコン、Gimmickはテレビと考えるとわかりやすいかと。
つまり、リモコンは信号を出すだけで、実際に仕事をするのは、テレビ本体ということです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/a3e151e1-11e8-2abf-e272-623723f095bd.png)


## Key
多分、CCK入門者が最初に躓くところ。
Keyって何？？？Itemの名前？？？え、違うの？？？？
プログラム寄りの素養を持っている方ほど混乱しやすい気がします。

CCKではすべてのやり取りがMessageで処理されており、その識別子がKey、つまりこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/a0ebbbd7-b88d-a353-12d7-e747c1edf0ed.png)

これでもまだ直感的ではないので、**Keyは関数名**という理解がわかりやすいのでは？と思います。
つまり、こう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/f2aa9c24-d4bf-20ac-71c6-eca4b2941808.png)
ギミックを付ける＝機能を付ける＝関数を生やす、というのはわりとしっくり来るのではないかな？と。

例えば、[的あてゲームの作り方 – Cluster Creators Guide](https://creator.cluster.mu/2020/06/11/howto_shootinggame/)で説明されている仕組みはこんな感じです。
（単純化のために一部削ってあります）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/60a1f523-2a99-81f1-0c89-0be0365f28c3.png)
単純に考えると、弾を前に進ませるのは銃では？？みたいになるのですが、
現実の中でも薬莢を叩くまでが銃で、弾は勝手に爆発して飛んでいきます。
あるいは、魔法的に考えても、前に進むのは魔法の機能でしょう。

## Target
CCK入門者が最初に躓くところ第二弾。
TargetってItemじゃないの？？よく分からん。Globalにしちゃえ。Keyが混線してうわわあぁぁぁぁぁ！！！

Targetはトリガーとギミックのスコープ（範囲）です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/b205cb7f-6bfb-9500-5139-8671f7d23f65.png)

バランス感覚のいい鳩…ではなく、ロボットに持たれている**「Zone」に着目**します。
何故ならば、**Triggerをコントロールできるのは、Itemだけ**だからです。

Zone自身は**This**です
Zoneを持っているロボットは**LocalPlayer（Owner）**です。
他のプレイヤーは**Player**です。
どのプレイヤー？というのは**CollidedItemOrPlayer**などで指定（検出）する必要があります。
自分自身以外のアイテムは**Item(SpecifiedItem）**です。
どのアイテム？という部分は**CollidedItemOrPlayer**またはPrefab化の時点で指定する必要があります。
上記すべてを包含する、ワールド全体が**Global**です。

スコープ、と表現したのは、**TriggerとGimmickでスコープを一致させる必要がある**ためです。
**This**で発火されたトリガーは**This**で拾われる必要があり、
**Item**で受けるトリガーは**SpecifiedItem**で発火する必要があります。
逆に言えば、スコープが一致していなければ拾われないので、**This.hit**と**Owner.hit**は混線しません。
ややこしくなるから使わないけどね！！！！

## Parameter Type
最初はSignalで困らないけど、ちょっと複雑にしようとすると詰まるところ。
関数の引数型です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/3b0abc44-7623-e98d-f6ad-0d499c9795e7.png)
当然、トリガーとギミックで型が一致していないと、死にます。
コンパイルエラーも動作エラーも出してくれないので、混乱して苦しむことが多いですが、そのへんは動的メッセージングでやりとりしているCCKの仕様上、仕方ないですね。。。

各ギミックの詳細ページに、使える引数と動作が書いてあるので、それを見て決めましょう。
[ギミック \- Cluster Creator Kit ドキュメント](https://clustervr.gitbook.io/creatorkit/game/gimmick)

基本的かつ、最初のうち忘れがちなのは、**Parameter Typeの指定はギミック側にある**、ということです。
Target（スコープ）もParameter Type（引数型）も、呼び出し先のギミック（関数）である程度決まっているので、
逆算的にトリガーの設定を作ることになります。
まあつまりはギミック＝インタフェースオーバーライド関数なわけですな。

## Gimmickの対象
**Clusterで何かしらの仕組みを持つものは基本的に「Item」である必要があります**と最初の方で書きましたが、これ実は嘘です。
代表的なところでは**Set Game Object Active Gimmick**（オブジェクトをアクティブ化する）は**GameObject**（Unityの基本型）であれば何でも付けられます。
まあ、実際にはActive化じゃなくてCreateしたいケースの方が圧倒的に多く、CreateするにはItemじゃないと…となって発狂するのですが。:scream:

# オペレーション（ロジック）
ハロクラなどで長らくロジックと呼ばれていたため、未だになかなか本名で呼んでもらえない子。
トリガーを発火するギミック、あるいはギミックの付いたトリガー。
タイマー（一定時間待ってから発火）とかLottely（くじ引き発火）とかですね。
なお、（本来の）Logicさんはラスボスすぎるので余白が足りない。。。（理解も足りない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/53189827-1e16-6a01-3931-3b5ae50ef5de.png)

# まとめ
なるべくイメージとして覚えやすいように図解しつつ、自分の中でも整理してみました！
書いてて思ったのですが、トリガー／ギミックではなく**ギミック**（本体）**／トリガー**（発動ポイント）と表現する方がいいのでは？と思いました。ギミックの無いトリガーはただの信号発生器なので。
ギミックはイメージ付いてるので後で～、などとやっていると、GAMEJAM終盤で死ぬことになりますし。:expressionless:

というわけで、トリガーギミックチョット分かる、でした。
モット分かる、色々工夫する記事は、つよつよクリエイターさんに期待します。
よいクラスターライフを！
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>

# おまけ：Collider
ゲーム的目線でCCKで何かしら作ろうと思った場合、意外とハマりがちなCollider

- 理由１：CCKのバグで、Unity上ではColliderが発火しないことが多い
- 理由２：Colliderがシビアすぎると持ったりぶつけたりといった操作がスカって辛い

どちらも、物理コライダーと衝突判定コライダーを別々に作っておくとよいです。
衝突判定の方は**isTrigger=True**にしておくのが**超重要**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570991/48413792-3686-7acc-f570-15432304e847.png)

# おまけ2：Animatorを活用しよう
Animatorというと「アニメーションを操作するもの」と思いがちですが、Unityにおけるアニメーターは、**エディタ上で操作できるものであれば大抵のものが操作できます**。
例えば、重力の強さを変えるとか、一部のアイテムの表示切り替えなどなど。
そして、**Set Animator Value Gimmick**を組み合わせれば、条件分岐などにも対応可能です。
中途入室では同期がズレるなどの問題もありますが、短時間のアクションや効果であれば、かなり選択肢が広がります。
もちろん、Animatorの知識は必要になりますが、UnityのAnimator解説記事は世の中に大量にありますので、ちょっと頑張ってみるのは、ありなのではないでしょうか？