在项目打开距离场功能,异步构建距离场时,右下角的通知信息框会显示需要编译的数量进度,Compiling Shaders同样也是的,接下来我们就探索一下引擎是怎么实现的,以DistanceField编译为例,参考环境UE4.26源码版
- 显示效果
- FTickableEditorObject类分析
/**
- 该类对于在游戏线程编辑器状态下,仅需要Tick的对象提供方便
- 派生类需要实现Tick、GetStatId、GetTickableTickType方法
- 如果Runtime下也想有这样的功能,请参考FTickableGameObject类,并实现相应的方法
通过堆栈我们不难发现,FTickableEditorObject类就是在引擎初始化后注册的Tick对象资源
- FDistanceFieldBuildNotificationImpl探索
void FDistanceFieldBuildNotificationImpl::Tick(float DeltaTime)
{
if (GDistanceFieldAsyncQueue)
{
// Trigger a new notification if we are doing an async build, and we haven't displayed the notification recently
if (GDistanceFieldAsyncQueue->GetNumOutstandingTasks() > 0
&& !DistanceFieldNotificationPtr.IsValid()
&& (FPlatformTime::Seconds() - LastEnableTime) > 5)
{
DistanceFieldBuildStarted();
}
// Disable the notification when we are no longer doing an async compile
else if (GDistanceFieldAsyncQueue->GetNumOutstandingTasks() == 0 && DistanceFieldNotificationPtr.IsValid())
{
DistanceFieldBuildFinished();
}
else if (GDistanceFieldAsyncQueue->GetNumOutstandingTasks() > 0 && DistanceFieldNotificationPtr.IsValid())
{
TSharedPtr<SNotificationItem> NotificationItem = DistanceFieldNotificationPtr.Pin();
if (NotificationItem.IsValid())
{
FFormatNamedArguments Args;
Args.Add( TEXT("BuildTasks"), FText::AsNumber( GDistanceFieldAsyncQueue->GetNumOutstandingTasks() ) );
FText ProgressMessage = FText::Format(NSLOCTEXT("DistanceFieldBuild", "DistanceFieldBuildInProgressFormat", "Building Mesh Distance Fields ({BuildTasks})"), Args);
NotificationItem->SetText( ProgressMessage );
}
}
}
}
理解了FTickableEditorObject类工作原理,我们再回头看FDistanceFieldBuildNotificationImpl就很好读懂了,主要就是在Tick函数里面,有异步构建任务就会创建一个通知信息框并更新上面的异步任务数量状态信息,没有异步任务了就修改通知信息框的状态并释放这块内存
- 注册FDistanceFieldBuildNotificationImpl
- 解注册FDistanceFieldBuildNotificationImpl
这是C语言的写法,一般我们在自己插件的StartupModule启动模块和ShutdownModule关闭模块中去注册和解注册就可以了
- Compiling Shaders参考FShaderCompilingNotificationImpl类,更多通知信息框玩法引擎搜索FNotificationInfo研究学习即可