26. 手順 3/3Entity つくる
var entity = entity_manager.CreateEntity(arche_type);
var entity = entity_manager.CreateEntity(arche_type);
var pos0 = new Position { Value = new float3(0,0,0), };
entity_manager.SetComponentData<Position>(entity, pos0);
SetComponentDataで初期化
CreateEntityでEntityを作成
28. public class CarSytem: ComponentSystem
{
}
手順(1/4) Systemを作る
ComponentSystemを継承
実行順がある場合は、
UpdateAfter(type)属性で
呼び出しタイミングを制御
29. 手順(2/4) グループを作成
public class CarSytem: ComponentSystem
{
struct Group {
public int Length;
public ComponentDataArray<Wheel> wheels;
[ReadOnly] public ComponentDataArray<Engine> engines;
private SubtractiveComponent<Wing> wings;
}
}
タイヤとエンジンを
持つEntity
羽を持つものは除く
条件を
フィルタリング
30. 手順(3/4) グループを注入
public class CarSytem: ComponentSystem
{
struct Group {
public int Length;
public ComponentDataArray<Wheel> wheels;
[ReadOnly] public ComponentDataArray<Engine> engines;
private SubtractiveComponent<Wing> wings;
}
[Inject] Group group;
}
グループの条件に一致した
ComponentDataが自動的に登録される
条件を
フィルタリング
31. 手順(4/4) 処理を追加
public class CarSytem: ComponentSystem
{
…
[Inject] Group group;
protected override void OnUpdate() {
for(int i=0; i<group.Length; i++){
var engine = group.engines[i];
//何かの処理
group.engines[i] = engine;
}
}
}
毎フレーム呼ばれる処理
グループと一致した
要素の分だけ回す
ComponentDataを
取り出して色々と処理
普通のC#
66. IJob
struct BJob : IJob {
public NativeArray<Vector3> positions;
public NativeArray<int> result;
public void Execute() {
}
}
入出力
67. IJob
struct BJob : IJob {
public NativeArray<Vector3> positions;
public NativeArray<int> result;
public void Execute() {
for (var i = 0; i < positions.Length; ++i) {
var pos = positions[i];
if( pos.x > -0.5f && pos.x < 0.5f){
}
}
}
}
ジョブの実行内容
68. IJob
struct BJob : IJob {
public NativeArray<Vector3> positions;
public NativeArray<int> result;
public void Execute() {
for (var i = 0; i < positions.Length; ++i) {
var pos = positions[i];
if( pos.x > -0.5f && pos.x < 0.5f){
result[0] = 1; return;
}
}
result[0] = 0;
}
}
結果を格納
69. IJob
struct BJob : IJob {
public NativeArray<Vector3> positions;
public NativeArray<int> result;
public void Execute() {
for (var i = 0; i < positions.Length; ++i) {
var pos = positions[i];
if( pos.x > -0.5f && pos.x < 0.5f){
result[0] = 1; return;
}
}
}
}
参照なので危険がつきまとう
読込専用なら兎も角、読み書きするジョブが複数同時に同じ要素を操作するとヤバイ
[ReadOnly]や[WriteOnly]属性をつける
データの読取専用 データの書込専用
70. 問題が起こりそうならエラーを出してくれる
InvalidOperationException: The previously scheduled job Job1:AJob
writes to the NativeArray AJob.positions. You are trying to schedule a
new job Job1:BJob, which writes to the same NativeArray (via
BJob.positions).
要約:複数のジョブが同じNativeArrayに同時に書き込むかも
71. InvalidOperationException: The native container has been
declared as [WriteOnly] in the job, but you are reading from it.
要約:書込専用のNativeArrayを読み込んじゃあかん
問題が起こりそうならエラーを出してくれる
ありがたや
72. ジョブの依存関係
Scheduleの引数にJobHandleを入れる
void Update() {
var ajob = new AJob() { positions = m_Positions, };
var bjob = new BJob() { positions = m_Positions, };
var handle = ajob.Schedule(positions.Length, 8);
handle = bjob.Schedule(handle);
JobHandle.ScheduleBatchedJobs();
handle.Complete();
}
bJobはaJobが
完了したら実行
73. Injectで取得したComponentDataArrayをそのまま渡せる
struct RigidbodyPositionJob : IJobParallelFor {
public ComponentDataArray<Unity.Transforms.Position> positions;
public ComponentDataArray<RigidbodyPosition> rigidbodies;
public void Execute(int i){
// 処理
}
}
ECSとのC# Job Systemの連携(1)
74. ECSとのC# Job Systemの連携(2)
public struct RigidbodyPositionJob
: IJobProcessComponentData<Position, RigidbodyPosition> {
public void Execute(ref Position pos, ref RigidbodyPosition rot) {
// 処理
}
}
[Inject]記述が不要になる他、若干効率的
[ReadOnly][WriteOnly]は引数に付与
競合しないようジョブの依存をよしなにしてくれる
必要なComponentDataはジェネリックで定義
IJobProcessComponentDataを使う
75. High Performance C# (C# Job Systemの制約)
Class Type無し
Boxing無し
GC Allocation無し
Exception無し
大丈夫!
まだ (一応) C#
All Basic Types
Struct
Enum
Generic
Properties
Safe Sandbox