1.定义一个Job结构体

首先,需要定义一个struct继承接口IJob。

注意:Job数据只接受引用类型的数据,无法使用类(calss)的数据。

public struct MyJob : IJob
{public float a;public float b;public NativeArray<float> result;public void Execute(){result[0] = a + b;}
}

在这个结构体MyJob中进行需要进行的计算并将结果存储于NativeContainer中,Unity附带一个NativeContainer名为NativeArray的程序。

您还可以使用NativeSlice操作一个NativeArray来获取NativeArray从指定位置到指定长度的子集。

注意:实体组件系统(ECS)包扩展了Unity.Collections命名空间以包括其他类型的NativeContainer:

  • NativeList- 可调整大小的NativeArray。
  • NativeHashMap - 键值对。
  • NativeMultiHashMap - 每个键有多个值。
  • NativeQueue- 先进先出(FIFO)队列。

2.实例化Job并填充数据

// Create a native array of a single float to store the result. This example waits for the
// job to complete for illustration purposes
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);// Set up the job data
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result;

实例化Job后需要对结构体中的数据赋值,并对要保存结果的NativeContainer分配内存。

当创建 NativeContainer时,必须指定所需的内存分配类型。分配类型取决于Job运行的时间长度。通过这种方式,您可以定制分配以在每种情况下获得最佳性能。
NativeContainer内存分配和释放有三种分配器类型。在实例化你的NativeContainer时候需要指定合适的一个类型。

  • Allocator.Temp分配的时候最快。它适用于寿命为一帧或更少的分配。您不应该使用Temp将NativeContainer分配传递给Jobs。您还需要在从方法(例如MonoBehaviour.Update,或从本机代码到托管代码的任何其他回调)调用返回之前调用该方法Dispose()。
  • Allocator.TempJob是一个比Temp慢的分配,但速度比Persistent快。它适用于四帧生命周期内的分配,并且是线程安全的。如果在四个帧内没有调用Dispose,则控制台会打印一个从本机代码生成的警告。大多数小型Jobs都使用这个NativeContainer分配类型。
  • Allocator.Persistent是最慢的分配,只要你需要它,就一直存在。并且如果有必要的话,可以持续整个应用程序的生命周期。它是直接调用malloc的包装器。较长的Jobs可以使用此NativeContainer分配类型。你不应该使用Persistent在性能至关重要的地方使用。

例如:

NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);

注意:上例中的数字1表示NativeArray的大小。在这种情况下,它只有一个数组元素(因为它只存储一个数据result)。

3.调用Schedule方法

// Schedule the job
JobHandle handle = jobData.Schedule();// Wait for the job to complete
handle.Complete();// All copies of the NativeArray point to the same memory, you can access the result in
// "your" copy of the NativeArray
float aPlusB = result[0];// Free the memory allocated by the result array
result.Dispose();

调用Schedule将Job放入Job队列中以便在适当的时间执行。一旦调度,你就不能打断Job的运行。
注意:您只能在主线程调用Schedule。

最终的结果需要从结构体的NativeContainer中读取出来。请及时使用Dispose释放内存。

4.Job依赖

如果需要使用多个Job,且需要用到前一个或几个Job的数据,则需要使用到Job依赖。

当您调用Job的Schedule方法时,它将返回JobHandle。您可以在代码中使用JobHandle 作为其他Job的依赖关系。如果Job取决于另一个Job的结果,您可以将第一个作业JobHandle作为参数传递给第二个作业的Schedule方法

JobHandle firstJobHandle = firstJob.Schedule();
secondJob.Schedule(firstJobHandle);

如果Job有许多依赖项,则可以使用JobHandle.CombineDependencies方法合并它们。CombineDependencies允许您将它们传递给Schedule方法。

NativeArray<JobHandle> handles = new NativeArray<JobHandle>(numJobs, Allocator.TempJob);// Populate `handles` with `JobHandles` from multiple scheduled jobs...JobHandle jh = JobHandle.CombineDependencies(handles);

Job Code:

// Job adding two floating point values together
public struct MyJob : IJob
{public float a;public float b;public NativeArray<float> result;public void Execute(){result[0] = a + b;}
}// Job adding one to a value
public struct AddOneJob : IJob
{public NativeArray<float> result;public void Execute(){result[0] = result[0] + 1;}
}

Main Code:

// Create a native array of a single float to store the result in. This example waits for the job to complete
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);// Setup the data for job #1
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result;// Schedule job #1
JobHandle firstHandle = jobData.Schedule();// Setup the data for job #2
AddOneJob incJobData = new AddOneJob();
incJobData.result = result;// Schedule job #2
JobHandle secondHandle = incJobData.Schedule(firstHandle);// Wait for job #2 to complete
secondHandle.Complete();// All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
float aPlusB = result[0];// Free the memory allocated by the result array
result.Dispose();

接口:

定义Job的结构体时,有3种不同的接口用于不同计算:

IJob,IJobParallelFor,IJobParallelForTransform

IJob:

允许调度一个与主线程和其他Jobs并行的单独的Job。当Job被列入工作计划时,Job的Execute方法将在一个工作线程上调用。返回的Job句柄可用于确保Job已完成。或者可以将其作为依赖项传递给其他Job,从而确保Job在工作线程上一个接一个地执行。

IJobParallelFor:

允许对本机NativeContainer的每个元素或固定次数的迭代执行相同的独立操作。当计划作业时,Execute(int index)方法将在多个工作线程上并行调用。Execute(int index)将对从0到指定的长度的每个索引执行一次。每个迭代必须独立于其他迭代(安全系统为您执行此规则)。索引没有保证顺序,而是在多个核上并行执行。

IJobParallelForTransform:

Unity的文档中没有详细介绍,只写了名字

在从Package Manager中加载了Jobs包后,Unity增加了三个新的接口IJobParallelForBatch、IJobParallelForFilter和IJobParallelForDefer,不过它们现在是不安全的(Unity说的,等待以后完善)。

IJobParallelForBatch:

它的工作原理类似于IJobParallelFor,但是它不是为每个索引调用一次执行函数,而是每个执行批次调用一次执行函数。如果您需要同时处理多个项目,但仍然希望并行处理,那么这是非常有用的。此Job类型的常见场景是,如果需要创建一个临时数组,并且希望避免一次创建数组中的每个项。通过使用IJobParallelFor,您可以为每个批创建一个临时数组。

IJobParallelForFilter和IJobParallelForDefer还没有具体文档。

Unity简单使用Job System相关推荐

  1. unity简单技能系统

    unity简单技能系统 类类型概览 CharacterSkillManager      角色技能管理器 挂载在角色 持有SkillData与释放器 通过释放器进行技能释放 SkillDeployer ...

  2. Unity 简单实现子弹射击

    Unity 简单实现子弹射击 一.具体步骤: 1.  创建预制体:Assets >> Create >> Prefab 并命名,添加碰撞(Box Collider 等)并勾选 ...

  3. Unity简单商城系统,用SQLite数据库保存/加载数据

    Unity简单商城系统案例 流程 最后效果展示 1. 创建项目并导入SQLite需要的dll文件 2. 创建数据库表(玩家表和商店表) 3. Singleton 单例脚本 4. 封装SQLite数据库 ...

  4. Unity简单实现图片墙功能

    Unity简单实现图片墙功能 前言 在做之前公司的项目中,我做过很多实现照片墙效果的功能.其中我觉得我做的效果比较好而且比较有难度的就是雀巢项目中的那个仿照apple watch拖拽效果实现的那个照片 ...

  5. unity 简单实现三阶魔方游戏

    unity 简单实现三阶魔方游戏 魔方体验地址 工程文件免费下载 实现思路 一.魔方的旋转 三阶魔方由26个方块与 9个旋转轴组成.旋转轴旋转时带动在其控制范围的方块旋转. 旋转轴如何带动方块旋转? ...

  6. Unity简单的ease模拟

    Unity简单的ease模拟 using System.Collections; using System.Collections.Generic; using UnityEngine; //简单的e ...

  7. unity简单的背包系统笔记(有视频讲解)

    视频参考:Unity教程:背包系统:04:显示在背包里(C# code) InventoryManager_哔哩哔哩_bilibili 素材下载: https://pan.baidu.com/s/1o ...

  8. Unity简单实现物体变色闪烁功能

    Unity简单实现3D物体变色闪烁功能 前言 在我们Unity的实际开发中,经常会碰到这样的需求,比如要在3D场景中凸显出某个物体或者需要让玩家注意到这个物体的时候,需要让该物体有一个高亮的功能.我所 ...

  9. Unity 简单手势识别

    Unity 简单手势识别 Unity 代码 代码很简单没有难度,都有注解,随便 康一康 就会了. CallEvent () 方法需要自己搭载使用. Unity 代码 using System.Coll ...

最新文章

  1. 配置oracle net,配置 Oracle Net 的3个重要文件
  2. 如何优化 Java 性能?
  3. linux怎么装mac系统,Linux/macos系统怎么安装nvm
  4. 开发工程师的职场人生路(转)
  5. 嵌入式C语言之struct内存分配分析
  6. 【Node学习】—Node.js中模块化开发的规范
  7. MongoDB的角色作用(2)
  8. 里恩eLearning在线培训考核系统介绍
  9. JAVA后端应该学什么技术?
  10. 调整外接显示屏亮度的方法
  11. 自然语言处理NLPIR-ICTCLAS 授权文件过期问题
  12. 水下光通信实现(1)----LED驱动电路
  13. 【转发】相似性度量学习及其在计算机视觉中的应用
  14. xv6的sleep和wakeup
  15. 凤凰汽车登陆纳斯达克:累计亏损1820万美元,持续经营能力存疑问
  16. 微信小程序自动保留空格换行
  17. 现在学IT行业,选择哪个方向较好?
  18. 如何在Vivado创建一个FIFO的IP核并使用ILA工具验证
  19. Pylint 常见问题文档
  20. 基于单片机的温控风扇

热门文章

  1. 线程让步——Thread.yield()
  2. 我的世界java版的马难以驯服_最难驯服的我的世界呆萌宠物排行榜介绍
  3. java写一个登录系统_用java写一个用户登陆界面
  4. Flink学习4-流式SQL
  5. knife4j:快速入门
  6. ios piv6遭拒绝
  7. 0110 - 给 iPhone 6 换了电池
  8. 刻录dvd的数据大约只能保存两年
  9. task6 .OR、IF以及whilemd
  10. 春雨医生官宣“莆田系”医院名单 北京24家“上榜”