上篇提到:IJOB接口是一个一个的开线程任务,因为数据是顺序执行的所以它可以保证正确性。如果想让线程人物真正的并行,那么可以采用IJobParallelFor。
案例六:IJobParallelFor多线程并行化控制指定数量cube向上移动(Scne7)
脚本:JobParallelForTest
using UnityEngine;
using Unity.Jobs;
using Unity.Entities;
using Unity.Collections;
public class JobParallelForTest : MonoBehaviour
{
struct VelocityJob : IJobParallelFor
{
public NativeArray<Vector3> positions;
public NativeArray<Vector3> velocitys;
public float delaTime;
// 并行化 让一个线程做数组的一部分处理
public void Execute(int index)
{
positions[index] = positions[index] + velocitys[index] * delaTime;
}
}
public int gameCount = 300;
public GameObject prefab;
public GameObject[] gameObjs;
void Start()
{
gameObjs = new GameObject[gameCount];
for (int i = 0; i < gameCount; i++)
{
gameObjs[i] = Instantiate<GameObject>(prefab);
gameObjs[i].transform.position = UnityEngine.Random.insideUnitSphere * 40;
}
}
void Update()
{
// 1.准备数据
NativeArray<Vector3> tmpPositions = new NativeArray<Vector3>(gameCount, Allocator.TempJob);
NativeArray<Vector3> tmpVelocitys = new NativeArray<Vector3>(gameCount, Allocator.TempJob);
for (int i = 0; i < gameCount; i++)
{
tmpVelocitys[i] = new Vector3(0, 1, 0);
//tmpPositions[i] = tmpPositions[i] + tmpVelocitys[i] * Time.deltaTime;
tmpPositions[i] = gameObjs[i].transform.position;
}
VelocityJob job = new VelocityJob()
{
positions = tmpPositions,
delaTime = Time.deltaTime,
velocitys = tmpVelocitys
};
// 2.执行
//信号量 主线程如何知道子线程执行完毕 gameCount 指定总共子线程执行数据数量 10:每个子线程以下处理多少次
JobHandle jobHandle = job.Schedule(gameCount,10);
// 3.同步
jobHandle.Complete();
for (int i = 0; i < gameCount; i++)
{
gameObjs[i].transform.position = tmpPositions[i];
}
tmpPositions.Dispose();
tmpVelocitys.Dispose();
}
}
并行化Job:”并行化“ Job是untiy所有实现IJobParallelFor接口的结构的总成,并行化job使用一个NativeArray存放数据来作为它的数据源。并行化job横跨多个核心执行。每个核心上有一个job,每个job处理一部分工作量。
IJob与IJobParallel 在上篇和本篇区别就是 Job内部的并行化,让一个Job在多个线程中同时处理。
远程项目仓库(github):https://github.com/h1031464180/UnityECS