【Unity】Hybrid ECS から Pure ECS へ

前回 でMeshInstanceRendererを使って描画できました。
PositionComponent とか RotationComponent とかも使ってPure ECS を少し理解が深まったので、
GameObject.Instantiate(...) でオブジェクトを生成ではなく、
Pure ECSらしく書き換えを行いたいです。

まずは調査!!

var manager = World.Active.GetOrCreateManager<EntityManager>();
var archetype = manager.CreateArchetype(...); // Position とか Rotationとか
var entity = manager.CreateEntity(archetype);
var look = ... // MeshInstanceRenderer
manager.AddSharedComponentData(entity, look);

以上の意味は自分なりに解釈すると、

EntityManager に Archetype を指定し Entity を生成し、
MeshInstanceRenderer を Entity に追加する
これで MeshInstanceRenderer は Entity の情報 ( Position , Rotationなど )で描画してくれる
あとは やりたいことを ComponentSystem とか JobComponentSystem を使って更新する

かなぁ~(間違ったらコメントで指摘していただければと・・・

オブジェクトの生成部分を変更する

オブジェクトは GameObject.Instantiate(...) ではなく
EntityManager から生成するため、Managerクラスを書き換えます

gist.github.com

MeshInstanceRendererComponent など設定して実行すると
f:id:kou_yeung:20181109142013g:plain

今まで通り描画されますが、回転しないよね。

回転スクリプト( Move.cs ) を変更する

gist.github.com
変更点は ※ を参照してください。

あとは Entity の Archetype に Move を追加するだけ

var archetype = manager.CreateArchetype(new ComponentType[]
{
    typeof(Position),
    typeof(Rotation),
    typeof(Move),      // ※ 追加する
});

f:id:kou_yeung:20181109143408g:plain
動きました!!
200FPS 以上になりました。

もう一歩先へ

Archetype はハードコーディングなのが不満です!!
どう解決するかなぁと思い、「そうだ、ComponentDataWrapper があるじゃないか!」

やりたいこと、
Prefab に アタッチしてる ComponentDataWrapper<T> の T 型を取得すればいいじゃない?(w)

書いた。
gist.github.com

GameObjectにアタッチした ComponentDataWrapperBase のコンポーネントを取得し
そのコンポーネントの基底クラスのジェネリック型パラメーターを取得する。

それと、MeshInstanceRendererComponent など SharedComponent が存在するかもしれないので
IsSharedComponent == true のものは取り除けばいいです

ついでに、CreateMeshInstanceRenderer() メソッドも提供し
MeshFilter や MeshRenderer から動的MeshInstanceRendererを生成すればスッキリです。

あとは、Manager のオブジェクト生成部分を書き換えればいい
gist.github.com

プログラム変更なしで、Archetype の調整ができました!!

まぁ

まだ検証段階なので、
Prefab から Archetype を取得するのが本当にいいのかも疑問ですが。。
結果的に ECS が理解を深まったからいいや~