当前位置: 首页 > 编程笔记 >

C#在Unity游戏开发中进行多线程编程的方法

丌官远
2023-03-14
本文向大家介绍C#在Unity游戏开发中进行多线程编程的方法,包括了C#在Unity游戏开发中进行多线程编程的方法的使用技巧和注意事项,需要的朋友参考一下

在这之前,有很多人在质疑Unity支不支持多线程,事实上Unity是支持多线程的。而提到多线程就要提到Unity非常常用的协程,然而协程并非真正的多线程。协程其实是等某个操作完成之后再执行后面的代码,或者说是控制代码在特定的时机执行。而多线程在Unity渲染和复杂逻辑运算时可以高效的使用多核CPU,帮助程序可以更高效的运行。本篇主要介绍在Unity中如何使用多线程。

首先引入C#中使用多线程的类库

using System.Threading;

创建线程实例的四种方式

一、线程执行无参方法

构造语法

// 初始化 Thread 类的新实例。
// < param name="start">无参委托对象.</ param>
public Thread(ThreadStart start)

start

类型:System.Threading.ThreadStart
表示开始执行此线程时要调用的方法的 ThreadStart 委托。

void Start()
{
 //创建无参线程对象
 Thread thr = new Thread(Func_NoArguments);
 //启动线程
 thr.Start();
}
// Function Of No Arguments.

void Func_NoArguments()
{
 Debug.Log("Run Func_NoArguments");
}

二、线程执行有参方法

构造语法

// 初始化 Thread 类的新实例。
// < param name="start">有参委托对象.< /param>
public Thread(ParameterizedThreadStart start)

start

类型:System.Threading.ParameterizedThreadStart
一个委托,它表示此线程开始执行时要调用的方法。
注意:参数只能有一个,且必须为object类型

实例

void Start()
{
 //创建有参线程对象
 Thread thr = new Thread(Func_Arguments);
 //启动线程,传入参数
 thr.Start("Lanou");
}
// Function Of Have Arguments.
void Func_Arguments(object data)
{
 Debug.Log("Run Func_Arguments, Data = " + data);
}

三、线程执行无参方法,限制线程要使用的最大堆栈大小

构造语法

// 初始化 Thread 类的新实例。
// < param name="start">无参委托对象.< /param>
// < param name="maxStackSize">使用的最大堆栈大小.< /param>
public Thread(ThreadStart start,int maxStackSize)

start

类型:System.Threading.ThreadStart
表示开始执行此线程时要调用的方法的 ThreadStart 委托。

maxStackSize

类型:System.Int32
线程要使用的最大堆栈大小(以字节为单位);如果为 0,则使用可执行文件的文件头中指定的默认最大堆栈大小。
重要事项:对于部分受信任的代码,如果 maxStackSize 大于默认堆栈大小,则将其忽略。 不引发异常。

void Start()
{
 //创建无参线程对象,限制256KB堆栈大小
 Thread thr = new Thread(Func_NoArguments,262144);
 //启动线程
 thr.Start();
}
// Function Of No Arguments.
void Func_NoArguments()
{
 Debug.Log("Run Func_NoArguments");
}

四、线程执行有参方法,限制线程要使用的最大堆栈大小

构造语法

// 初始化 Thread 类的新实例。
// < param name="start">有参委托对象.< /param>
// < param name="maxStackSize">使用的最大堆栈大小.< /param>
public Thread(ParameterizedThreadStart start,int maxStackSize)

start

类型:System.Threading.ParameterizedThreadStart
一个委托,它表示此线程开始执行时要调用的方法。
注意:参数只能有一个,且必须为object类型

maxStackSize

类型:System.Int32
线程要使用的最大堆栈大小(以字节为单位);如果为 0,则使用可执行文件的文件头中指定的默认最大堆栈大小。
重要事项:对于部分受信任的代码,如果 maxStackSize 大于默认堆栈大小,则将其忽略。 不引发异常。

实例

void Start()
{
 //创建有参线程对象,限制256KB堆栈大小
 Thread thr = new Thread(Func_Arguments,262144);
 //启动线程,传入参数
 thr.Start("Lanou");
}
// Function Of Have Arguments.
void Func_Arguments(object data)
{
 Debug.Log("Run Func_Arguments, Data = " + data);
}

启动线程(上文已使用)

无参启动

void Start()
{
 //创建无参线程对象
 Thread thr = new Thread(Func_NoArguments);
 //启动线程
 thr.Start();
}
// Function Of No Arguments.
void Func_NoArguments()
{
 Debug.Log("Run Func_NoArguments");
}

有参启动

void Start()
{
 //创建有参线程对象
 Thread thr = new Thread(Func_Arguments);
 //启动线程,传入参数
 thr.Start("Lanou");
}
// Function Of Have Arguments.
void Func_Arguments(object data)
{
 Debug.Log("Run Func_Arguments, Data = " + data);
}


常用方法

1.public static void Sleep( int millisecondsTimeout)将当前线程挂起指定的毫秒数。
(1)millisecondsTimeout
类型:System.Int32
挂起线程的毫秒数。 如果 millisecondsTimeout 参数的值为零,则该线程会将其时间片的剩余部分让给任何已经准备好运行的、有同等优先级的线程。 如果没有其他已经准备好运行的、具有同等优先级的线程,则不会挂起当前线程的执行。
(2)public void Resume()
继续已挂起的线程。(已过时)
(3)public void Abort()
在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。
(4)public void Join()
阻止调用线程直到线程终止,同时继续执行标准的 COM 和 SendMessage 传送。
(5)public enum ThreadPriority
指定 Thread 的调度优先级。

通过线程池执行线程

2.ThreadPool.QueueUserWorkItem 方法 (WaitCallback)
public static bool QueueUserWorkItem(WaitCallback callBack)
callBack
类型:System.Threading.WaitCallback
一个 WaitCallback,表示要执行的方法。
返回值
类型:System.Boolean
如果此方法成功排队,则为 true;如果无法将该工作项排队,则引发 NotSupportedException。

Unity使用多线程注意

变量都是共享的(都能指向相同的内存地址)
UnityEngine的API不能在分线程运行
UnityEngine定义的基本结构(int,float,Struct定义的数据类型)可以在分线程计算,如 Vector3(Struct)可以 , 但Texture2d(class,根父类为Object)不可以。
UnityEngine定义的基本类型的函数可以在分线程运行
Unity多线程插件

LOOM Multi Threading Framework 1.7 

核心方法

// Unlike "StartMultithreadedWorkloadExecution", you will have to build your own IThreadWorkerObject.
 // Downside: It requires some extra work. Upside: you got more controll over what goes in and comes out
 // Infact: You can create you own polymorphed IThreadWorkerObject-array, each ellement being a completely different type. For example: the statemachines of enemies are IThreadWorkerObject's and the array contains completely different classes with enemies/AI-behaviours.
 // < param name="workerObjects">An array of IThreadWorkerObject objects to be handled by the threads. If you want multiple cores/threads to be active, make sure that the number of IThreadWorkerObject's proves matches/exeeds your preferred number maxWorkingThreads. < /param>
 // < param name="onComplete">Fired when all re-packaged workLoad-objects are finished computing< /param>
 // < param name="onPackageExecuted">Fires foreach finished re-packaged set of workLoad-object< /param>
 // < param name="maxThreads"> Lets you choose how many threads will be run simultaneously by the threadpool. Default: -1 == number of cores minus one, to make sure the MainThread has at least one core to run on. (quadcore == 1 core Mainthread, 3 cores used by the ThreadPoolScheduler)< /param>
 // < param name="scheduler">If Null, a new ThreadPoolScheduler will be instantiated.< /param>
 // < param name="safeMode">Executes all the computations within try-catch events, logging it the message + stacktrace< /param>
 // < returns>A ThreadPoolScheduler that handles all the repackaged workLoad-Objects< /returns>
 public static ThreadPoolScheduler StartMultithreadedWorkerObjects(IThreadWorkerObject[] workerObjects, ThreadPoolSchedulerEvent onCompleteCallBack, ThreadedWorkCompleteEvent onPackageExecuted = null, int maxThreads = -1, ThreadPoolScheduler scheduler = null, bool safeMode = true)
{
  if (scheduler == null)
  scheduler = CreateThreadPoolScheduler();

 scheduler.StartASyncThreads(workerObjects, onCompleteCallBack, onPackageExecuted, maxThreads, safeMode);
 return scheduler;
}


结束语

Unity可以使用多线程,但对其有很多限制,所以在不使用UnityEngine API的情况下,可以使用多线程,提高多核CPU的使用率。通常可以将需要大量计算的算法内容,放置到多线程中执行,包括逻辑框架也可以放到多线程中执行。本篇理论性较强,后期会陆续发布实战型文章。

 类似资料:
  • 问题内容: 我想尝试一下Objective-C进行游戏编程。问题是我需要一些工具和库。 首先需要想到的是GUI和图形库。 我有什么选择? 问题答案: OpenStep / Cocoa类型的Objective C平台有四种非Mac实现: OpenStep / NextStep:仅Openstep / NeXT支持机器-停产。 p …可以记住名字或在网上找到它-它在某个地方!-Linux Cocotr

  • 并发是什么?引用Rob Pike的经典描述: 并发是同一时间应对多件事情的能力 其实在我们身边就有很多并发的事情,比如一边上课,一边发短信;一边给小孩喂奶,一边看电视,只要你细心留意,就会发现许多类似的事。相应地,在软件的世界里,我们也会发现这样的事,比如一边写博客,一边听音乐;一边看网页,一边下载软件等等。显而易见这样会节约不少时间,干更多的事。然而一开始计算机系统并不能同时处理两件事,这明显满

  • 面试官是一个年轻的小哥很帅,就是周围太嘈杂,有时候听不清在说什么 1. 自我介绍 2. 为什么想做游戏开发 3. 游戏开发的相关技术,想做哪方面的工作(引擎or客户端) 4. C++多态 5. C++内存模型,堆和栈的区别 6. 共享内存的使用需要注意什么 7. 进程和线程的区别 8. 进程间通信方式 9. 高并发有哪些好的处理方法 10. 数据库的索引类型 11. 两道智力题:三个门有一个有奖品

  • 本章讲解 Rust 中,并发,并行,多线程编程的相关知识。

  • 本文向大家介绍C#使用Parallel类进行多线程编程实例,包括了C#使用Parallel类进行多线程编程实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#使用 Parallel 类进行多线程编程的方法。分享给大家供大家参考。具体如下: 希望本文所述对大家的C#程序设计有所帮助。

  • 本文向大家介绍C#编程中常见数据结构的比较(Unity3D游戏开发),包括了C#编程中常见数据结构的比较(Unity3D游戏开发)的使用技巧和注意事项,需要的朋友参考一下 一.前言 Unity3D是如今最火爆的游戏开发引擎,它可以让我们能轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型的互动内容。它支持2D/3D游戏开发,据不完全统计,目前国内80%的手机游戏都是用Unity3D开发。 由