Skip to content

Jobs

Job Types

In here you can find example of job types used in Stratkit. For more details, please refer to the Unity Entties Package documentation.

IJob

internal struct VelocityJob : IJob {
    [ReadOnly]
    public NativeArray<float3> velocities;
    public NativeArray<float3> positions;
    public float deltaTime;

    public void Execute() {
        for (var i = 0; i < positions.Length; i++) {
            positions[i] += velocities[i] * deltaTime;
        }
    }
}

IJobParallelFor

internal struct VelocityJob : IJobParallelFor {
    [ReadOnly]
    public NativeArray<float3> velocities;
    public NativeArray<float3> positions;
    public float deltaTime;

    public void Execute(int i) {
        positions[i] += velocities[i] * deltaTime;
    }
}
How it is schedule
var job = new VelocityJob() {
    deltaTime = Time.deltaTime,
    positions = ...,
    velocities = ...
};
JobHandle jobHandle = job.Schedule(positions.Length, 32);

IJobEntity

public struct Velocity: IComponentData {
    public float3 Value;
}
public struct Position: IComponentData {
    public float3 Value;
}
internal partial struct VelocityJob : IJobEntity {
    public float deltaTime;

    private void Execute(
        in Velocity velocity,
        ref Position position) {
        position.Value += velocity.Value * deltaTime;
    }
}
This job has an implicit query
var implicitQuery = SystemAPI.QueryBuilder()
    .WithAll<Velocity, Position>()
    .Build();
It could be scheduled with its implicit query
new VelocityJob().ScheduleParallel();
Or scheduled with a custom compatible query
var compatibleQuery = SystemAPI.QueryBuilder()
    .WithAll<Velocity, Position>()
    .WithAll<BulletTag>()
    .Build();
new VelocityJob().ScheduleParallel(compatibleQuery);

Jobify sequential code

flowchart LR
Burstify --> Jobify

Burstify code

Burstify code is the process of converting normal Unity's C# code into High Performance C# code. In summary: - Remove managed component - Use Native Container instead of maanged collections (List<T>, T[], Dictionary<T1, T2>) - Remove all HPC# incompatible code: yield statement, interface casting, etc… - Add BurstCompile attribute: the compiler will guide you by giving errors until it's completely Burstified

Jobify code

Identify repeatable code blocks

foreach (var a in arrayA) {
    listB.Add(func1(a, param1));
}
param2 = func2(listB);
foreach (var a in arrayA) {
    foreach (var b in arrayB) {
        listC.Add(func3(a, b, param2));
    }
}
And turn them into jobs
internal struct Job1 : IJobParallelFor {
    [ReadOnly]
    public NativeArray<T> arrayA;
    public NativeArray<T> arrayB;
    public T param1;

    public void Execute(int i) {
        arrayB[i] = func1(arrayA[i], param1);
    }
}
internal struct Job2 : IJob {
    [ReadOnly]
    public NativeArray<T> arrayB;
    public NativeArray<T> output;
    public void Execute() {
        output[0] = func2(arrayB);
    }
}
internal partial struct Job3 : IJobParallelFor {
    [ReadOnly]
    public NativeArray<T> arrayA;
    [ReadOnly]
    public NativeArray<T> arrayB;
    public NativeArray<T> arrayC;
    public T param2;

    public void Execute(int i) {
        for (int j= 0; j < arrayB.Length; j++) {
            arrayC[i] = func3(arrayA[i], arrayB[j], param2);
        }
    }
}

// scheduling jobs
var handle1 = new Job1{ ... }.ScheduleParallel(arrayA.Length, 16, Dependency);
var handle2 = new Job2{
    output = output,
    ...
}.Schedule(handle1);
Dependency = new Job3{
    param2 = output[0],
    ...
}.Schedule(arrayA.Length, 16, handle2);

Jobify by using Component

Remodelling the relevant classes using Components

public class MyClass: MonoBehaviour {
    public T a;
    public T b;
    public T c;
    public void Update() {
        c = func1(a, b);
    }
}
internal partial struct MyClassJob : IJobEntity {
    private void Execute(in AB ab, ref C c) {
        c = func1(ab.a, ab.b);
    }
}

Reverse one-to-many relationship

Refer to this refactoring pattern