テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】ECSの並列処理(IJobParallelForやIJobForEach系)でEntityCommandBufferを使う

今回はECSで並列処理した結果をEntityCommandBufferから削除する方法についてです。以前は出来なかったのですが、最近出来るようになりました。

 

 

EntityCommandBufferと非同期処理

使用中のEntity郡に対して、非同期(C# Job System)でアクセスする事は望ましくありません。そのためバッファを別途用意し一旦蓄積、後で一気に処理するというアプローチが望ましいです。

そういった事をしたい場合、EntityCommandBufferを使用して一旦バッファに指示を格納、後で一気に処理するといったを使用します。https://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubaki_t1/20180902/20180902194448.png

tsubakit1.hateblo.jp

規模がでかい場合はExclusiveEntityTransactionを使用するのも良いかもしれませんが、細々としたものはEntityCommandBufferでやるべきです。

tsubakit1.hateblo.jp

このEntityCommandBuffer、以前はIJobでは使えてもIJobParallelForでは使えなかったのですが、気づいたら出来るようになっていました。

EntityCommandBufferと並列処理

EntityCommandBufferを使えると言っても直接は使えません。EntityCommandBuffer.Concurrentを経由してアクセスします。EntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent()インスタンスを取得しジョブに流し込み、後はジョブ側でオブジェクトの追加や削除、Entityの設定等を行います。

なおEntityCommandBuffer.Concurrent経由でオブジェクトを操作する際にはユニークなIDが必要です。これはExecuteの引数のint indexを指定しておけばOKです。

下の例では、指定座標に対して当たり判定を行い、接触していたら削除する…といったものです。以前は一旦バッファに格納していましたが、それが無くても動作します。

 

実際に動かした所、ちゃんと当たり判定の計算は非同期で行いつつ、Entityの削除もちゃんと動作しています。

f:id:tsubaki_t1:20181001220311g:plainIJobForEachWithEntity が使えるようになったので、Entity関連に対してもIJobParallelForを使わずComponentDataとEntityが一緒に取れるようになったのは楽で良いです。

コード

gist.github.com