ECSで[Inject]
属性が非推奨になり、新しいAPIが追加されました。
個人的に、多少パフォーマンスを犠牲にして簡単になるなら、プロダクトとして妥当*1だと思っていたので若干ガッカリですが、新しいAPI群はInject
よりスッキリしているので好印象です。
- ForEachでComponentDataを処理する
- ラムダ式を使ってるならGCが発生するんじゃない?
- ComponentGroupで操作対象を予め絞り込む
- JobSystem側は、IJobProcessComponentDataとIJobChunkを使う
- 感想
- 補足
- 関連
ForEachでComponentDataを処理する
メインスレッドを使用するComponentSystemの場合、ForEachを使用して処理を記述出来ます。これはC#の言語的なforeachではなく、ComponentSystem専用に拡張したAPIです。
ForEach( operation );
という感じの書式で、operationはEntity
やDynamicBuffer
、IComponentData
、ISharedComponentData
や普通のComponent
が使用できます。refキーワード
を使うのはIComponentData
だけの点に注意です。また、使用できるComponentDataの数は大体5個までです。なおEntity
やDynamicBuffer
は要素の先頭というルールがあります。
下のような形で記述出来ます。構造体を用意する必要のあった[Inject]構文と比較して、かなりスッキリした印象です。
ラムダ式を使ってるならGCが発生するんじゃない?
コードを追ってみた所、ラムダ式の部分はIL2CPPでビルドする際にキャッシュするコードが挿入されており、GCは発生しませんでした。
ただForEach外の値を参照するなら別で、newが走ります。
そういう場合は、ToComponentDataArray
とCopyFromComponentDataArray
を使うのが良さそうです。
ComponentGroupで操作対象を予め絞り込む
要素が最大5つなので絞り込みに不安があるところですが、有り難い事にComponentGroup
で事前に操作対象を絞り込んでおき、その中から特定のComponentDataにアクセスするといった事が可能になっています。これは「”命令を組み合わせた物を繰り返して計算"するより”命令を繰り返し実行したものを組み合わせた方が良い"」に合わせやすくて良いです。
なおForEach内ではEntityの追加・削除は出来ません。一旦ForEachの外に出して一気に処理するのが良いです。
InvalidOperationException: EntityManager.AddComponent/RemoveComponent/CreateEntity/DestroyEntity are not allowed during ForEach. Please use PostUpdateCommandBuffer to delay applying those changes until after ForEach.
IJobProcessComponentData
にもScheduleGroup( ComponentGroup, JobHandle );
が追加され、要素の絞り込みが可能になったっぽいです。EntityDebuggerではバグって絞り込み出来ないような表示になりますが、実際の動きではComponentGroupで一旦絞り込みがされた物だけが対象になります。
もうこれRequireComponentTag
無くても何とかなるんじゃねと思うんですが、どうなんでしょう。
JobSystem側は、IJobProcessComponentDataとIJobChunkを使う
C# Job System側はと言うと、IJobProcessComponentData
とIJobChunk
が推奨されています。
それでも十分でないケースでは、ToComponentDataArrayで一覧取得、それも無理ならCreateArchetypeChunkArray
でChunk単位でコントロールするという感じみたいです。
感想
[Inject]やComponentArrayを使わずとも、概ね同じような機能を非常にスッキリとした形で記述出来ました。
…ただ、「ForEach」は別名にしてほしかった感
補足
Unity 2018.3系で新しいECSを使用する場合「"com.unity.test-framework.performance": "0.1.49-preview",」が要ります
関連
*1:逆に、難しいが効率的…というプロダクトは、他と比較して余程のメリットが無ければ大体死ぬ