选择其中的Create Thread Exec Tick节点。
简单的使用案例如下。在该示例图中,除了Create Thread Exec Tick节点的节点都是演示用的节点,并不是本插件含有的节点。MainProcess1为前处理,MainProcess2为执行了该节点之后的后处理。DoAlgorithm即其他线程中执行的任务。CallBack是Loop跳出后执行的回调任务。
该使用案例将创建一个每次Tick执行一次算法函数的线程任务。算法函数返回一个是否完成的布尔值,用来判断是否打断循环tick、关闭线程并执行Completed。
上图是一个Tick内执行的主要内容的简化图。执行顺序从上到下。第一层结构是主要tick,向下一级是Tick内部不同的Tick组。这些Tick组将会串行执行。另外,这个主tick线是发生在游戏线程中的。
上图为在一个tick内,有多个部分tick先后执行。其中有关游戏逻辑的部分大多放在了PrePhysics到PostUpdateWork之间。
在各个Tick之间,有时UE也会进行垃圾回收(GC)。所以将重要的对游戏对象的操作放在除了允许计算游戏逻辑的tick组之外的地方执行往往会导致崩溃。
以下节点将会提供安全的在其他线程中执行游戏逻辑,但是其实现的方式也是基于与主Tick同步的方式。
节点引脚 | 描述 |
---|---|
默认执行输入 | 执行该引脚后会创建线程并执行(下同) |
bLongTask | 如果为真,则创建单独的线程。独立线程一般用于执行长任务。如果为假,则创建线程任务。其一般用于执行短任务。创建短任务线程时的性能消耗是最少的。(下同) |
ExecuteWhenPaused | 当游戏暂停时是否仍然继续执行 |
ThreadName | 自定义线程名称,如果未None,则为Pair默认值 |
TimingPair | 决定在一帧内执行时合适开始、合适结束的时机对 |
默认执行输出 | 创建线程后执行该引脚(下同) |
Execution | 线程创建后将执行一次该引脚 |
Completed | Execution执行完成后,将会在游戏主线程中执行该引脚 |
上图为CreateThreadExecOnce的执行时机。
你执行了该节点时,会先创建一个执行对象,但此时(LastTick)并不会立即执行任务。而是等待到下一次tick。到下一tick时(CurrentTick),会根据你在创建该线程任务时传入的参数(BeginIn、EndBefore)来控制任务的开始执行和确保结束。如图,根据传入的执行时机参数,我们在tick执行到PrePhysics时开始执行任务。于是在另一个线程里的任务就被触发开始执行了。
等执行到PostUpdateWork时,因为我们的EndBefore传入的参数是PostUpdateWork。所以这里会询问线程任务:是否执行完毕。如果执行完毕,则询问操作立即结束,紧接着tick继续执行。如果执行为完毕,则会等待,直到线程任务执行完毕,再返回,然后tick继续执行。
从上面可以看出有几个注意的点!
该宏节点是CreateThreadExecOnce的简化版。该节点确保不会被重复执行。即,当该节点执行一次后,会创建一个线程任务到下一个tick,直到创建的线程任务执行完毕之前,重复执行该节点将不做任何事。下同
节点引脚 | 描述 |
---|---|
GameThreadExec | 传入一个你想要在游戏线程中执行的委托 |
节点引脚 | 描述 |
---|---|
TickEnabled | 是否默认执行Tick,如果为true,创建线程后执行Tick。如果为false,则创建线程后不会执行Tick,直到该值为真。 |
TcikWhenPaused | 是否在游戏暂停时执行Tick |
bLongTask | 如果为真,则创建单独的线程。独立线程一般用于执行长任务。如果为假,则创建线程任务。其一般用于执行短任务。创建短任务线程时的性能消耗是最少的。(下同) |
ThreadName | 自定义线程名称,如果未None,则为默认值 |
TimingPair | 决定在一阵内执行时合适开始、合适结束的时机对 |
Behavior | Tick行为结构体。用于在执行时决定Tick的静动态执行次数。 |
Execution | 每一Tick执行的引脚 |
TickEnd | 在一次全部的Execution结束后,会执行的引脚 |
Completed | Tick跳出时执行的引脚 |
DeltaSeconds | Tick引脚附带的参数。表示当前Tick的变化时间。 |
TickHandle | TickHandle是这个线程Tick的对象引用。用于对该线程Tick进行控制。 |
执行时机其实和CreateThreadExecOnce差不多。只不过在执行完毕后会在下一tick继续重复操作。
名称 | 图示 | 描述 |
---|---|---|
BreakNextTick | ![]() | 打断下一次Tick并跳出。 |
IsTicking | ![]() | 是否正在执行任务 |
IsTickEnabled | ![]() | 获取线程Tick的可否Tick值。 |
SetTickEnabled | ![]() | 设置线程Tick可否Tick值。设置为真后将使其能执行Tick。设置为假后将使其不能被Tick。该值的真假并不影响该线程Tick的生命周期。 |
IsTickableWhenPaused | ![]() | 获取线程Tick的可否在游戏暂停时Tick的值。 |
SetTickableWhenPaused | ![]() | 设置线程Tick的可否在游戏暂停时Tick的值。 |
GetTimingPair | ![]() | 获取线程Tick的时机对 |
GetBehavior | ![]() | 获取线程Tick的行为定义 |
下面仅解释与CreateThreadExecTick不同的引脚
节点引脚 | 描述 |
---|---|
FirstIndex | 循环时的第一个循环的下标 |
LastIndex | 循环时的最后一个循环的下标 |
Index | 当前循环的下标 |
名称 | 图示 | 描述 |
---|---|---|
GetCurrent | ![]() | 获取线程Loop的当前下标 |
GetFirstIndex | ![]() | 获取线程Loop的开始下标 |
GetLastIndex | ![]() | 获取线程Loop的结束下标 |
不安全地执行一次。这个节点开发不完善,且有很多问题。注意使用!
它并没有上述的Once节点那样有跟游戏线程Tick同步的机制,所以他会无视掉这些直接强制执行线程任务。
如果你将一些游戏逻辑放进去,很可能会导致崩溃。
不建议使用。
同上,不建议使用。
同上,不建议使用。
名称 | 图示 | 描述 |
---|---|---|
GetCurrentThreadID | ![]() | 获取执行该节点的线程ID |
GetCurrentThreadName | ![]() | 获取执行该节点的线程名称 |
SetThreadName | ![]() | 设置当前线程的名称 |
IsGameThread | ![]() | 获取执行该节点的线程是否为游戏线程 |
IsGameThread | ![]() | 一个分支选项。条件是执行该节点的线程是否是游戏线程。 |
名称 | 图示 | 描述 |
---|---|---|
Get All Thread Exec Nodes | ![]() | 获取所有的线程执行节点,返回一个元素类型为ThreadAsyncExecBase引用的数组。目前版本该类型的引用没有什么可以调用的函数。 |
Get All Thread Exec Onces | ![]() | 获取所有的线程执行一次节点,返回一个元素类型为ThreadAsyncExecOnce引用的数组。 |
Get All Thread Exec Ticks | ![]() | 获取所有的线程执行一次节点,返回一个元素类型为ThreadAsyncExecTick引用的数组。 |
枚举值 | 解释 |
---|---|
PreActorTick | 在所有Actor进行tick之前 |
PrePhysics | 在进行物理模拟之前 |
DuringPhysics | 在进行物理模拟时 |
PostPhysics | 在进行物理模拟之后 |
PostUpdateWork | 在Tick完毕之前 |
PostActorTick | 在所有Actor进行Tick完毕之后 |
成员名 | 类型 | 解释 |
---|---|---|
BeginIn | EThreadTickTiming | 开始于…… |
EndBefore | EThreadTickTiming | 在……之前结束 |
成员名 | 类型 | 解释 |
---|---|---|
bDynamicExecPerTick | bool | 是否启用动态的每帧执行次数。如果启用,则每帧会执行多次,具体次数取决于可用耗时。会在线程Tick开始时持续重复执行,直到线程Tick结束时。 |
StaticExecTimes | int32 | bDynamicExecPerTick为false时有效。静态执行时固定的每帧执行次数。 |
PredictNextUsingPreExec | bool | bDynamicExecPerTick为true时有效。当执行一次时,是否要根据上次执行的耗时以及当前剩余可用耗时来预测是否要继续重复执行。 |
PredictedTimeCostFactor | float | bDynamicExecPerTick和PredictNextUsingPreExec均为true时有效。该值作为上次执行耗时的系数。值为1时,意味着将上次执行的时间作为参考,来预测剩余耗时是否能够允许再次一次。该值大于1时,将导致动态执行在一次tick内提前结束。该值小于1时,可能导致动态执行可能会稍微阻塞一下游戏线程,造成游戏线程闲置。 |