今回はECSで並列処理した結果をEntityCommandBufferから削除する方法についてです。以前は出来なかったのですが、最近出来るようになりました。
EntityCommandBufferと非同期処理
使用中のEntity郡に対して、非同期(C# Job System)でアクセスする事は望ましくありません。そのためバッファを別途用意し一旦蓄積、後で一気に処理するというアプローチが望ましいです。
そういった事をしたい場合、EntityCommandBufferを使用して一旦バッファに指示を格納、後で一気に処理するといったを使用します。
規模がでかい場合はExclusiveEntityTransactionを使用するのも良いかもしれませんが、細々としたものはEntityCommandBufferでやるべきです。
このEntityCommandBuffer、以前はIJobでは使えてもIJobParallelForでは使えなかったのですが、気づいたら出来るようになっていました。
EntityCommandBufferと並列処理
EntityCommandBufferを使えると言っても直接は使えません。EntityCommandBuffer.Concurrent
を経由してアクセスします。EntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent()
でインスタンスを取得しジョブに流し込み、後はジョブ側でオブジェクトの追加や削除、Entityの設定等を行います。
なおEntityCommandBuffer.Concurrent
経由でオブジェクトを操作する際にはユニークなIDが必要です。これはExecuteの引数のint index
を指定しておけばOKです。
下の例では、指定座標に対して当たり判定を行い、接触していたら削除する…といったものです。以前は一旦バッファに格納していましたが、それが無くても動作します。
実際に動かした所、ちゃんと当たり判定の計算は非同期で行いつつ、Entityの削除もちゃんと動作しています。
IJobForEachWithEntity が使えるようになったので、Entity関連に対してもIJobParallelFor
を使わずComponentDataとEntityが一緒に取れるようになったのは楽で良いです。