IJob:开启单个线程进行计算,线程内不允许对同一个数据进行操作,也就是如果你想用多个IJob分别计算,将其结果存储到同一个NativeArray<int>数组是不允许的,所以不要这样做,如下例子就是反面教材,应该直接用一个IJob去进行for循环,将结果存储到传入的NativeArray<int>。
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
public class MyJob : MonoBehaviour
{
//public List<int> intArray;
//public void Start()
//{
// intArray = new List<int>();
// for (int i = 0; i < 100; i++)
// {
// for (int j = 0; j < 100; j++)
// {
// intArray.Add(i * j);
// }
// }
//}
void Start()
{
List<NativeArray<int>> map = new List<NativeArray<int>>();
NativeArray<int> tempArray = new NativeArray<int>(10000, Allocator.TempJob);
//处理多个Job时需要缓存JobHandle for之外执行Complete,单个时可以直接 jobHandle.Complete();
NativeList<JobHandle> jobHandles = new NativeList<JobHandle>(Allocator.Temp);
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
map.Add(new NativeArray<int>(1, Allocator.TempJob));
SingleJob singleJob = new SingleJob() { i = i, j = j, result = map[i * 100 + j] };
JobHandle jobHandle = singleJob.Schedule();
jobHandles.Add(jobHandle);
}
}
JobHandle.CompleteAll(jobHandles);
Debug.Log(map[20 * 100 + 30][0]);
jobHandles.Dispose();
tempArray.Dispose();
foreach (var v in map)
{
v.Dispose();
}
map.Clear();
}
[BurstCompile]
public struct SingleJob : IJob
{
public int i, j;
public NativeArray<int> result;
public void Execute()
{
result[0] = i * j;
}
}
}
IJobParallelFor:进行并行计算移动物体的位置信息(帧数在35左右)
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
public class MyJob : MonoBehaviour
{
public GameObject cubePrefab;
public List<Transform> cubeTransList;
public float time;
public int dir = 1;
void Start()
{
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
GameObject go = GameObject.Instantiate(cubePrefab);
go.transform.position = new Vector3(i * 2, j * 2, 0);
cubeTransList.Add(go.transform);
}
}
}
void Update()
{
MyJobParallelFor myJobParallelFor = new MyJobParallelFor();
NativeArray<float3> float3sArray = new NativeArray<float3>(cubeTransList.Count, Allocator.TempJob);
for (int i = 0; i < cubeTransList.Count; i++)
{
float3sArray[i] = cubeTransList[i].transform.localPosition;
}
myJobParallelFor.float3sArray = float3sArray;
myJobParallelFor.deltaTime = Time.deltaTime;
time += Time.deltaTime;
if (time >= 2)
{
dir = dir * -1;
time = 0;
}
myJobParallelFor.dir = dir;
JobHandle jobHandle = myJobParallelFor.Schedule(cubeTransList.Count, 10); //10是内核数 (最大会使用到实际CPU内核数)
jobHandle.Complete();
for (int i = 0; i < cubeTransList.Count; i++)
{
cubeTransList[i].localPosition = float3sArray[i];
}
float3sArray.Dispose();
}
//并行执行线程
[BurstCompile]
public struct MyJobParallelFor : IJobParallelFor
{
public NativeArray<float3> float3sArray;
public float deltaTime;
public int dir;
//index对应执行传入的数组索引
public void Execute(int index)
{
float3sArray[index] += new float3(0, dir * deltaTime, 0);
}
}
}
若不想使用并行,可以使用IJobFor(并发计算)需修改为如下:
JobHandle jobHandle = default;
jobHandle = myJobParallelFor.Schedule(cubeTransList.Count, jobHandle);
jobHandle.Complete();
或者并发与并行兼容的,允许并行操作情况下才会进行并行。
JobHandle jobHandle = default;
jobHandle = myJobParallelFor.ScheduleParallel(cubeTransList.Count, 10, jobHandle); //10是内核数 (最大会使用到实际CPU内核数)
jobHandle.Complete();