Unity2018.xで知っておきたい「ECS」の概要

# 最初に

この記事はUnity2018.xで目玉機能とされている「ECS」に関しての概要記事となっております。実践的な記事はまた別途用意できたらと思います。

# ECSとは？

**`Entity Component System`**の略称です。Unityにおいてのこれまでのコンポーネント指向(`MonoBehaviour`)とは異なる新しいアーキテクチャとなります。オブジェクトとデータと処理を分割して、**効率の良いメモリ配置を実現する**ことでターゲットとするCPUに対して高レベルなチューニングを行えます(これによってプリフェッチも可能)。ECSとJob Systemを組み合わせることで並列処理となり、膨大な数のゲームオブジェクトを生成/破棄を行なっても問題なく動くほどに高速化されます。

ECSは以前記事でも紹介した**C# Job SystemとBurst Compilerと組み合わせることで、劇的なパフォーマンス改善**が期待できます。

- [Unity2018.xで知っておきたいC# Job System機能の概要](https://qiita.com/4_mio_11/items/39354a18425da7490b59)
- [Unity開発するにあたって知っておきたいコンパイラのすゝめ(Part3～Burst編～)](https://qiita.com/4_mio_11/items/cda0c8aa4c77a7748418)

具体的にMonoBehaviourから、ECSの書式に書き換えるためには、データだけが定義されているようなクラスを**IComponentData**を継承する**struct**(構造体)に置き換えるなどの必要があります。この辺はまた別の機会に…。

# コンポーネントとECSの違い

コンポーネントは画像のように、`GameObject`としてゲーム世界内で物体として存在することのできるオブジェクトの中に、そのオブジェクトの動作を定義する**部品**として組み込まれているTransformのようなものを指します。これらコンポーネントはそれぞれ、**フィールド、ロジック、他のコンポーネントへの紐付け**等が含まれています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/6fd05af0-d826-628f-4d8d-6296a845dfa2.png)

一方のECSについてですが、こちらはいくつか専門用語が登場するのでまずはそこから見ていきましょう。

## ECSの用語

|用語|概要|
|:--|:---|
|Entity|ゲーム世界においてGameObjectの超軽量版。ComponentDataを複数含む。|
|ComponentData|Entityに対して追加・削除が行える値型のデータ(構造体)。ロジックは含まれない。|
|ComponentSystem|Groupが一致するEntityに対して処理を実行する。|
|Group|ComponentSystemが全体からEntityをフィルタリングする際に条件として設定するComponentDataの組み合わせを指す。|

以下に補足説明を付け足します。

### Entity

EntityManagerからコストをかけずに生成できる**ゲーム世界のモノ**です。生成時にComponentDataを含めている状態が推奨されていますが、AddとRemoveは自由に行うことができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/f47d2354-1e3c-857b-0858-fa2342215fc9.png)


ComponentSystemが要求する**Groupと一致するComponentDataを保持している場合は、ComponentSystemによって処理が行われます**。

ただEntity同士はメッセージのやり取りができないとのことです。テラシュールブログさんでは以下のように書いてあります。

> 特定のEntityにメッセージを送りたい場合、Entityの持つComponentDataの中身を上書きし、Systemで上書きされたデータを判定する的な処理を実装します。`

少し考えて実装する必要がありそうですね。

### ComponentData

現在のUnityの仕組みで言うと、コンポーネントのフィールド群のようなものです。ロジックは含まれません。
IComponentDataを継承したstructがComponentDataとして扱うことができます。

### ComponentSystem

Group内に定義されているComponentDataを持つ**全てのEntity**を全体から効率よく検索し、**一括処理を行います**。ComponentSystemは処理を行うEntityが一つでもある状態であればActiveな状態となります。開発者自身の手でSystemから止めることもできます。

処理を行う際には要求した**コンポーネントの情報がComponentSystemに直接読み込まれます**。

### Group

ComponentDataの組み合わせのことを指します。例えばTransformとRigidbody言う二つのComponentDataを持つEntityをフィルタリングして処理を行わせたい場合は、この二つのComponentDataのことをGroupと呼びます。

## ECSについてまとめると？

①...ComponentDataを定義。Entityを作成。
②...ComponentSystemが定義したGroupにマッチするEntityを全体から検索。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/6a2733be-1de2-6edd-c870-1fbe066813d5.png)

③...フィルタリングしたEntityに対して一括処理（上記の図ならAとBに対して）。同じGroupを要求する処理が二つあるなら二つとも処理を行う。
④...②に戻って別のGroup検索を行う。

# 最後に

いかがでしたでしょうか。正直ECSはまだふわっとしか理解できてないので、次は実際に動かすところまで持っていって理解を深めようと思います。



# 参考

- [[GCC2018] Unity 2018は「カスタマイズ」で小さく速く多機能に](http://jp.gamesindustry.biz/article/1804/18040201/)
- [【Unity】Unity 2018のEntity Component System（通称ECS）について（１）](http://tsubakit1.hateblo.jp/entry/2018/03/25/180203)
- [Unity:C# JobSystemとBurstCompilerそしてECSこと(EntityComponentSystem)の概要](https://simplestar-tech.hatenablog.com/entry/2018/08/22/090034)
- [【GTMF2018TOKYO】ハードウェアの性能を活かす為の、Unityの新しい3つの機能](https://www.slideshare.net/UnityTechnologiesJapan/gtmf2018tokyounity3)