Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ECS初学者に向けてのTips集

mao
October 22, 2018

 ECS初学者に向けてのTips集

Unity ECS完全に理解した
登壇資料

https://connpass.com/event/101774/

mao

October 22, 2018
Tweet

More Decks by mao

Other Decks in Technology

Transcript

  1. 趣味でECSに関するQiita記事を書いてます。 ・ 【Unity】ECSで弾幕STGを作ってみたので技術周りについて解説 ・ 【Unity】ECS + JobSystemでライフゲームを実装してみた ・ 【Unity】PureECSの描画周りについて解説してみる ・

    【Unity】PureECSの衝突判定周りについて解説してみる ・ 【Unity】ECS + JobSystemで10万個のドカベンロゴをアニメーションさせてみた ※[Unity ECS]でググると何故か検索上位に出てくる。     但し最初に書いた記事の為に実装周りの情報が古いので注意。 その他にも「OculusGoで大量のオブジェクトを動かしてみた」 と言うECS + JobSystemをフル活用して OculusGoでドカベンロゴ2万個を60fps近くキープしつつ動かすと言うLTを話したりも。
  2. ▼ 今回話す内容 ・ ▽ ECS入門/復習 - ▼ 初学者向け おすすめ資料リンク集 -

    ▼ 既存のサンプルプロジェクトを動かす前の注意点 - ▼ 用語の整理から ・ ▽ どうやって描画するの? ・ ▽ アニメーションってどうするの? ・ ▽ 衝突判定ってどうするの? ・ ▽ その他Tips
  3. ▼ 初学者向け おすすめ資料リンク集 ・ 【GTMF2018TOKYO】ハードウェアの性能を活かす為の、Unityの新しい3つの機能 - https://www.slideshare.net/UnityTechnologiesJapan/gtmf2018tokyounity3 ・ 【Unity】Entity Component

    System入門(その1)【2018.2】 - https://qiita.com/pCYSl5EDgo/items/caac60ee41058cde085a ・ Unity:はじめてのECS - https://qiita.com/simplestar/items/17b0886be0170f79aa2e ・ EntityComponentSystemSamples/Documentation - https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/Documentation/index.md
  4. ▼ 用語の整理から ・ World - ComponentSystem(後述)の所属先 - インスタンスはWorld1つにつき1つずつ存在する - 現状だと「Default

    World」と言うのが自動で生成される - 存在する全てのComponentSystemを登録する。  (この仕様のおかげで良くも悪くもWorld/Systemの登録を意識せずとも動かすことができる。) - シンボルを定義することで自動生成を止めることも可能。 - 自分で作ることもできる。
  5. [Default World] // ▽ ComponentSystem // デフォルトで備わっているSystem L [TransformSytem] L

    [MeshInstanceRendererSystem] // 自前で実装したSystem L [PlayerInputeSystem](プレイヤー入力) L [GenerateSystem](Entityの生成周り) [Original World] // ▽ ComponentSystem // 自前で実装したSystem L [MyTransformSystem] L [MyRendererSystem] L [PlayerInputeSystem](プレイヤー入力) L [GenerateSystem](Entityの生成周り) ※上記のComponentSystemの並びは適当(実行順ではない)。名前も厳密に言うと少し違う。 ※Defaultについては他にも登録されるComponentSystemが幾つかあるが↑のは例なので割愛。 ・デフォルトで用意されているComponentSystemはオレンジ色表記 ・自作のComponentSystemは水色表記。
  6. ▼ 用語の整理から ・ Component System - Entity(後述)が持つComponentData(後述)を見て、 動作に必要なものが揃っていたら処理を行う部分。 - 例

    : TransformSystem EntityがPosition, Rotation, Scaleと言うComponentDataの内、 どれかを所持していたらLocalToWorldと言うモデル変換行列に値を纏める。 逆に言うと上記3点全て所持していない場合にはモデル変換行列は生成されない。 ※上記の緑色表記の物は全てデフォルトで定義されているComponentData
  7. 補足 : Entityの取得について Entity (Player) L Position/Rotation/Scale L LocalToWorld L

    MeshInstanceRenderer L PlayerData Entity (Enemy) L Position L LocalToWorld L MeshInstanceRenderer L EnemyData Entity (EnemyGenerator) L EnemyGenerateData TransformSystem 共通取得条件 : Position/Rotation/Scaleのどれかを持っていたら処理 →以下のEntityが処理される。 ・Entity(Player) : Position/Rotation/Scale ・Entity(Enemy) : Position
  8. 補足 : Entityの取得について Entity (Player) L Position/Rotation/Scale L LocalToWorld L

    MeshInstanceRenderer L PlayerData Entity (Enemy) L Position L LocalToWorld L MeshInstanceRenderer L EnemyData Entity (EnemyGenerator) L EnemyGenerateData TransformSystem 共通取得条件 : Position/Rotation/Scaleのどれかを持っていたら処理 →以下のEntityが処理される。 ・Entity(Player) : Position/Rotation/Scale ・Entity(Enemy) : Position RendererSystem 共通取得条件 : LocalToWorldとMeshInstRendererの両方を持っていたら処理 →以下のEntityが処理される。 ・Entity(Player) : LocalToWorld/MeshInstRenderer ・Entity(Enemy) : LocalToWorld/MeshInstRenderer
  9. 補足 : Entityの取得について Entity (Player) L Position/Rotation/Scale L LocalToWorld L

    MeshInstanceRenderer L PlayerData Entity (Enemy) L Position L LocalToWorld L MeshInstanceRenderer L EnemyData Entity (EnemyGenerator) L EnemyGenerateData TransformSystem 共通取得条件 : Position/Rotation/Scaleのどれかを持っていたら処理 →以下のEntityが処理される。 ・Entity(Player) : Position/Rotation/Scale ・Entity(Enemy) : Position RendererSystem 共通取得条件 : LocalToWorldとMeshInstRendererの両方を持っていたら処理 →以下のEntityが処理される。 ・Entity(Player) : LocalToWorld/MeshInstRenderer ・Entity(Enemy) : LocalToWorld/MeshInstRenderer EnemyGenerateSystem Entity(Generator)の取得条件 : EnemyGenerateDataを持っていたら処理 Entity(Enemy)の取得条件 : EnemyDataを持っていたら処理。 →以下のEntityが処理される。 ・Entity(EnemyGenerator) : EnemyGenerateData ・Entity(Enemy) : EnemyData
  10. ▼ 用語の整理から ・ Component Data - ComponentSystemが求めるデータ。 - MonoBehaviourのフィールドに相当(※) ・

    Entity - 実体。よくGameObjectに相当すると言われる。 - 但しEntity自体はただのIndexでしか無く、 フィールドに座標や体力と言った情報は一切持たない。
  11. ▼ 必要なComponentSystem Worldに以下のComponentSystemを登録 ・ EndFrameTransformSystem - デフォルトで用意されているTransform周りのComponentSystem - TrasnformSystemと言う物があるが、こちらは抽象クラス。 ・

    RenderingSystemBootstrap - デフォルトで用意されている描画周りのComponentSystem - 正確に言うとMeshInstanceRendererSystemと言う物となるが、 ↑を経由する事でCameraの設定などを良い感じにやってくれる。
  12. ・ EndFrameTransformSystem - EntityがPosition/Rotation/Scaleと言うComponentDataを持っていたら、 LocalToWorldと言うモデル変換行列に纏めてくれる。 - ※それ以外にも親子構造などの機能もあるが割愛。 ・ RenderingSystemBootstrap -

    EntityがMeshInstanceRenderer(後述)とLocalToWorldを持っていたら 描画情報とモデル変換行列を元にDrawMesh/Instancedで描画してくれる。 - 行列の参照の都合もあってか、EndFrameTransformSystemの後に実行される。 ▼ 必要なComponentData
  13. ・ MeshInstanceRendererSystemで   描画されるEntityの描画情報。  → Mesh, Materialなど ・ ISharedComponentDataを実装。  →

    簡単に説明すると共通情報向けの    ComponentData。    メモリ管理周りが少し違った覚え。 ・ [Serializable]属性が付いているので   Inspectorから値を設定可能。 ※補足 : MeshInstanceRenderer
  14. Entity L Position L Rotation L Scale L LocalToWorld L

    MeshInstanceRenderer ▼ ComponentDataの設定 MeshInstRender : 配管工モデル Scale : float(1f, 0.1f, 1f) ※モデルイメージ
  15. Entity L Position L Rotation L Scale L LocalToWorld L

    MeshInstanceRenderer Transform System ▼ ComponentDataの設定 MeshInstRender : 配管工モデル Scale : float(1f, 0.1f, 1f) → LocalToWorldにScaleの結果が反映される。 ※この時点では描画されていない ※モデルイメージ
  16. Entity L Position L Rotation L Scale L LocalToWorld L

    MeshInstanceRenderer Transform System Renderer System ▼ ComponentDataの設定 MeshInstRender : 配管工モデル Scale : float(1f, 0.1f, 1f) → → LocalToWorldにScaleの結果が反映される。 ※この時点では描画されていない モデル変換行列と描画情報を元に DrawMesh***で描画を行う。 ※モデルイメージ
  17. ▼ ECSの描画について ・ 細かい点を意識せずに簡単に描画する事が可能。 ・ 頂点シェーダーで単純なループアニメーションを   再生するぐらいならこちらでも対応可能。 - e.g.

    BoidExampleの魚の動き、特定のロゴの回転処理など。 - ※アニメーションについては後述 ・ 求める結果によっては改造/自作を行うことで   高速化/高機能化を求めても良いかも。 → 座標計算周りはComputeSahderに投げる → 細かなアニメーション制御対応など
  18. Entity L Position/Rotation/Scale L LocalToWorld L PlayData(キーフレームなど) Animation System 全Entityが1万体居るとして、

    歩行モーションの配管工が5000体居るとした場合、 先ずは歩行モーション5000体分のComputeBufferを生成して PlayData(キーフレームなど)を渡す。 →マテリアルは同じなのでDrawMeshInstanceIndirectで一括描画。 → ※モデルイメージ
  19. Entity L Position/Rotation/Scale L LocalToWorld L PlayData(キーフレームなど) Animation System Resurt

    全Entityが1万体居るとして、 歩行モーションの配管工が5000体居るとした場合、 先ずは歩行モーション5000体分のComputeBufferを生成して PlayData(キーフレームなど)を渡す。 →マテリアルは同じなのでDrawMeshInstanceIndirectで一括描画。 → → 後は左の手順をアニメーションタイプ毎 に繰り返すだけ。 ※モデルイメージ
  20. ▼ 衝突判定について 但し参考例ならある。 ・【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミング - https://www.slideshare.net/UnityTechnologiesJapan/cedec2018cpu-entity-component-systemecs

    - ※リンクは貼っていないが講演動画もある。 上記資料の「16. コリジョンを作ってみた」(108ページ目~)にて解説されている。 リポジトリの方も公開されているので参考にすることが可能。 - https://github.com/Unity-Technologies/AnotherThreadECS
  21. ▼ 仕組み ・ やっている事は簡単に纏めると総当たりでしか無い。 1. Entityに球体形状の衝突プリミティブとなるComponentDataを持たせる → 位置や半径の情報を持っているなど 2. 衝突判定を行うComponentSystemを実装

    → 中で衝突判定プリミティブを持つEntityを収集し判定。 ※全てのEntityを一括りで取るのではなく、 「プレイヤー」「敵」とEntityの種類ごとに分けて取得。(後述) ※単純に全てのEntityに対して総当たりをすると言う手もあるが、 先程例に出したCEDEC講演の方では空間を分割するアプローチで最適化を行っていた。
  22. ▼ EntityDebuggerについて ・ 主に以下の要素を参照可能 - 各Entityに紐付いているComponentDataの内容 - 各アーキタイプのチャンク使用量 - World及び登録されているComponentSystem

    - ComponentSystemの実行順/処理負荷 ・ 最初は1~数個のEntityを作って動作確認すると   追いやすいのでおすすめ。
  23. ▼ Prefab ComponentData 要約するとEntityに紐付けることで以下の機能を付与可能。 - EntityがPrefabを持っている間は全てのComponentDataで動作しない。 - RemoveComponentDataでPrefabを外すと再び起動する。 - Prefabを持つEntityを元にInstanciateして生成したEntityは

    Prefabが外れた状態で複製される。 特徴としては複製時の挙動。 その為に予め共通の初期設定を済ませておいたEntityをPrefabとして生成し、 後は必要なタイミングで雛形を元に生成すると言った使いみちが考えられる。