UnityECS版のNavMeshAgent
AgentNavigationのパッケージを使えば自分のECSベースのプロジェクトで、GameObjectでいうNavMeshAgentをほぼ再現できますが、マルチコアを意識して、scheduleParalleとJobHandleによる効率化を考えると、Localtransformへのアクセス競合が問題になってきたので、備忘録を残します。
Pathを計算して経路を導出し、移動方向を決める流れは同じですが、最終的にLocaltransformに位置情報を記録するのは、AgentLocomotionJob の中で行われています。
public void Execute(ref LocalTransform transform)
のスクリプトは、refを用いているので、他のJobから
[ReadOnly] public ComponentLookup LocalTransformLookup;
のようにLocaltransformにアクセスしても、State.Dependencyにしていれば競合が発生することはありません。
これはUnity内で自動的にタイミングを制御してくれているかららしいですが、言い換えるとマルチコアを十分に生かし切れていない、ということになります。
このような場合、JobHandleを設定してジョブを他のスレッドに投げ、真のマルチコア動作をしたいですが、その方法として、NativeListを作ってLocaltransformの情報を保存しておき、そのNativeListに[ReadOnly]でアクセスすることで、マルチコアを最大限に生かすことが可能です(EntityCommandBuffer.ParallelWriterの併用が必要)
また、Dependencyを用いず、JobHandleを用いて並列でJobに投げるためには、以下のAgentNavigationのパッケージ内のScriptを改造し、既存スクリプトと合体させます(アップデート時にエラーの可能性があるので、要注意)
AgentLocomotionJob
AgentSeekingSystem