Question about Jobs System

I tried to create a simple Move Job and it seems like i have not understand how to properly used the jobs system, as i am getting a much worst performance.
Is there any tips on how to get it to properly work?

The normal way of updating positions

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateNormal : MonoBehaviour
{
    public int cubesToSpawn = 1000;
    public GameObject cube;

    private List<Transform> cubes = new List<Transform>();
   
    // Start is called before the first frame update
    void Start()
    {
        for (int i = 0; i < cubesToSpawn; i++)
        {
            var newCube = Instantiate(cube);
            newCube.transform.position = GetRandomPosition();
            cubes.Add(newCube.transform);
        }
    }

    // Update is called once per frame
    void Update()
    {
        var downVec = Vector3.down;
        var delta = Time.deltaTime;
        for (int i = 0; i < cubesToSpawn; i++)
        {
            cubes[i].position += downVec * delta;
        }
    }

    private Vector3 GetRandomPosition()
    {
        return new Vector3(Random.Range(-2,2), Random.Range(-2,2));
    }
}

The jobs way of updating position

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Jobs;
using Random = UnityEngine.Random;

public class JobsRotate : MonoBehaviour
{
    public int cubesToSpawn = 1000;
    public GameObject cube;

    private List<Transform> cubes = new List<Transform>();

    private TransformAccessArray cubesTransform;
    private JobHandle moveJob;
    private MoveJob job;
   
    // Start is called before the first frame update
    void Start()
    {
       
        for (int i = 0; i < cubesToSpawn; i++)
        {
            var newCube = Instantiate(cube);
            newCube.transform.position = GetRandomPosition();
            cubes.Add(newCube.transform);
        }
       
        cubesTransform = new TransformAccessArray(cubes.ToArray());
    }

    // Update is called once per frame
    void Update()
    {
        job = new MoveJob
        {
            downVec = Vector3.down,
            deltaTime = Time.deltaTime
        };

        moveJob = job.Schedule(cubesTransform);
    }

    private void LateUpdate()
    {
        moveJob.Complete();
    }

    private void OnDestroy()
    {
        cubesTransform.Dispose();
    }

    private Vector3 GetRandomPosition()
    {
        return new Vector3(Random.Range(-2,2), Random.Range(-2,2));
    }
}

public struct MoveJob : IJobParallelForTransform
{
    public Vector3 downVec;
    public float deltaTime;
   
    public void Execute(int index, TransformAccess transform)
    {
        transform.position += downVec * deltaTime;
    }
}
1 Like

You need to call JobHandle.ScheduleBatchedJobs at the end of your Update function: Unity - Scripting API: Unity.Jobs.JobHandle.ScheduleBatchedJobs

2 Likes

Also adding [BurstCompile] to your job will help a lot.

2 Likes

Also your transforms need to have different roots or the IJobParallelForTransform will only run on one thread.
Doubt it will help much here, but in general try using float3 instead of Vector3 as the Burst compiler can do better transformations to speed up you code with that.
Do note though that Vector3 has some (rather questionable) behaviors which are not the same in float3, for example that == in Vector3 looks for approximate equality rather than whether the values are actually equal

1 Like