使用UE4 C++ 执行UGameplayStatics::OpenLevel() 耗时太久
求一个使用C++代码异步执行切换关卡并有进度值显示的例子代码 求个解决办法额
求一个使用C++代码异步执行切换关卡并有进度值显示的例子代码 求个解决办法额
【以下回答由 GPT 生成】
首先,我们需要创建一个异步任务类来执行切换关卡的操作,并提供一个方法来获取进度值。下面是一个简单的示例代码:
#include "AsyncTaskSwitchLevel.h"
#include "Engine/LevelStreaming.h"
// 定义一个异步任务类
class FAsyncTaskSwitchLevel : public FNonAbandonableTask
{
public:
// 构造函数,传入需要切换的关卡名称
FAsyncTaskSwitchLevel(const FString& InLevelName)
: LevelName(InLevelName)
, bIsDone(false)
{
}
// 实现执行任务的方法
void DoWork()
{
// 切换关卡的逻辑
UGameplayStatics::OpenLevel(GWorld, FName(*LevelName), false);
// 标记任务已完成
bIsDone = true;
}
// 实现获取进度值的方法
float GetProgress() const
{
// 根据切换关卡的进度返回进度值
// 这里简单返回一个固定的值,实际可以根据具体需求进行实现
return 0.5f;
}
// 指定任务的类型
TStatId GetStatId() const
{
RETURN_QUICK_DECLARE_CYCLE_STAT(FAsyncTaskSwitchLevel, STATGROUP_ThreadPoolAsyncTasks);
}
// 判断任务是否已完成的标志
bool IsDone() const
{
return bIsDone;
}
private:
FString LevelName;
bool bIsDone;
};
在你希望进行异步关卡切换的地方,可以通过以下方式来调用异步任务类:
// 创建一个任务指针
TSharedPtr<FAsyncTaskSwitchLevel, ESPMode::ThreadSafe> AsyncTask = MakeShareable(new FAsyncTaskSwitchLevel("LevelName"));
// 将任务添加到异步任务管理器中并开始执行
AsyncTaskManager.AddTask(AsyncTask.ToSharedRef());
// 循环检查任务是否完成
while (!AsyncTask->IsDone())
{
// 获取任务的进度值,并进行相应的处理
float Progress = AsyncTask->GetProgress();
// 显示进度值
UE_LOG(LogTemp, Warning, TEXT("Progress: %f"), Progress);
// 延时一段时间(可选)
FPlatformProcess::Sleep(0.1f);
}
// 关卡切换完成
这样,就可以通过异步任务类来进行关卡切换,并且在切换的过程中获取到进度值进行显示。
上述代码中的 AsyncTaskManager
是一个异步任务管理器,用来管理所有的异步任务。你可以根据自己的需求来实现一个异步任务管理器,或者使用 Unreal Engine 提供的工具类 FTaskGraphInterface
。
class FAsyncTaskManager
{
public:
// 添加任务到管理器并开始执行
void AddTask(TWeakPtr<FAsyncTaskSwitchLevel> InTask)
{
if (InTask.IsValid())
{
TaskList.Add(InTask);
FTaskGraphInterface::Get().GetNamedTaskGraph().AddTask(InTask.Pin().ToSharedRef(), ENamedThreads::GameThread);
}
}
// 检查是否还有任务在执行
bool HasPendingTasks() const
{
for (auto Task : TaskList)
{
if (Task.IsValid() && !Task.Pin()->IsDone())
{
return true;
}
}
return false;
}
private:
TArray<TWeakPtr<FAsyncTaskSwitchLevel>> TaskList;
};
下面是一个完整的实例代码,展示了如何使用异步任务类来切换关卡并显示进度值:
#include "AsyncTaskSwitchLevel.h"
#include "Engine/LevelStreaming.h"
// 定义一个异步任务类
class FAsyncTaskSwitchLevel : public FNonAbandonableTask
{
public:
// 构造函数,传入需要切换的关卡名称
FAsyncTaskSwitchLevel(const FString& InLevelName)
: LevelName(InLevelName)
, bIsDone(false)
{
}
// 实现执行任务的方法
void DoWork()
{
// 切换关卡的逻辑
UGameplayStatics::OpenLevel(GWorld, FName(*LevelName), false);
// 标记任务已完成
bIsDone = true;
}
// 实现获取进度值的方法
float GetProgress() const
{
// 根据切换关卡的进度返回进度值
// 这里简单返回一个固定的值,实际可以根据具体需求进行实现
return 0.5f;
}
// 指定任务的类型
TStatId GetStatId() const
{
RETURN_QUICK_DECLARE_CYCLE_STAT(FAsyncTaskSwitchLevel, STATGROUP_ThreadPoolAsyncTasks);
}
// 判断任务是否已完成的标志
bool IsDone() const
{
return bIsDone;
}
private:
FString LevelName;
bool bIsDone;
};
class FAsyncTaskManager
{
public:
// 添加任务到管理器并开始执行
void AddTask(TWeakPtr<FAsyncTaskSwitchLevel> InTask)
{
if (InTask.IsValid())
{
TaskList.Add(InTask);
FTaskGraphInterface::Get().GetNamedTaskGraph().AddTask(InTask.Pin().ToSharedRef(), ENamedThreads::GameThread);
}
}
// 检查是否还有任务在执行
bool HasPendingTasks() const
{
for (auto Task : TaskList)
{
if (Task.IsValid() && !Task.Pin()->IsDone())
{
return true;
}
}
return false;
}
private:
TArray<TWeakPtr<FAsyncTaskSwitchLevel>> TaskList;
};
void SwitchLevelWithProgress()
{
// 创建一个任务指针
TSharedPtr<FAsyncTaskSwitchLevel, ESPMode::ThreadSafe> AsyncTask = MakeShareable(new FAsyncTaskSwitchLevel("LevelName"));
// 创建一个异步任务管理器
FAsyncTaskManager AsyncTaskManager;
// 将任务添加到异步任务管理器中并开始执行
AsyncTaskManager.AddTask(AsyncTask.ToSharedRef());
// 循环检查任务是否完成
while (AsyncTaskManager.HasPendingTasks())
{
// 获取任务的进度值,并进行相应的处理
float Progress = AsyncTask->GetProgress();
// 显示进度值
UE_LOG(LogTemp, Warning, TEXT("Progress: %f"), Progress);
// 延时一段时间(可选)
FPlatformProcess::Sleep(0.1f);
}
// 关卡切换完成
}
以上就是一个实现在 UE4 C++ 中使用异步操作切换关卡并显示进度值的示例代码。希望对你有帮助!如果还有其他问题,请随时提问。