> For the complete documentation index, see [llms.txt](/llms.txt)

# UI Kit を使ってテキストチャットを実装

もう少し高度なチュートリアルにも挑戦してみましょう



## UI 構成

![img.png](img.png)

まずシーンの全体像をお見せします。

画面上部にメッセージリスト、下部にテキスト入力フィールドと送信ボタンを配置しています。

## コンテキスト

![img_1.png](img_1.png)

Context の配置について解説します。

A は GS2-Chat のルームコンテキストです。

B は GS2-Chat のメッセージリストコンテキストです。

C は GS2-Chat のメッセージコンテキストです。

## 実装解説

### メッセージ一覧の取得

![img_11.png](img_11.png) ![img_12.png](img_12.png)

ルームコンテキスト には事前に GS2-Chat で作成しておいたルームの情報を設定しています。

![img_2.png](img_2.png) ![img_3.png](img_3.png)

メッセージリストコンテキストには、2つのコンポーネントをつけてあります。

Gs2ChatMessageListFetcher はルームコンテキストで指定されたルーム内のメッセージの一覧を取得します。

Gs2ChatMessageList は Fetcher が取得したデータに基づいて、GameObject を作成します。
Maximum Items はリスト内の要素を生成する最大数です。

起動時に Maximum Items の数だけ Prefab として指定した GameObject を複製してインスタンス化します。
リストアイテムの増減にあわせてインスタンス化しなおすのはコストが高いため、事前に全ての GameObject をインスタンス化し、不要なものは非表示にします。

{{% cardpane %}}


![img_4.png](img_4.png)

大量にインスタンス化された Message ノード。


{{% /cardpane %}}

Prefab には メッセージコンテキスト を持つ GameObject を指定することができ、表示する際にはかならず Fetcher から取得したメッセージのうち1つが設定されます。

{{% cardpane %}}


![img_5.png](img_5.png) ![img_6.png](img_6.png)

インスタンス化した Message に割り当てられた メッセージコンテキスト の状態。


{{% /cardpane %}}

### メッセージの表示

![img_8.png](img_8.png) ![img_9.png](img_9.png)

メッセージコンテキストには3つのコンポーネントを付けています。

Gs2ChatMessageContext には Message を指定していません。これは Gs2ChatMessageList によって値が設定されることを想定しているためです。

Gs2ChatMessageFetcher は Gs2ChatMessageContext に指定されたメッセージの情報を取得し、保持します。

Gs2ChatMessageEnabler は Gs2ChatMessageFetcher が値の取得を完了したら Text ノードを有効化するように設定しています。

![img_10.png](img_10.png)

Text には Gs2ChatMessageLabel を指定し、Message の metadata の内容をテキストに反映するように設定しています。

### メッセージを投稿

メッセージの投稿を行うには GS2-Chat の Post API を呼び出す必要があります。

![img_15.png](img_15.png)

UI Kit には、Post を実行するための Prefab である Gs2ChatMessagePostAction が用意されています。
この Prefab は有効化されるとAPIが呼び出されるため、初期状態で無効化しておきます。

![img_16.png](img_16.png)

投稿するメッセージには2つのパラメーターを設定できます。

| 名前 | 説明 |
| --- | --- |
| Category | メッセージの種類 |
| Metadata | メッセージの本文 |

Category には任意の数字を指定でき、「0」はテキストメッセージ「1」はステッカー のようにカテゴライズし、Metadata の読み込み方法を決定する情報とすることができます。
Metadata はメッセージの本文です。

今回のサンプルでは Category は 0 のみを使用し、Metadata には生の文字列を指定することにします。

成功時には OnPostComplete が呼び出され、自分自身の GameObject を無効化し、InputField の入力内容を空に初期化しています。

![img_13.png](img_13.png) ![img_14.png](img_14.png)

InputField で OnValueChanged で入力フィールドの値の変更をハンドリングして、Gs2ChatMessagePostAction の Metadata に値を設定しています。

![img_17.png](img_17.png) ![img_18.png](img_18.png)

送信ボタンの OnClick イベントで Gs2ChatMessagePostAction Prefab を有効化しています。

## 動作確認

![img_19.png](img_19.png)

（事前に動作確認したことで3件のメッセージが存在します）
ddd と入力し、送信ボタンを押します。

![img_20.png](img_20.png)

メッセージリストに ddd が追加され、InputField が初期化されます。

## 最後に

UI Kit の `宣言的プログラミング` の面白さが伝わったでしょうか？

メッセージの送信処理をした後、メッセージ一覧を取り直すような処理をわざわざ記述しなくても
コンポーネントとして「メッセージ一覧を表示する」「メッセージの metadata の内容をテキストに反映する」という設定をするだけで挙動を制御できます。




