unity多线程Burst+Job System

news2024/11/19 9:41:25

Unity自己本身UnityEngine所使用的API是不能被多线程调用的,它没有向用户开放线程接口,所以Unity是不能使用多线程的,但是C#中可以使用多线程,Unity使用C#进行脚本编辑,故而Unity也可以通过C#来调用多线程。

JobSystem 是Unity Dots(多线程运行框架)的核心组件之一,也可以把它拿出来利用多线程帮我们处理一些运算,比如视锥体剔除等。

在使用前需要导入:(具体自行百度下吧)

 

根据unity 官网以下几个隶属于: Unity.​Collections

这三个一般就是常用的:

IJob:

  1. 同一时间一个 Job 只能执行一个任务

IJobParallelFor

      1、同一时间执行多个相同的任务,则可以使用IJobParallelFor

IJobParallelForTransform

      1、同一时间执行多个相同的任务,专门用于操作 Transform 的 Parallel Job

IJob:执行方法示例

using Unity.Mathematics;
using UnityEngine;
using Unity.Jobs;
using Unity.Collections;
using Unity.Burst;
public class Texting : MonoBehaviour
{
    [SerializeField] private bool UseJobs = true;//控制开关
    private void Update()
   {
       float startTime = Time.realtimeSinceStartup;//游戏开始时间
       if (UseJobs)
       {
           //集合存储返回的对象
           NativeList<JobHandle> _native = new NativeList<JobHandle>(Allocator.Temp);
           for (int i = 0; i < 10; i++)
           {
               //接收返回的数据
               JobHandle jobhandle=ReallyToughTaskJob();
               //添加至集合
               _native.Add(jobhandle);
               
               //jobhandle.Complete();//等待线程完成
           }
           JobHandle.CompleteAll(_native);//等待所有线程完成
           _native.Dispose();//结束线程

       }
       else
       {
           //这里测试的是直接执行
           for (int i = 0; i < 10; i++)
           {
               ReallyToughTask();
           }
           
       }
       //输出结果
       Debug.Log((Time.realtimeSinceStartup-startTime)*1000f+"ms");
   }

   private void ReallyToughTask()
   {
       float value = 0f;
       for (int i = 0; i < 50000; i++)
       {
           value = math.exp(math.sqrt((value)));
       }
   }

   private JobHandle ReallyToughTaskJob()
   {
       //创建线程
       ReallyToughJob job = new ReallyToughJob();
       //返回结果
       return job.Schedule();
   }
   
}
[BurstCompile]//加入此标签再度提升性能
public struct ReallyToughJob:IJob  //引用类型
{
    public void Execute()
    {
        //执行的数据
        float value = 0f;
        for (int i = 0; i < 50000; i++)
        {
            value = math.exp(math.sqrt((value)));
        }
    }
}

IJobParallelFor示例:

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

public class Text2 : MonoBehaviour
{
    [SerializeField] private bool UseJobs = true;
    [SerializeField] private Transform pfZombie;
    private List<Zombie> zombieList;

    //用一个class类型保存数据结构
    public class Zombie
    {
        public Transform transform;
        public float moveY;
    }

    private void Start()
    {
        //创建
        zombieList = new List<Zombie>();
        for (int i = 0; i < 1000; i++)
        {
            //实例化创建1000个对象
           Transform zombieTransform= Instantiate(pfZombie,new Vector3(Random.Range(-8f,8f),Random.Range(-5f,5f),Random.Range(-10f,10f)),Quaternion.identity);
           //添加进集合 还有随机移动的y
           zombieList.Add(new Zombie
           {
               transform = zombieTransform,
               moveY = UnityEngine.Random.Range(1f,2f)
           });
        }
    }

    private void Update()
    {
        float startTime = Time.realtimeSinceStartup;//游戏开始时间

        if (UseJobs)
        {
            NativeArray<float3> positionArray = new NativeArray<float3>(zombieList.Count,Allocator.TempJob);
            NativeArray<float> moveYArray = new NativeArray<float>(zombieList.Count,Allocator.TempJob);
            
            //放入“高性能”集合中,保存数据(翻译可能有误,仅供参考)
            for (int i = 0; i < zombieList.Count; i++)
            {
                positionArray[i] = zombieList[i].transform.position;
                moveYArray[i] = zombieList[i].moveY;
            }
            //创建线程
            ReallyToughJobFor toughJobFor = new ReallyToughJobFor
            {
                //赋值给线程中的几个,提供数据
                dataTime = Time.deltaTime,
                postionArray=positionArray,
                moveYArray=moveYArray,
            };
            //开启 告知线程处理多少对象  要处理多少次
           JobHandle jobhandle= toughJobFor.Schedule(zombieList.Count,100);
           //等待线程结束
           jobhandle.Complete();
            //将返回的结果重新赋值
           for (int i = 0; i < zombieList.Count; i++)
           {
               zombieList[i].transform.position = positionArray[i];
               zombieList[i].moveY = moveYArray[i];
           }
            //删除集合
           positionArray.Dispose();
           moveYArray.Dispose();

        }
        else
        {
            //普通方法测试
            foreach (var zombie in zombieList)
            {
                zombie.transform.position += new Vector3(0, zombie.moveY * Time.deltaTime);
                if (zombie.transform.position.y>5f)
                {
                    zombie.moveY = -math.abs(zombie.moveY);
                }

                if (zombie.transform.position.y<-5f)
                {
                    zombie.moveY += +math.abs(zombie.moveY);
                }

                float value = 0f;
                for (int i = 0; i < 1000; i++)
                {
                    value = math.exp10(math.sqrt(value));
                }
            }
        }
        //输出结果
        Debug.Log((Time.realtimeSinceStartup-startTime)*1000f+"ms");
    }
    
    
}
[BurstCompile]//加入此标签再度提升性能,使得计算转为LR,提升运行效率
public struct ReallyToughJobFor:IJobParallelFor  //引用类型
{
    //创建集合
    public NativeArray<float3>  postionArray;
    public NativeArray<float> moveYArray;
    public float dataTime;
    //index 获取执行次数
    public void Execute(int index)
    {
        //具体执行方案
        postionArray[index] += new float3(0, moveYArray[index] * dataTime,0f);
        if (postionArray[index].y>5f)
        {
            moveYArray[index] = -math.abs(moveYArray[index]);
        }

        if (postionArray[index].y<-5f)
        {
            moveYArray[index] += +math.abs(moveYArray[index]);
        }

        float value = 0f;
        for (int i = 0; i < 1000; i++)
        {
            value = math.exp10(math.sqrt(value));
        }
    }
}

IJobParallelForTransform示例:

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

public class Text3 : MonoBehaviour
{
   [SerializeField] private bool UseJobs = true;
    [SerializeField] private Transform pfZombie;
    private List<Zombie> zombieList;

    //创建集合
    public class Zombie
    {
        public Transform transform;
        public float moveY;
    }

    private void Start()
    {
        zombieList = new List<Zombie>();
        for (int i = 0; i < 1000; i++)
        {
           Transform zombieTransform= Instantiate(pfZombie,new Vector3(Random.Range(-8f,8f),Random.Range(-5f,5f),Random.Range(-10f,10f)),Quaternion.identity);
           
           
           zombieList.Add(new Zombie
           {
               transform = zombieTransform,
               moveY = UnityEngine.Random.Range(1f,2f)
           });
        }
    }

    private void Update()
    {
        float startTime = Time.realtimeSinceStartup;//游戏开始时间

        if (UseJobs)
        {
            //创建Transfrom集合
            TransformAccessArray _array = new TransformAccessArray(zombieList.Count);
            NativeArray<float> moveYArray = new NativeArray<float>(zombieList.Count,Allocator.TempJob);

            //添加
            for (int i = 0; i < zombieList.Count; i++)
            {
                _array.Add(zombieList[i].transform);
                moveYArray[i] = zombieList[i].moveY;
            }
            
            //创建多线程
            ReallyToughJobForTransfrom _tough = new ReallyToughJobForTransfrom
            {
                //赋值
                dataTime = Time.deltaTime,
                moveYArray=moveYArray,
            };
            
            //开启 传入对象集合
           JobHandle jobhandle= _tough.Schedule(_array);
           //等待完成
           jobhandle.Complete();

           //返回结果,重新赋值
           for (int i = 0; i < zombieList.Count; i++)
           {
               zombieList[i].moveY = moveYArray[i];
           }
           
           //清空关闭集合
           moveYArray.Dispose();
           _array.Dispose();
        }
        else
        {
            //普通执行
            foreach (var zombie in zombieList)
            {
                zombie.transform.position += new Vector3(0, zombie.moveY * Time.deltaTime);
                if (zombie.transform.position.y>5f)
                {
                    zombie.moveY = -math.abs(zombie.moveY);
                }

                if (zombie.transform.position.y<-5f)
                {
                    zombie.moveY += +math.abs(zombie.moveY);
                }

                float value = 0f;
                for (int i = 0; i < 1000; i++)
                {
                    value = math.exp10(math.sqrt(value));
                }
            }
        }
        
        Debug.Log((Time.realtimeSinceStartup-startTime)*1000f+"ms");
    }
    
}
[BurstCompile]
public struct ReallyToughJobForTransfrom:IJobParallelForTransform  //引用类型
{
    
    public NativeArray<float> moveYArray;
    public float dataTime;
    
    //获取对象 Transfrom对象
    public void Execute(int index,TransformAccess access )
    {
        //具体方法
        access.position += new Vector3(0, moveYArray[index] * dataTime,0f);
        if (access.position.y>5f)
        {
            moveYArray[index] = -math.abs(moveYArray[index]);
        }

        if (access.position.y<-5f)
        {
            moveYArray[index] += +math.abs(moveYArray[index]);
        }

        float value = 0f;
        for (int i = 0; i < 1000; i++)
        {
            value = math.exp10(math.sqrt(value));
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/543173.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在新能源行业运用IPD?

新能源又称非常规能源&#xff0c;一般指在新技术基础上&#xff0c;可系统地开发利用的可再生能源。是指传统能源之外的各种能源形式&#xff0c;也是指刚开始开发利用或正在积极研究、有待推广的能源&#xff0c;如太阳能、地热能、风能、海洋能、生物质能和核聚变能等。目前…

HTTP与HTTPS的区别

1 HTTP与HTTPS有哪些区别 HTTP 是超文本传输协议&#xff0c;信息是明文传输&#xff0c;存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷&#xff0c;在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议&#xff0c;使得报文能够加密传输。HTTP 连接建立相对简单&#x…

你的私人编程老师,ChatGPT帮你快速掌握Python编程

ChatGPT为我们提供了一种全新的学习方式&#xff0c;让你可以更轻松&#xff0c;更快速地学习编程知识。 以下是ChatGPT帮助用户学习编程的优势&#xff1a; 推荐资源和课程ChatGPT可以根据您的编程经验和学习目标&#xff0c;推荐适合您的在线学习资源和课程。例如&#xff0c…

Go类型断言

在Go语言中类型断言的语法格式如下&#xff1a; value, ok : x.(T) 类型断言失败&#xff0c;不会发生panic。根据ok判断是否成功 或者 value: x.(T) 类型断言失败&#xff0c;会发生panic 其中&#xff0c;x 表示一个接口的类型&#xff0c;T 表示一个具体的类型&#xff08;也…

希望所有计算机专业同学都知道这些老师

C语言教程——翁凯老师、赫斌 翁恺老师是土生土长的浙大码农&#xff0c;从本科到博士都毕业于浙大计算机系&#xff0c;后来留校教书&#xff0c;一教就是20多年。 翁恺老师的c语言课程非常好&#xff0c;讲解特别有趣&#xff0c;很适合初学者学习。 郝斌老师的思路是以初学…

进口常用除氟树脂品牌

随着经济的发展&#xff0c;半导体、表面处理、采矿等行业产生了大量的高氟废水&#xff0c;由于高氟水对人体健康具有较大危害&#xff0c;含氟污水治理己经引起了广泛的关注。 多年以前&#xff0c;含氟废水的处理&#xff0c;一般下游污水处理厂通过合并多股废水&#xff0…

html监听界面被隐藏或显示

vue相比于小程序和uni-app 显然少了两个有点用的生命周期 onShow 应用被展示 onHide 应用被隐藏 但其实这个 要做其实也很简单 JavaScript中 有对应的visibilitychange事件可以监听 我们Html参考代码如下 <!DOCTYPE html> <html lang"en"> <head>…

在GB28181项目中,调用eXosip_register_send_register函数并且返回值为-2或者-3的含义是什么

一、eXosip_register_send_register返回-2的原因&#xff1a; 在GB28181项目中&#xff0c;调用eXosip_register_send_register函数并且返回值为-2通常表示注册发送失败。该返回值的含义是注册请求被拒绝&#xff0c;可能是由于身份验证失败或其他原因导致的。 以下是可能导致…

人车混合机器人实现身体平衡功能

1. 功能说明 在R035c样机上安装一个六轴陀螺仪传感器&#xff0c;本文示例将实现机器人身体平衡功能。当用手把机器人人形部分摆动到左侧时&#xff0c;人形部分会自动恢复到中间&#xff1b;当用手把机器人人形部分摆动到右侧时&#xff0c;人形部分也会自动恢复到中间。 ​ 2…

简历照片底色要求是什么?怎么修改证件照底色?

准备一份完美的简历是找到工作的关键之一。其中一个重要的组成部分是照片。照片可以让我们的简历更加生动活泼&#xff0c;同时也可以为面试官在面试时提供更好的印象。但是&#xff0c;如果在照片中使用了错误的背景色&#xff0c;那么简历可能会被忽略或被视为不专业。因此&a…

数据结构与算法——求二叉树叶子数量求二叉树高度

递归特性求树的高度流程图 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> //二叉树的节点结构体 struct BinaryNode {char ch;//显示的字母struct BinaryNode * lChild;//左孩子struct BinaryNode * rChil…

代码随想录训练营Day45| 70. 爬楼梯 (进阶) 322. 零钱兑换 279.完全平方数

目录 学习目标 学习内容 70. 爬楼梯 &#xff08;进阶&#xff09; 322. 零钱兑换 279.完全平方数 学习目标 70. 爬楼梯 &#xff08;进阶&#xff09; 322. 零钱兑换 279.完全平方数 学习内容 70. 爬楼梯 &#xff08;进阶&#xff09; problems/0070.爬楼梯完全背包版本…

用ChatGPT创作小说,根据不同情境设定做多线推进

小说根据不同情境设定做多线推进 我们在读小说、看影视剧时&#xff0c;经常会有这样那样的遗憾&#xff1a;这里主角怎么没有吻上去呢&#xff1f;为什么不能给个大团圆结局呢&#xff1f;再仔细找找就能发现宝藏了啊&#xff01;等等等等……在网剧领域&#xff0c;已经开始…

gRPC-go参数功能介绍总结目录

本篇文章是gRPC-go框架的参数功能介绍总结 本篇文章的目的&#xff1a; 查看快速方便查询gRPC-go都有哪些参数可用&#xff01;可以快速的查询到相关案例&#xff01; gRPC-go版本是v1.30.0 可以从下面的地址下载gRPC-go版本 链接: https://pan.baidu.com/s/1za02qnUII78n-…

数据钻取,详细数据一览无遗!

钻取数据源 路径 仪表盘设计 >> 统计表 功能简介 图表配置新增「钻取数据源」功能。 钻取数据源是一个对全局图表添加的功能&#xff0c;使得用户点击统计表的图表对维度统计的图表形状进行数据源查看。 使用场景 用户使用饼图统计不同团队的任务时&#xff0c;期望…

沃尔玛、Shopee、亚马逊测评养号如何最大程度提高listing产品销量

打造一条优质的、有吸引力的listing对于每个做跨境电商的都很重要&#xff0c;那沃尔玛也不例外。产品的listing写得越好&#xff0c;就有可能获得更高的曝光和更高的转化&#xff01;今天就跟大家讲一下沃尔玛listing优化的几大因素。Listing的优化不仅仅只有关键词的优化、文…

盘点盛产 Web3 项目的全球七大高校:哪些知名项目从中诞生?

这七所高校分别是哈佛大学、斯坦福大学、加州大学伯克利分校、麻省理工学院、清华大学、北京大学、浙江大学。 作为当前社会最前沿的技术领域之一&#xff0c;Web3 正在吸引越来越多顶级高校校友的加入&#xff0c;例如 Blur、Scroll、Opensea、Aleo、STEPN 等都由斯坦福等一线…

Linux如何部署爬虫

在 Linux 上部署爬虫需要先安装必要的软件和环境&#xff0c;然后编写脚本或选择相应的爬虫框架来完成实际操作。以下是可行的部署过程&#xff1a; 1、安装必要的软件和环境 在 Debian/Ubuntu 系统中使用以下命令安装 Python、pip 和 Git 等软件&#xff1a; sudo apt updat…

JDBC连接GaussDB云数据库操作示例

目录 一、实验环境 二、登录华为云创建测试库表 1、登录GaussDB云数据库 2、建库、建表,用于测试 3、新增普通角色&#xff08;用户&#xff09;用于登录及访问测试&#xff08;可选&#xff09; 4、获取对应的公网IP 三、创建java工程 1、创建java工程 2、添加jar包 …

bug:生产问题,Golang解决csv文件用excel打开中文乱码问题

bug&#xff1a;Golang解决csv文件用excel打开中文乱码问题 1 场景及分析 场景&#xff1a;今天在生成csv文件之后&#xff0c;测试发现用office和wps打开乱码 分析&#xff1a;经过测试之后发现使用记事本打开不乱码&#xff0c;同时用记事本打开之后另存为ANSI编码之后用off…