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. python编的游戏可以直接玩吗_怎么用python开发游戏?
  2. 以太坊发token教程
  3. android 页卡切换实现,TabLayout+ViewPager实现选项卡切换效果
  4. 编写字符串反转函数 .
  5. Linux系统中/dev/mtd与/dev/mtdblock的区别
  6. android关机位置定位,Android5.0关机充电动画位置
  7. 处理血压信号_测血压检测健康,8款高品质血压计推荐
  8. 学计算机之路写一篇作文,写我的学艺之路作文
  9. 转:CentOS系统yum源配置修改、yum安装软件包源码包出错解决办法!
  10. 华为当个pl怎么样_华为员工吐槽:画饼、忽悠、洗脑,有些pl、pm怎么可以那么坏?...
  11. 基于弹性计算网络能力提升容器密度最佳实践
  12. java用1234组成_java编程题,java1234组成三位数不重复
  13. linux怎么运行idl,科学网—在Scientific linux 7上安装idl83 - 姜小川的博文
  14. AECC2015官方破解补丁/AdobeAfterEffectsCC2015中文版免费下载(AE安装教程)
  15. 计算机端口连接失败,电脑telnet端口(23端口)提示连接失败怎么办?
  16. 通过SQL注入获得网站后台用户密码
  17. 自己做小程序开个社区团购可行吗?
  18. C++中字符串的三种定义和引用方法
  19. GNSS观测值质量分析必备基础知识
  20. 《逃离禁闭岛》游戏评测:不一样的密室逃脱

热门文章

  1. php动态绘制仪表盘,Pyecharts制作酷炫仪表盘,还能实时更新!
  2. 任泽平:谏言、真相与几句心里话
  3. MySQL查询这一篇就够了
  4. 中英保险业务常用词汇--产险
  5. 【工具合集】渗透测试工具库-年度最强合辑
  6. 【实用】一套专业的人员定位系统应该如何选择硬件设备?
  7. 显示器色彩精度测试软件,色彩精确度、亮度均匀度及伽玛线测试
  8. 安装的java打不开tsa文件_java – 具有https tsa的JDK 1.7 jarsigner不再有效
  9. python做的游戏放到微信_【1、 创建一个python的文件,运行后,文字版方式模拟微信游戏“跳一跳?】...
  10. mysql自愈_数据库跨地域容灾自愈最强攻略来了!