当前位置: 首页 > news >正文

做网站需要的服务器口碑营销案例2022

做网站需要的服务器,口碑营销案例2022,室内设计装修图,网站推广广告语目录 步骤 一、搭建基本同步框架 二、添加委托 三、添加蓝图互动框架 四、修改为异步框架 完整代码 通过一个游戏初始化流程的示例来介绍“ControlFlows”的基本使用。 步骤 一、搭建基本同步框架 1. 勾选“ControlFlows”插件 2. 新建一个空白C类,这里…

目录

步骤

一、搭建基本同步框架 

二、添加委托 

三、添加蓝图互动框架 

四、修改为异步框架

完整代码


通过一个游戏初始化流程的示例来介绍“ControlFlows”的基本使用。

步骤

一、搭建基本同步框架 

1. 勾选“ControlFlows”插件

2. 新建一个空白C++类,这里命名为“ControlFlowSubSystem” 

让“ControlFlowSubSystem” 继承“GameInstanceSubsystem”,然后添加反射所需代码

重写父类“ShouldCreateSubsystem”、“Initialize”和“Deinitialize”方法

3. 在Build.cs中添加“ControlFlows”模块

引入所需库

定义一个蓝图可调用的方法“InitLevel”,表示要执行的初始化流程;定义一个布尔类型变量“bIniting”用于表示当前是否处于初始化流程;再定义5个函数用于表示初始化流程的各个步骤。

“InitLevel”实现如下:

        首先,通过检查 bIniting 来判断当前是否已经处于初始化过程中。如果 bIniting 为 true,意味着初始化正在进行或者已经执行过了,此时输出一条日志信息然后直接返回,避免重复执行初始化流程。只有当 bIniting 为 false 时,才会将其设置为 true,表示即将开始初始化流程。

        第31行代码通过调用 FControlFlowStatics::Create 静态函数创建一个 FControlFlow 类型的控制流实例 Flow。在创建过程中,传入了 this 指针和一个字符串,这个字符串作为控制流的唯一标识符。 

        第33~37行代码通过多次调用 Flow.QueueStep 函数,向刚创建的控制流实例中依次添加了多个需要按顺序执行的步骤。

        第40行代码调用 Flow.ExecuteFlow() 函数启动控制流的执行。此时,FControlFlow 实例会按照之前添加步骤的顺序,依次调用对应的成员函数,确保整个初始化流程按照预定的顺序有条不紊地进行,直到所有步骤都执行完毕,完成整个初始化过程。

        用于表示初始化流程步骤的5个函数实现如下,当执行到最后一个步骤时。将 bIniting 改为 false,表示初始化流程已经结束。

4. 在关卡蓝图中调用“InitLevel”函数

执行结果如下,可以通过日志信息看到完整执行了整个初始化流程。

5. 为了观察每个步骤在哪一帧执行,可以通过添加如下代码实现:

运行结果如下,可以看到所有表示流程步骤的函数都是在同一帧执行的,这可能会造成游戏帧率下降,因此这并不符合我们的需求。

二、添加委托 

6. 下面先创建两个委托,通过委托来向外界传递任务进度等信息。

申明两个动态多播委托类型

        在第11行代码中,FControlFlows_InitProgress是要声明的委托类型的名称,FGuid 是UE中用于表示全局唯一标识符(GUID)的类型,在这里它作为委托参数的类型,而 InitAsyncID 是给这个参数起的变量名。当委托被调用时,会传递一个 FGuid 类型的全局唯一标识符。该委托在被调用时,还会传递一个表示进度值的浮点型数据,这个值可以用来直观地展示当前异步初始化任务已经完成的比例或者进度情况。

        在第12行代码中,FControlFlows_InitResult代表所声明的委托类型名称,FGuid 与InitAsyncID和前面的委托类似,bool 与 bResult用于指示异步初始化任务最终是成功还是失败,直观地告知结果状态。Message 表示委托调用时还会附带更详细的关于初始化结果的说明。

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FControlFlows_InitProgress, FGuid, InitAsyncID, float, ProgressValue);  //进度更新
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FControlFlows_InitResult, FGuid, InitAsyncID, bool, bResult, FString, Message);  //初始化结果

声明两个委托类型的成员变量,并且通过 UPROPERTY(BlueprintAssignable) 元数据标签对这两个属性进行修饰,使其具备了在蓝图系统中可被绑定具体的回调函数的特性。

 7. 为表示初始化步骤的5个成员函数添加进度值输入参数

8. 设置进行“InitLocalAsset”步骤时,初始化进度为10%;进行“InitNetInfo”步骤时,初始化进度为20%;进行“InitUserInfo”步骤时,初始化进度为50%;进行“NotifyMainUI”步骤时,初始化进度为80%;进行“FinishThisInit”步骤时,初始化进度为100%;

9. 声明InitAsyncID用于唯一标识某次初始化的异步任务

执行“InitLevel”函数进行初始化时为InitAsyncID赋值

当进行各初始化的步骤时,通过InitProgress委托广播当前的初始化进度,传入对应的InitAsyncID和本步骤的当前进度值InProgressValue,这样外部绑定了该委托的对象就能接收到进度更新情况。

在初始化流程的最后一个步骤对应的函数中,添加如下一行代码,通过InitResult委托广播当前的初始化结果。

三、添加蓝图互动框架 

10. 添加一个控件蓝图,用于显示当前初始化进度,这里命名为“WBP_ControlFlowsMainUI”

打开“WBP_ControlFlowsMainUI”,添加如下控件,主要是添加一个文本控件用于显示进度值,按钮用于调用“InitLevel”从而开始初始化

在事件构造和结构时分别绑定和解绑“InitProgress”、“InitResult”委托

重命名委托绑定的匹配函数为“UpdateProgress”和“InitResult”

匹配函数“UpdateProgress”和“InitResult”函数逻辑如下,将委托传递的GUID、进度值和初始化结果信息打印出来,并显示进度值。如果初始化成功后就将界面隐藏,如果失败就显示进度值为0.00

 当按钮点击后调用“InitLevel”开始初始化

 11. 在关卡蓝图中让界面显示出来

此时运行后界面如下

点击初始化按钮后打印信息如下:

此时就完成了初始化流程的同步框架实现,接下来我们希望将同步改为异步实现。

四、修改为异步框架

12. 引入所需头文件

13. 更改“InitLocalAsset”、“InitNetInfo”、“InitUserInfo”函数逻辑如下

主要通过使用AsyncTask函数创建了一个外层的异步任务,并指定其可以在任意线程上执行。在这个异步任务的 lambda 表达式内部首先调用FPlatformProcess::Sleep(0.2)模拟一个耗时操作,接着又创建了一个内层的异步任务,指定在游戏线程上执行后续的耗时操作,以及向外广播初始化的进度信息。

完善“InitUserInfo”逻辑如下

        第81行首先获取位于项目保存目录下的文件名为 ControlFlowsUserInfo.txt的目标文件相对路径,然后将相对路径转换为绝对路径。

        第82行将初始化任务的唯一标识 InitAsyncID 转换为字符串形式赋值给 UserInitAsyncID。

        第83行获取当前的日期时间并转换为 HTTP 日期格式赋值给 UserInitDataTime 。

        第84~86行创建一个 TArray<FString> 类型的数组 MyStringInfo,并将前面获取的UserInitAsyncID 和 UserInitDataTime 字符串添加进去,准备将这些信息保存到文件中。

        第87行使用 FFileHelper::SaveStringArrayToFile 函数将包含用户初始化相关信息的字符串数组 MyStringInfo 保存到指定路径 UserInfoPath 的 ControlFlowsUserInfo.txt中,并且指定了编码选项为ForceUTF8WithoutBOM,确保文件内容以指定的编码格式存储。

        编译后运行,此时当我们点击初始化按钮后,看到输出日志信息如下,可以发现初始化流程的步骤不再是一帧内执行的了。

并且在“Saved”文件夹中多了一个名为 ControlFlowsUserInfo.txt的文件

 ControlFlowsUserInfo.txt的内容如下,包括了初始化任务的唯一标识和文件存储时间。

如果初始化流程中的某一步失败了,通过 InitResult 委托向外广播初始化失败的结果信息,第113行调用 SubFlow->CancelFlow()标识取消当前正在执行的控制流,从而及时终止整个初始化流程。将 bIniting 变量设置为 false,表示当前不再处于初始化过程中,同时将 InitAsyncID 重置为默认值,为下一次可能的初始化操作做好准备。

完整代码

“ControlFlowSubSystem.h”

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "ControlFlow.h"
#include "ControlFlowManager.h"
#include "ControlFlowNode.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Async/Async.h"
#include "ControlFlowSubSystem.generated.h"DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FControlFlows_InitProgress, FGuid, InitAsyncID, float, ProgressValue);  //进度更新
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FControlFlows_InitResult, FGuid, InitAsyncID, bool, bResult, FString, Message);  //初始化结果#define INITRESULT falseUCLASS()
class STUDY_API UControlFlowSubSystem : public UGameInstanceSubsystem
{GENERATED_BODY()public:virtual bool ShouldCreateSubsystem(UObject* Outer) const override;virtual void Initialize(FSubsystemCollectionBase& Collection) override;virtual void Deinitialize() override;UFUNCTION(BlueprintCallable)void InitLevel();public:UPROPERTY(BlueprintAssignable)FControlFlows_InitProgress InitProgress;UPROPERTY(BlueprintAssignable)FControlFlows_InitResult InitResult;protected:bool bIniting = false;FGuid InitAsyncID = FGuid();void InitLocalAsset(FControlFlowNodeRef SubFlow, double InProgressValue);void InitNetInfo(FControlFlowNodeRef SubFlow, double InProgressValue);void InitUserInfo(FControlFlowNodeRef SubFlow, double InProgressValue);void NotifyMainUI(FControlFlowNodeRef SubFlow, double InProgressValue);void FinishThisInit(FControlFlowNodeRef SubFlow, double InProgressValue);
};

“ControlFlowSubSystem.cpp” 

// Fill out your copyright notice in the Description page of Project Settings.#include "ControlFlowSubSystem.h"bool UControlFlowSubSystem::ShouldCreateSubsystem(UObject* Outer) const
{return true;
}void UControlFlowSubSystem::Initialize(FSubsystemCollectionBase& Collection)
{Super::Initialize(Collection);
}void UControlFlowSubSystem::Deinitialize()
{Super::Deinitialize();
}void UControlFlowSubSystem::InitLevel()
{if (bIniting){UE_LOG(LogTemp, Warning, TEXT("Initing..."));return;}InitAsyncID = FGuid::NewGuid();bIniting = true;uint64 FrameIndex = GFrameCounter;UE_LOG(LogTemp, Warning, TEXT("InitFlow -- FrameIndex: %d"), FrameIndex);FControlFlow& Flow = FControlFlowStatics::Create(this, TEXT("ControlFlow_InitLevel"));Flow.QueueStep(TEXT("InitLocalAsset"), this, &UControlFlowSubSystem::InitLocalAsset, 0.1);Flow.QueueStep(TEXT("InitNetInfo"), this, &UControlFlowSubSystem::InitNetInfo, 0.2);Flow.QueueStep(TEXT("InitUserInfo"), this, &UControlFlowSubSystem::InitUserInfo, 0.5);Flow.QueueStep(TEXT("NotifyMainUI"), this, &UControlFlowSubSystem::NotifyMainUI, 0.8);Flow.QueueStep(TEXT("FinishThisInit"), this, &UControlFlowSubSystem::FinishThisInit, 1.0);UE_LOG(LogTemp, Warning, TEXT("ExecuteFlow -- FrameIndex: %d"), FrameIndex);Flow.ExecuteFlow();
}void UControlFlowSubSystem::InitLocalAsset(FControlFlowNodeRef SubFlow, double InProgressValue)
{uint64 FrameIndex = GFrameCounter;UE_LOG(LogTemp, Warning, TEXT("InitLocalAsset -- FrameIndex: %d"), FrameIndex);AsyncTask(ENamedThreads::AnyThread, [this, SubFlow, InProgressValue]() {FPlatformProcess::Sleep(0.2);AsyncTask(ENamedThreads::GameThread, [this, SubFlow, InProgressValue]() {FPlatformProcess::Sleep(0.2);InitProgress.Broadcast(InitAsyncID, InProgressValue);SubFlow->ContinueFlow();});});
}void UControlFlowSubSystem::InitNetInfo(FControlFlowNodeRef SubFlow, double InProgressValue)
{uint64 FrameIndex = GFrameCounter;UE_LOG(LogTemp, Warning, TEXT("InitNetInfo -- FrameIndex: %d"), FrameIndex);AsyncTask(ENamedThreads::AnyThread, [this, SubFlow, InProgressValue]() {FPlatformProcess::Sleep(0.2);AsyncTask(ENamedThreads::GameThread, [this, SubFlow, InProgressValue]() {FPlatformProcess::Sleep(0.2);InitProgress.Broadcast(InitAsyncID, InProgressValue);SubFlow->ContinueFlow();});});
}void UControlFlowSubSystem::InitUserInfo(FControlFlowNodeRef SubFlow, double InProgressValue)
{uint64 FrameIndex = GFrameCounter;UE_LOG(LogTemp, Warning, TEXT("InitUserInfo -- FrameIndex: %d"), FrameIndex);AsyncTask(ENamedThreads::AnyThread, [this, SubFlow, InProgressValue]() {FPlatformProcess::Sleep(0.2);FString UserInfoPath = FPaths::ConvertRelativePathToFull(FPaths::ProjectSavedDir()/TEXT("ControlFlowsUserInfo.txt"));FString UserInitAsyncID = InitAsyncID.ToString();FString UserInitDataTime = FDateTime::Now().ToHttpDate();TArray<FString> MyStringInfo;MyStringInfo.Add(UserInitAsyncID);MyStringInfo.Add(UserInitDataTime);FFileHelper::SaveStringArrayToFile(MyStringInfo, *UserInfoPath, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM);AsyncTask(ENamedThreads::GameThread, [this, SubFlow, InProgressValue]() {FPlatformProcess::Sleep(0.2);InitProgress.Broadcast(InitAsyncID, InProgressValue);SubFlow->ContinueFlow();});});
}void UControlFlowSubSystem::NotifyMainUI(FControlFlowNodeRef SubFlow, double InProgressValue)
{uint64 FrameIndex = GFrameCounter;UE_LOG(LogTemp, Warning, TEXT("NotifyMainUI -- FrameIndex: %d"), FrameIndex);if (INITRESULT){InitProgress.Broadcast(InitAsyncID, InProgressValue);SubFlow->ContinueFlow();}else{AsyncTask(ENamedThreads::GameThread, [this]() {InitResult.Broadcast(InitAsyncID, false, TEXT("Init Failed"));});SubFlow->CancelFlow();bIniting = false;InitAsyncID = {};}
}void UControlFlowSubSystem::FinishThisInit(FControlFlowNodeRef SubFlow, double InProgressValue)
{uint64 FrameIndex = GFrameCounter;UE_LOG(LogTemp, Warning, TEXT("FinishThisInit -- FrameIndex: %d"), FrameIndex);InitProgress.Broadcast(InitAsyncID, InProgressValue);InitResult.Broadcast(InitAsyncID, true, TEXT("Init Success"));SubFlow->ContinueFlow();bIniting = false;InitAsyncID = {};
}
http://www.hkea.cn/news/426842/

相关文章:

  • 计算机毕设网站建设怎么改长沙网站设计拓谋网络
  • 类似红盟的网站怎么做aso优化推广
  • vs2013做网站怎样制作免费网页
  • b2c网站的开发无锡网络优化推广公司
  • 网站做视频在线观看营销活动推广方案
  • wordpress多站点统计google图片搜索引擎入口
  • 麻章手机网站建设百度网盘提取码入口
  • 网站后台管理系统的重要技术指标sem竞价托管费用
  • 包头怎样做网站我想做电商怎么加入
  • 株洲企业网站建设品牌2023免费b站推广大全
  • 仿制单页面网站多少钱免费制作网站app
  • 商城网站制作网站长尾词挖掘工具
  • 夹克定制公司trinseo公司
  • 四川智能网站建设制作网站链接分析工具
  • 制作销售网站有哪些宁波网络营销推广咨询报价
  • 佛山做外贸网站服务新闻发稿平台
  • 做网站前怎么写文档域名收录
  • 中信建设有限责任公司钟宁关键词优化的方法有哪些
  • 建站之星平台优化推广网站排名
  • wordpress 网盘 插件郑州seo外包阿亮
  • 怎样建设网站首页广告营销平台
  • wordpress调起淘宝app什么叫做seo
  • 嘉兴做网站优化的公司网站维护公司
  • css层叠样式会不会影响打开网站的速度百度免费下载安装百度
  • 网站模板制作流程nba交易最新消息汇总
  • 近的网站在线客服系统网络优化工程师前景如何
  • 网站制作职业google入口
  • 广州网站 制作信科便宜网络营销软文范例500
  • 网站建设公开课长沙网站推广和优化
  • 建设网站的需求分析俄罗斯搜索引擎yandex推广入口