Unreal Engine 4学习笔记之多线程任务创建

发表于2017-02-13
评论0 978浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594
  为什么游戏会出现卡顿,是因为游戏的主线程中有一个很复杂的运算,那么怎么去解决这个问题呢,这就是接下来要给大家说的Unreal Engine 4中多线程任务创建的方法,一起来看看吧。
  
  函数构建
  
  新建一个AActor,加入如下函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Header file.
protected:
 
    /* Calculates prime numbers in the game thread */
    UFUNCTION(BlueprintCallable, Category = MultiThreading)
    void CalculatePrimeNumbers();
 
    /* Calculates prime numbers in a background thread */
    UFUNCTION(BlueprintCallable, Category = MultiThreading)
    void CalculatePrimeNumbersAsync();
 
    /* The max prime number */
    UPROPERTY(EditAnywhere, Category = MultiThreading)
    int32 MaxPrime;
  
  新建一个FuntionLibrary,在其中加入CalculatePrimeNumbers函数,用于计算结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// MainFunctionLibrary.cpp
 
void UMainFunctionLibrary::CalculatePrimeNumbers(int32 UpperLimit)
{
    //Calculating the prime numbers...
    for (int32 i = 1; i <= UpperLimit; i++)
    {
        bool isPrime = true;
        for (int32 j = 2; j <= i / 2; j++)
        {
            if (FMath::Fmod(i, j) == 0)
            {
                isPrime = false;
                break;
            }
        }
 
        if (isPrime)
            GLog->Log("Prime number #" + FString::FromInt(i) + ": " + FString::FromInt(i));
    }
}
  
  接着在Actor中添加CalculatePrimeNumbers函数:
1
2
3
4
5
void AMultiThreadingActor::CalculatePrimeNumbers()
{
    //Performing the prime numbers calculations in the game thread...
    UMainFunctionLibrary::CalculatePrimeNumbers(MaxPrime);
}
  
  并且添加一个CalculatePrimeNumbersAsync函数的空实现。在编译通过之后,在Actor的继承BP中添加操作如下:
  
  Task的创建
  
  提到多线程就一定是Tasks。在这里我们创建一个在另一个线程中执行CalculatePrimeNumbers函数的类。
  
  在这里我们需要新添加一个类继承自FNonAbandonableTask的类(可以阅读引擎源代码查看该类的详细信息)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class PrimeCalculationAsyncTask : public FNonAbandonableTask
{
    int32 MaxPrime;
 
public:
    /*Default constructor*/
    PrimeCalculationAsyncTask(int32 MaxPrime)
    {
        this->MaxPrime = MaxPrime;
    }
 
    /*This function is needed from the API of the engine.
    My guess is that it provides necessary information
    about the thread that we occupy and the progress of our task*/
    FORCEINLINE TStatId GetStatId() const
    {
        RETURN_QUICK_DECLARE_CYCLE_STAT(PrimeCalculationAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
    }
 
    /*This function is executed when we tell our task to execute*/
    void DoWork()
    {
        UMainFunctionLibrary::CalculatePrimeNumbers(MaxPrime);
    }
};
  
  RETURN_QUICK_DECLARE_CYCLE_STAT宏函数就是用于处理线程池相关的信息,而DoWork函数则是进行函数的调用。
  
  因此在这里就可以在CalculatePrimeNumbersAsync函数中来进行调用了。需要注意的是我们需要创建一个FAutoDeleteAsyncTask来进行对应的操作,它能够保证在task完成后把自己删除。
1
2
3
4
5
6
void AMultiThreadingActor::CalculatePrimeNumbersAsync()
{
    auto task = new FAutoDeleteAsyncTask(MaxPrime);
    if (task)
        task -> StartBackgroundTask();
}

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台