Comments (6)
APP开发的GamePlay
UAPPGameInstance
Init()
初始化全局配置表
创建客户端实例
反射类注册
初始化客户端
Tick()
监测Tick
Shutdown()
销毁(Destroy)
GetStatId()
GetClient()
AAPPGameModeBase
AAPPGameStateBase
AAPPPlayController
BeginPlay()
控制台程序ConsoleCommand设置初始尺寸
Tick()
协程Tick(DetaTime)
EndPlay()
GThread::Destroy()
AAPPPlayerState
AAPPPawn
Data
UserData
APPData
Network
UAppClientObjectController
Init()
Tick()
Close()
RecvProtocol()
Protocols
LoginProtocols
Login
LoginSuccess
LoginFailed
Unregistered
WrongPassword
HallProtocols
GateLoginSucessful
HomePage
HomePageRequestSuccessful
HomePageRequestFailed
ProjectRequest
ProjectRequestSuccessful
ProjectRequestFailed
SubmitComments
SubmitCommentsSuccessful
SubmitCommentsFailed
GetComments
GetCommentsSuccessful
GetCommentsFailed
GetUser
GetUserSuccessful
GetUserFailed
AAPPHUD
AAllPlatformAPPHUD()
if PLATFORM_WINDOWS || PLATFORM_MAC
elif PALTFORM_IOS || PLATFORM_ANDROID
BeginPlay()
HomePagePtr->AddToViewport()
TSubclassOf<UUI_HomePage> HomePageClass
TWeakObjectPtr<UUI_HomePage> HomePagePtr
UI
UI_Base
构造UUI_Base(const FObjectInitializer& ObjectInitializer)
RecvProtocol()
循环绑定BindClientRecv()
绑定RecvProtocol()
协程循环执行BindClientRecv()
SetParent()
GetParent()
UWidget* MyParent
UI_Login
(UPROPERTY)UEditableTextBox* Account
(UPROPERTY)UEditableTextBox* Password
(UPROPERTY)UButton* SignInButton
(UPROPERTY)UButton* SignUpButton
(UPROPERTY)UTextBlock* LoginMes
NativeConstruct()
绑定Button
BindClientRecv()
解密本地账户DecryptionUser()
NativeDestruct()
IsAccountValid()
IsPasswordValid()
SignInGame()
SignUpGame()
LoginMsg()
DecryptionUser()
解密
自动登录:协程绑定SignInGame()
AES加密EncryptionUser()
RecvProtocol()接收服务器发送过来的协议
LoginSuccess
接收FNetUserInfo UserInfo
*FClientUserData::Get() = UserInfo
加密本地密码EncryptionUser()
LoginCallback()登录回调
接收网关地址
关闭原通道
从登录服务器切换到网关服务器(Init())
BindClientRecv()重新绑定
绑定主页
GateLoginSucessful
发送HomePage请求给网关
LoginCallback()登录回调
SetVisibility(Collapsed)
UI_HomePage
UPROPERTY(meta = (BindWidget))UButton* HomePageButton
(UPROPERTY)UUI_Login* LoginWidget
(UPROPERTY)UUI_Navigation* NavigationWidget
(UPROPERTY)UUI_Menu* MenuWidget
(UPROPERTY)UImage* LoaddingImage
(UPROPERTY)UScrollBox* ScrollListBox
(UPROPERTY)TSubclassOf<UUI_HomeDetailPage> HomeDetailPage
(UPROPERTY)TSubclassOf<UUI_ProjectDetailPage> ProjectDetailPage
TSubclassOf<UUI_UserDetailPage> UserDetailPage
NativeConstruct()
SetParent(this)
LoaddingImage协程GetCoroutines()3s后Collapsed
HomePageButton->OnClicked.AddDynamic(HomePage())
NativeDestruct()
RecvProtocol()
HomePageRequestSuccessful
接收网关服务器的数据SIMPLE_PROTOCOLS_RECEIVE
导航InitButtons()
菜单
首页详情页HomeDetailPage
InHomeDetailPage = CreateWidget<UUI_HomeDetailPage>
InHomeDetailPage->SetParent(this)
WidgetReplace(InHomeDetailPage)
InHomeDetailPage->InitHomeDetailPage()
SP_ProjectRequestSuccessful
接收网关服务器的数据SIMPLE_PROTOCOLS_RECEIVE
InProjectDetailPage =
CreateWidget<UUI_ProjectDetailPage>
InProjectDetailPage->SetPostID()
InProjectDetailPage->SetParent(this)
WidgetReplace(InProjectDetailPage)
InProjectDetailPage->InitProjectDetailData()
SP_GetUser
接收网关服务器的数据SIMPLE_PROTOCOLS_RECEIVE
InUserDetailPage = CreateWidget<UUI_UserDetailPage>
InUserDetailPage->SetParent(this)
WidgetReplace(InUserDetailPage)
InUserDetailPage->InitUserDetailPage()
WidgetReplace()
ScrollListBox->ClearChildren()
ScrollListBox->AddChild(InReplaceWidget)
CreateProjectDetailPages()
向服务器发送请求SEND_DATA(SP_ProjectRequest, InID)
ScrollListBox->ClearChildren()
CreateUserDetailPage()
向服务器发送请求SEND_DATA(SP_GetUser, FClientUserData::Get()->UserID)
ScrollListBox->ClearChildren()
UFUNCTION() HomePage()
SEND_DATA(SP_HomePage)
ScrollListBox->ClearChildren()
NavigationWidget->CleanBox()
UI_ProjectPageList
UI_List
(UPROPERTY)UHorizontalBox* BoxList
(UPROPERTY)TSubclassOf<UUI_Node> NodeClass
RecvProtocol()
InitResources()UI_Node* InNode -》Init
BoxList-》AddChildToHorizontalBox(InNode)
InitFrameworks()
UI_Node* InNode -》Init
BoxList-》AddChildToHorizontalBox(InNode)
CreateResourceNode()
InNode = CreateWidget()
InNode->InitNodeName
InNode->InitContent
InNode->InitPrice
InNode->InitID
InNode->SetParent
InNode->StartThumbnail
InFun(InNode)
UI_Node
(UPROPERTY)UTextBlock* NodeName
(UPROPERTY)UTextBlock* Content
(UPROPERTY)UTextBlock* Price
(UPROPERTY)UImage* Thumbnail
(UPROPERTY)UButton* LinkButton
InitNodeName()
InitContent()
InitPrice()
InitID()
InitThumnail()
StartThumbnail()
UFUNCTION() DownloadComplete()
UFUNCTION() OnLinked()InHomePage = GetParent<UUI_HomePage>()
InHomePage->CreateProjectDetailPages(NodeID)
UI_InebrietyList
UI_FrameworkPageList
Common
UI_Menu
UButton* UserButton
NativeConstruct()UserButton->OnClicked.AddDynamic(OnLinked)
OnLinked()
InHomePage = GetParent<UUI_HomePage>()
InHomePage->CreateUserDetailPage()
UI_Navigation
(UPROPERTY)UWrapBox* Box;
(UPROPERTY)TSubclassOf<UUI_Button> ButtonClass
InitButtons()
NativeConstruct()
NativeDestruct()
void CleanBox()Box->ClearChildren()
Element
UI_Button
(UPROPERTY)UTextBlock* ButtonName
(UPROPERTY)UButton* ButtonWidget
UFUNCTION() OnClicked()
NativeConstruct()
ButtonWidget绑定OnClicked
SetID()
SetButtonName()
UI_Slide
(UPROPERTY)UFilmstrip* FilmstripInst
(UPROPERTY)UButton* NestButton
(UPROPERTY)UButton* PreviousButton
NativeConstruct()FilmstripInst->OnClickedLinkEvent绑定敲击事件 Link()
NestButton->OnClicked
PreviousButton->OnClicked
InitFilmstrip()
从NetFilmstrips中提取ImgURL
HTTP代理绑定下载
UFUNCTION() DownloadComplete()
图片转换Uint8ArrayToTexture2D
FilmstripLinkInfos.Texture赋值
FilmstripLinkInfos.LinkURL赋值
UFUNCTION() AllDownloadComplete()
FilmstripInst->AddTextures()
UFUNCTION() Link()
UFUNCTION() Nest()FilmstripInst->Nest()
UFUNCTION() Previous()
FilmstripInst->Previous()
(UPROPERTY)TArray FilmstripLinkInfos
FNetFilmstrips NetFilmstrips
UFilmstrip插件
(UPROPERTY)TArray LinkInfo
(UPROPERTY)float ShowTime
(UPROPERTY)float ChangeTime
(UPROPERTY)FFilmstripPlayType FilmstripPlayType
(UPROPERTY)FOnClickedLinkEvent OnClickedLinkEvent定义动态多播代理敲击事件
UFilmstrip()构造
初始化ShowTime
初始化ChangeTime
初始化FilmstripPlayType
初始化裁剪模式clipping
UFUNCTION() InitResources()
判断时间句柄是否有效Handle.IsValid()
ClearTimer(Handle)
判断LinkInfo是否有值
AddTextures()
UFUNCTION()AddTextures()
判断MyFilmstrip是否有效
MyFilmstrip->ClearChildren()
Brushs.Empty()
遍历AddTexture()
UFUNCTION()Previous()
MyFilmstrip->Previous()
UFUNCTION()Nest()
MyFilmstrip->Nest()
AddTexture()
添加图片
设置图片格式
MyFilmstrip设置图片和LinkURL
SlateHandleLinkClicked()
OnClickedLinkEvent.Broadcast()执行动态多播代理敲击事件广播
virtual TSharedRef RebuildWidget() override
初始化MyFilmstrip
ShowTime
ChangeTime
PlayStyle
OnLinkClicked代理绑定SlateHandleLinkClicked()
SetTimer(Handle, this, &UFilmstrip::InitResources, 0.1f)
返回MyFilmstrip共享引用
virtual void ReleaseSlateResources(bool bReleaseChildren)
MyFilmstrip.Reset()
Brushs.Empty()
ClearTimer(Handle)
TSharedPtr MyFilmstrip
TArray Brushs
FTimerHandle Handle
FilmstripPlayType
FilmstripPlayType
Default
Surround
FilmstripLinkInfo
(UPROPERTY)UTexture2D* Texture
(UPROPERTY)FString Link
SFilmstrip
SLATE_ARGS
SLATE_BEGIN_ARGS
_ShowTime
_ChangeTime
_PlayStyle
SLATE_ARGUMENT
ShowTime
ChangeTime
PlayStyle
SLATE_EVENT
OnLinkClicked
SLATE_END_ARGS
Construct()
ShowTime = InArgs._ShowTime
ChangeTime = InArgs._ChangeTime
PlayStyle = InArgs._PlayStyle
OnLinkClicked = InArgs._OnLinkClicked
SetImage()
TSharedPtr Image = SNew(SImage);
Image->SetImage(InImage);
获取数量
设置位置
设置图片大小
收集Slot
SNew(SButton)
OnClicked绑定OnClickedLinked()
ContentPadding(FMargin())
HAlign(EHorizontalAlignment::HAlign_Fill)
VAlign(EVerticalAlignment::VAlign_Fill)
Content()
Image.ToSharedRef()
设置Slot当前阶段
OnPaint()
PlayType::Default
PlayType::Surround
Previous()
Nest()
TArray MySlots
OnClickedLinked()
执行OnLinkClicked.Execute()
单播代理FOnLinkClicked OnLinkClicked
float ShowTime
float ChangeTime
FFilmstripPlayType PlayStyle
float ChangeDeltaTime
bool bHasImage
bool bFlip
FDrawElement
FSlot* Slot
float CurrentStage
float ShowTimeCount
float EndStage
float StartPos
细节面板
UI_HomeDetailPage
(UPROPERTY)UUI_Slide* SlideWidget
(UPROPERTY)UUI_List* ProjectWidget
(UPROPERTY)UUI_List* FrameworkWidget
(UPROPERTY)UUI_List* InebrietyWidget
NativeConstruct()
SetParent(this)
InitHomeDetailPage()
SlideWidget->InitFilmstrip()
ProjectWidget->InitResources()
InebrietyWidget->InitResources()
FrameworkWidget->InitFrameworks()
UI_ProjectDetailPage
(UPROPERTY)
UUI_TutoriaSystem* Video
UImage* AuthorAvatar
UTextBlock* AuthorIntroduce
UButton* BuyButton
UCheckBox* DocumentBox
UCheckBox* DownloadBox
UCheckBox* CommentBox
UCheckBox* VideoCatalogueBox
UWidgetSwitcher* Switcher
UUI_ArticleDisplayPage* ArticleDisplayPage
UUI_CatalogueDisplayPage* CatalogueDisplayPage
UUI_CommentDisplayPage* CommentDisplayPage
UUI_DownloadDisplayPage* DownloadDisplayPage
NativeConstruct()
AddDynamic()
Boxs.Add()
SetParent(this)
InitProjectDetailData()
AuthorIntroduce->SetText()
ArticleDisplayPage->InitArticleDetailPage()
CatalogueDisplayPage->InitCatalogueDisplay()
DownloadDisplayPage->InitDownloadDisplayPage()
CommentDisplayPage->SetPostID()
CommentDisplayPage->InitCommentDisplayPage()
PlayVideo()
Video->PlayMediaByNet()
SetPostID ()
CheckBox OnCheckStateChanged绑定函数
DocumentDetail()
ResetCheckBox()
DocumentBox->SetCheckedState()
Switcher->SetActiveWidgetIndex(0)
DownloadDetail()
CommentDetail()
VideoCatalogueDetail()
ResetCheckBox()
遍历Boxs
SetCheckedState(ECheckBoxState::Unchecked)
Buy()
TArray<UCheckBox*> Boxs
uint32 PostID
uint32 AuthorID
UI_InebrietyPage
UI_FrameDetailPage
UI_UserDetailPage
UImage* HeadPortrait
UTextBlock* UserName
UTextBlock* UserID
UCheckBox* ResourceBox_96
UCheckBox* GameBox_188
UWidgetSwitcher* Switcher
UWrapBox* ResourceList
UWrapBox* GameList
TSubclassOf<UUI_Node> NodeClass
NativeConstruct()
ResourceBox_96->OnCheckStateChanged.AddDynamic(Resource)
GameBox_188->OnCheckStateChanged.AddDynamic(Game)
Resource(bool IsChecked)
GameBox_188->SetCheckedState(Unchecked)
Switcher->SetActiveWidgetIndex(0)
Game(bool IsChecked)
ResourceBox_96->SetCheckedState(Unchecked)
Switcher->SetActiveWidgetIndex(1)
InitUserDetailPage()
UUI_List::CreateResourceNode()
UserName->SetText
UserID->SetText
UI_RechargeDetailPage
UI_PurchaseVerification
Element
UI_ArticleDisplayPage
UPROPERTY()UWebBrowser* WebBrowserPtr
UPROPERTY()FString DummyURL
UUI_ArticleDisplayPage()
InitArticleDetailPage()
WebBrowserPtr->LoadString()
UI_CatalogueDisplayPage
UPROPERTY(meta = (BindWidget))UVerticalBox* ListBox
UPROPERTY(EditDefaultsOnly, Category = UI)TSubclassOf<UUI_CatalogueDisplaySlot> CatalogueDisplaySlots
InitCatalogueDisplay()
InExpandableArea = NewObject()
HeaderText = NewObject()
InList = NewObject()
InExpandableArea->SetContentForSlot(header,Body)
InCatalogueDisplaySlot = CreateWidget<UUI_CatalogueDisplaySlot>()
InList->AddChildToVerticalBox(InCatalogueDisplaySlot)
InCatalogueDisplaySlot->InitCatalogueDisplaySlot()
父类注册InCatalogueDisplaySlot->SetParent(this)
ListBox->AddChildToVerticalBox(InExpandableArea)
ResetSlot()
遍历ListBox
遍历CatalogueDisplaySlots
设置SetCheckedState()
UI_CommentDisplayPage
UPROPERTY(meta = (BindWidget))UUI_CommentInput* CommentInput
UPROPERTY(EditDefaultsOnly, Category = UI)
TSubclassOf<UUI_IeaveMessage> IeaveMessage
UPROPERTY(EditDefaultsOnly, Category = UI) int32 MaxCommentNum
UPROPERTY(meta = (BindWidget))
UVerticalBox* CommentList
UPROPERTY(meta = (BindWidget))
UButton* PreviousButton
UPROPERTY(meta = (BindWidget))
UButton* NestButton
本地可识别数据struct FCommentDataNode
UUI_CommentDisplayPage()
初始化MaxCommentNum(5)
初始化CurrentPageCount(0)
NativeConstruct()
BindClientRecv()
PreviousButton->OnClicked.AddDynamic(Previous)
NestButtonButton->OnClicked.AddDynamic(Nest)
CommentInput->SetParent(this)
NativeDestruct()
Remove(DelegateHandle)
RecvProtocol()
SP_SubmitCommentsSuccessful
SP_GetCommentsSuccessful接收评论内容和数量
InitCommentDisplayPage()
BindClientRecv()
InitCommentDisplayPage()
判断评论所处的位置
设置PreviuosButton和NestButton可见性
CommentList->ClearChildren()
将网络数据转成本地可识别数据NetCommentsToCommentDataNode()
遍历本地可识别数据
RecursionSpawnWidget递归动态生成ExpandableArea
CommentList->AddChildToVerticalBox(ExpandableArea)
SetPostID()
CommentInput->SetPostID()
SetCommentInputReplyID()
SetCommentAuthorName()
CommentInput->SetCommentObject()
ActivateCancelButton()
CommentInput->ActivateCancelButton()
FORCEINLINE const GetMaxCommentNum()
FORCEINLINE const GetCurrentPageCount()
UFUNCTION() Previous()
CurrentPageCount--
向服务器发送GetComments请求
UFUNCTION() Nest()
CurrentPageCount++
向服务器发送GetComments请求
内部函数
NetCommentsToCommentDataNode()
if CommentParentID == 0)直接赋值
else递归RecursionNetToNode()
RecursionSpawnWidget
动态生成ExpandableArea
动态生成HorizontalBox
动态创建UI_LeaveMessage
创建UI_LeaveMessage成功
SetParent()
SetCommentID
SetCommentatorID
SetHeadPortrait
SetAuthorName
SetCommentAndDate
SetCommentContent
生成间隔Spacer
HorizontalBox->AddChildToHorizontalBox(Spacer)
HorizontalBox->AddChildToHorizontalBox(UI_LeaveMessage)
设置HorizontalBoxSlotSize
如果该评论有回复动态生成VerticalBox
遍历回复
递归动态生成NewExpandableArea
VerticalBox->AddChildToVerticalBox(NewExpandableArea)ExpandableArea设置身体VerticalBox
ExpandableArea设置头部HorizontalBox
FDelegateHandle DelegateHandle
uint32 PostID
uint32 CurrentPageCount
UI_DownloadDisplayPage
UPROPERTY(meta = (BindWidget)) UImage* Propaganda
UPROPERTY(meta = (BindWidget)) UWebBrowser* CourseBrowser
UPROPERTY(meta = (BindWidget)) UWebBrowser* FrameworkBrowser
UPROPERTY(meta = (BindWidget)) UButton* CourseLinkButton
UPROPERTY() FString CourseLinkURL
NativeConstruct()
CourseLinkButton绑定OnLink事件CourseLink
InitDownloadDisplayPage()
HTTP代理绑定DownloadComplete()
执行下载Propaganda
FrameworkBrowser->LoadString()
UFUNCTION() DownloadComplete()
InTexture = Uint8ArrayToTexture2D()
Propaganda->SetBrushFromTexture(InTexture)
UFUNCTION() CourseLink()
CourseBrowser->LoadURL(CourseLinkURL)
Element
UI_CatalogueDisplaySlot
UPROPERTY(meta = (BindWidget)) UCheckBox* VideoSectionBox;
UPROPERTY(meta = (BindWidget))
UTextBlock* VideoName
NativeConstruct()
InitCatalogueDisplaySlot()
URL赋值
设置VideoName
SetCheckedState()
SetCheckedState()
UFUNCTION()Section()
CatalogueDisplayPage = GetParent<UUI_CatalogueDisplayPage>()
CatalogueDisplayPage->ResetSlot(this)
ProjectDetailPage = GetParent<UUI_ProjectDetailPage>()
ProjectDetailPage->PlayVideo(URL)
FString URL
UI_CommentInput
UPROPERTY(meta = (BindWidget)) UTextBlock* CommentObject
UPROPERTY(meta = (BindWidget))
UButton* CommetButton
UPROPERTY(meta = (BindWidget))
UMultiLineEditableTextBox* EditableTextBox
UPROPERTY(meta = (BindWidget))
UButton* CancelCommetButton
UUI_CommentInput(const FObjectInitializer& ObjectInitializer)
初始化PostID
初始化ReplyID
NativeConstruct()
CommetButton->OnClicked.AddDynamic(OnClickCommet)
EditableTextBox->OnTextCommitted.AddDynamic(OnTextCommittedEditableText)
CancelCommetButton->OnClicked.AddDynamic(OnClickCancelComment)
SetPostID()
SetReplyID()
SetCommentObject()
CommentObject->SetText()
ActivateCancelButton()
CancelCommetButton->SetIsEnabled(true)
UFUNCTION() OnClickCommet()
InCommentDisplayPage = GetParent<UUI_CommentDisplayPage>()
InCommentDisplayPage->GetMaxCommentNum()
InCommentDisplayPage->GetCurrentPageCount()
SEND_DATA(SP_ProjectRequest, PostID, ReplyID, FClientUserData::Get()->UserID,MaxCommentNum,CurrentPageCount,LeavingMessage)
清空 LeavingMessage
UFUNCTION() OnClickCancelComment()
ancelCommetButton->SetIsEnabled(false)
CommentObject->SetText()
UFUNCTION() OnTextCommittedEditableText()
LeavingMessage = InText
清空EditableTextBox
uint32 PostID
uint32 ReplyID
FString LeavingMessage
UI_IeaveMessage
UPROPERTY(meta = (BindWidget))
UTextBlock* AuthorName
UPROPERTY(meta = (BindWidget))
UImage* HeadPortrait
UPROPERTY(meta = (BindWidget))
UTextBlock* CommentAndDate
UPROPERTY(meta = (BindWidget))
UTextBlock* CommentContent
UPROPERTY(meta = (BindWidget))
UButton* ReplyButton
NativeConstruct()
ReplyButton->OnClicked.AddDynamic(OnClickReply)
SetAuthorName()
SetHeadPortrait()
SetCommentAndDate()
SetCommentContent()
SetCommentID()
SetCommentatorID()
UFUNCTION() OnClickReply()
CommentDisplayPage = GetParent<UUI_CommentDisplayPage>()
CommentDisplayPage->SetCommentInputReplyID (CommentID)
CommentDisplayPage->SetCommentAuthorName(AuthorName->GetText())
CommentDisplayPage->ActivateCancelButton()
uint32 CommentID
uint32 CommentatorID
FClientUserData单例
FClientUserData* Get()
Destroy()
重载操作符=
uint32 UserID
FString UserEmail
FString UserURL
FString UserAccount
FString UserName
static FClientUserData* UserData
struct FCommentDataNode
uint32 CommentID
uint32 CommentatorID
UTexture2D* CommentatorImag
FString CommentData
FString CommentatorName
FString CommentContent
TArray<TSharedPtr> Node
重载操作符=:FCommentDataNode& operator=(const FNetComment& InNetComment)
递归网络数据RecursionNetToNode()
NetDataStruct
通用的节点数据FNetData
uint32 ID
TCHAR ImgURL[TCHAR_MAX_SIZE]
通用的节点数据FNetNodeData
TCHAR Name[TCHAR_MAX_SIZE]
首页详情数据结构FNetHomePageData
导航
导航FNetButton
TCHAR Name[TCHAR_MAX_SIZE]
uint32 ID
菜单
幻灯片
幻灯片FNetFilmstrip
TCHAR LinkURL[TCHAR_MAX_SIZE]
资源
资源节点FNetResourcesData
uint32 DownloadCount
uint32 Price
游戏
资源节点FNetResourcesData
uint32 DownloadCount
uint32 Price
文章
文章节点FNetFrameworkData
TCHAR Introduction[TCHAR_MAX_SIZE]
项目详情数据结构FNetProjectDetailPageData
视频目录FNetVideoCatalogue
TCHAR VideoURL[TCHAR_MAX_SIZE]
评论FNetComment
uint32 CommentParentID
uint32 CommentID
uint32 CommentatorID
TCHAR CommentatorURL[TCHAR_MAX_SIZE]
TCHAR CommentDate[TCHAR_MAX_SIZE]
TCHAR CommentatorName[TCHAR_MAX_SIZE]
TCHAR CommentCotent[TCHAR_MAX_SIZE_2]
int32 CommentNum
下载
FNetDownloadData NetDownloadData
TCHAR CourseURL[TCHAR_MAX_SIZE]
TCHAR PropagandaURL[TCHAR_MAX_SIZE]
FString DownloadContent
FString DescriptionContent
文章FNetAticleContent
用户页数据FNetUserDetailPage
uint32 UserID
FString UserName
FString ImageURL
FNetResourcesDatas ResourcesDatas
FNetUserInfo
uint32 UserID
FString UserEmail
FString UserURL
FString UserAccount
FString UserName
from blog.
week1 笔记
1.[安装UE5源码版本]
安装VS2019到C盘
选择语言包
中文
英文
安装UE5源码版
从官网下载源码版本,解压时注意修改文件名短一点,不然安装时会报错
打开UE5项目文件后提示什么安什么比如
编译
选择为模式然后进行编译
2.[安装番茄插件]
如果安装前已经有番茄插件,执行卸载,然后在卸载后检查注册表有番茄英文名的删掉.然后再进行重新安装.安装好后替换放入两个破解文件即可,注意禁用自动更新
3.[安装UE5相关开发插件]
新建一个项目
将这个目录底下除了文件夹以外的文件都复制到这个文件夹的上一级
然后右键项目文件重新生成项目后如果报错在项目根目录底下新建一个txt文件改为bat文件来进行使用.在里面粘贴进去报错第一行.然后修改一下路径.在最终执行exe上级再加一个文件夹路径
如果进去编译新建项目还是报错的话,在调试最后的位置加入如下字段-zm140
安装四个插件
将这四个插件安装到引擎中的插件目录中
最后在代码中再生成一次UE5引擎
4.准备db和网关和登陆服务器启动结构
在该目录下复制3个BlankProgram
登录服务器,是负责转发的.验证我们当前的玩家是否可以登录服务器
网关服务器,也是用来做转发的,为了安全.捏脸的数据保存.创建角色之类的
数据库服务器,用来负责处理数据的[读写数据库]
替换目录下的BlankProgram为当前服务器文件夹的名字.然后cpp和Build等文件里的对应字段[类名,其他空白文件名等]也要修改成当前服务器文件名
使用批处理的方式按顺序启动db,网关和登录服务器.Build后在该目录底下可以找到对应服务器的启动程序.然后可以作为批处理的路径
间隔0.5秒去启动服务器
5.数据库服务器架构概念
初始化读取本地配置
MySql
初始化MySql配置数据
端口用户密码等等
分布式插件[管理Socket]
服务器IP可以省掉,只设置端口就可以
客户端IP不能省,因为需要知道连接的服务器IP.
用的是预分配方案不考虑内存泄漏
注册(对象注册),绑定一些代理
Tick不断的检测消息(是一个死循环,因为服务器一旦开启不考虑关掉)
把服务器清掉
删除其他的类.做一些清理
6.架构db服务器全局配置
MMOARPGdbServer
定义接口变量,结构体[配置表结构]
配置表单例
7.部署远程数据库的准备工作
下载安装PHPStudy
其中包含部署网站要用的一些环境
部署WordPress
用来开发网站,可以帮我们生成一些用户信息,不用手动.用的是他里面的数据库
部署到远程电脑上[本机也可以,或者局域网和阿里云之类的也可以,但是学习阶段用本机就够了]
8.手把手部署远端WP数据库
官网下载PHPStudy(小皮)最新版
在面板里安装7.4.3的php(以后根据环境选最新)然后记得把网站里的php切换成这个版本.原来低版本的卸载不卸载无所谓
运行SQL和阿帕奇
官网下载WorldPress当前最新版本
解压wordpress数据包
改名为wp(其实叫什么都可以,这里主要是为了简写然后访问的时候好输入)注意解压的文件是所有文件直接就在wp底下.中间不要再有中间文件夹层级,不然后面访问wp页面的时候会报错
然后在浏览器输入地址开始进行安装
安装到这一步保持和下面新建的数据库一致
最后可以登录看一下
官网下载Navicat的Premium版本
数据库可视化操作用的(用别的可视化数据库软件也可以,但是新手建议跟着老师用这个)
首次链接会填写链接名(随便填)还有密码,教学里是和用户名一致都是root,别的保持默认就可以
然后右键新建数据库
在上面worldpress安装完成后可以刷新看一下wp的用户表里有没有值
9.架构数据库服务器
步骤
初始化
注册反射类
Tick
销毁
创建
这个类是用来暴露在外面由用户来进行配置的.如何发送消息,消息里有那些内容.服务端和客户端都会有这样一个对象
继承自USimpleController主要是为了支持反射
数据库配置文件,DB得改成wp_server
10.分布式插件架构讲解
UPD构架
服务器(Manage)
connect(状态)
channel(主通道)
object(对象,反射)用户可以在上面写一些用户行为
channel_1
...
connect2(状态)服务器的一个connect对应一个客户端.服务器可以有多个connect.当释放掉(客户端关闭以后.这个connect也会关掉)
...
Manage
这一步创建的就是Manage也就是上面的服务器或者之后的客户端
Manage初始化过程
创建Socket
申请缓存区
绑定端口(服务器)
开启监听模式
可以去知乎看分布式插件的介绍.里面也有详细讲解
11.架构数据库服务器读和写
MySQL插件
对象
一个对象专门用来写
提交到服务器
Post
一个对象专门用来读
从服务器拿下来然后发到UE5客户端
Get
创建读写Object和对应接口
在初始化中创建读写实例
Post给数据库写入对象(其实就是数据库查询)
获取数据库信息
在Init的最后面加入这些语句进行测试.看是否能正常获取到数据库的信息.如果获取征程.结果不为空而且在CMD里会正常打印你的用户信息
如果是多台电脑只要不是在本机测试的情况下获取为空的话去数据库的用户表里复制第一行到最后一行.然后替换Host为%号.这样所有的用户权限都相当于打开了.这样就可以正常获取了
12.分离数据日志
这节课没啥难的.就是把原来文件里的这一句提出来,然后单独放一个文件里.然后原来文件里再包含这个头文件就行了.这样做就是单纯为了这个独立程序里的其他文件也可以调用这个日志打印的东西
调用的时候的例子
13.架构网关服务器
网关可以理解成就是个把门的,过滤数据的
然后从第二步开始创建网关和db的实例初始化等操作.其实和dbServer那一节基本是一样的.就是Object里不带数据库操作了
注意第三步用的Object不是同一个.需要分开.虽然代码一样.这里的Object是去掉数据库部分的.剩下的代码都是基本的插件里的执行父类
db服务器指定端口
登录服务器构架
大致构架,这个构架有点问题.具体看下一课
14.架构登陆服务器
登录服务器构架
创建对应需要的Object
里面的代码结构都一样.这里我只放一个.实现调用一下父类就行了.还有别忘了剥离Log系统
代码实现上和dbServer还有GateServer差不多.就是注意客户端和服务器创建Manage里面的链接状态.服务器是监听.客户端是连接
至此整个分布式的构架就算搭好了
服务器的Build和Target设置和dbServer基本一致,只是不包含数据库插件
15.架构客户端网络驱动
客户端网络驱动器简单构架理解
使用GameInstance来做这一部分
初始化
循环
结束(销毁)
和之前的服务器比少了Object反射那一部分创建
如果报错的话应该是HTTP插件那边有个报错,通过报错的参数,用Alt+G找到声明的地方.把注释调换一下就可以了
把创建的GI选择上.如果没有的话.重启一下UE5就好了
具体实现
注意GameInstance是不带Tick.按照老师说的是用TStatId后面要怎么做一下才可以(这个我得拿去完了问一下老师)
初始化拆开
创建Socket
链接服务器
防止握手过程中失败,保证握手成功之后再保持长链接.再一个就是在握手前对客户端进行一个绑定
注意这一节课还需要在UE5中包含人宅老师的这几个插件.HTTP主要是用来下载图片的
注意这里也要包含,因为客户端网络驱动用了
这节课把头显的模块还有角色里涉及到头显的头文件还有代码都注释掉
客户端(Manage)
connect(状态)[客户端只有一个]
channel(主通道)
object(对象,反射)用户可以在上面写一些用户行为
channel_1
...
CoreUObject的包含是因为编译报错了.找到报错的那一行代码.然后找到这个文件.然后看最上级模块是CoreUObject[文件夹名]所以包含
from blog.
week2 笔记
1.部署登录Gameplay框架
loding的显示条件和服务器与客户端状态进行对应
登录的GamePlay构架
UI是一方面主要是用来显示服务器和客户端状态的
具体实现
创建GameMode
关联HUD
关联Pawn
关联PlayerController
创建Controller(用来做输入用的,比如触摸点击或者文字输入)
在构造里打开鼠标显示
创建Pawn(主要是为了断绝WASD这样的输入后角色还能移动的问题)
创建HUD(作为登录的UI显示用)
HUD里生成登录的UI
创建UI
创建UI_Base(这样里面可以放一些通用方法类)
创建UI_LoginMain继承自UI_Base
创建Login用的Map
Map加载登陆的GameMode
2.获取前期握手登录状态
登录这块客户端的构架就是UI
1.部署协议接收通道(接受服务器的回应)
2.部署绑定握手能不能握成功的检测
3.宏文件
确保GameInstance是准备好的再去和UI进行代理绑定
客户端
UI_Base
UI_LoginMain
就是按照之前的逻辑来实现了一下.逻辑顺序看LoginMain的构造里的调用顺序就基本明白了
3.架构Cpp登陆UI
登录窗口的逻辑
UI_Base模板函数返回任意父类类型.设置父类的接口作用应该是每个继承自该基类的UI都有一个设置上的父类.这里的作用还是为了让UI_Login去快速调用UI_LoginMain的接口.但是其实UI_LoginMain并不是UI_Login的父类.这个子父关系更像是Unity里的获取父类组件
UI_LoginMain
UI_Login
仔细看逻辑都是执行在Main(父类里)
4.分离通用的协议模块
为什么要分离通用的协议模块
在MMOARPG里创建一个新的空白插件.创建这个插件作为通用工具.(其实是一个模块,但是做成插件好调用.这个插件不具备可移植性)是给几个服务器客户端啥的进行通用的.[最后注意模块包含.引擎模块是肯定不包含的.省下就是SNC插件包含如图]
然后把这个插件连根移到UE的插件目录底下,重新生成引擎和项目文件.
然后启动在项目里启用插件.然后注意这一部分重新启动项目后可能需要再生成一遍引擎的部分文件
在项目的模块里包含这个插件(本质上不是插件,我们只是用到它的一个模块)
在插件里给登录协议加入两个请求,登录请求和响应请求
MMOARPG包含该插件模块
网关包含该插件模块
DB服务器包含该插件模块
登录服务器包含该插件模块
网络协议分离,一套东西多个服务器客户端共同使用.该插件不具备可移植性.因为本质是模块
5.发送登录请求到数据库验证
交互逻辑
这节课完成的逻辑,主要就是发送登录请求到dbServer
视口点击登录发送的接口其实之前的课已经做了.这里需要的是加入协议进行发送(传入账号密码)
判断平台来进行写宏.PC和移动平台的宏不一样必须这样做,区别主要是后面的参数
点击以后先是发送到登录服务器,接收账号密码.注意登录协议保持一致.提出地址给db客户端转发.并打印Log
这里没有做具体逻辑.但是执行父类了.应该是插件就做转发了
最后转发到dbServer打印信息.其实和登录服务器的逻辑基本一样(仅限于这节课).下节课开始dbServer要开始做验证密码是否正确的逻辑了
6.数据库如何验证wp登录密码
这节课在做什么的逻辑
dbServer拿到账户密码后开始验证
1.看代码逻辑,首先是用SQL语句获取账户ID.这个是从真正的数据库里取到的
2.然后获取对应的加密密码
3.然后是用全局配置获取服务器公网IP
4.将公网IP,还有用户加密密码,拿到的客户端那边发送过来的密码.地址.端口.通道.还有完成密码验证后的回调代理传入.向wp服务器发送一个验证密码的请求
PS.如果没有取到结果或者是取到的结果没有值,均发送错误响应.ELoginType是共用登录类型枚举(自己加的)
wordPress需要安装的老师的插件,用来做密码验证的
UserID是用户ID
EncryptedPassword是加密了的密码
Password是密码
IP是网关IP
Port是网关端口
Channel是网关通道
注意安装时的头文件包含报错
密码验证应该是调用了WP的验证
这个安装注意是要进入WorlPress的后台进行安装的
7.如何通过HTTP向PHP进行通信
这节课主要讲的是打通下面这条线
从dbServer接收开始回调开始
执行回调里解析,验证,并最后响应
db客户端接收,然后转发给登录服务器.这里注意转发到服务器用是SERVER.转发到客户端用的是CLIENT[这里的响应的网关地址就是服务器当初发过去的地址.一路转发过来地址是保持对应的,不然没办法回调回去]
客户端登录回调.注意是响应不是请求
8.验证登录请求到服务器响应流程
修改第一个错误,是响应不是请求协议.不然接收不到
第二个错误.这里转发到服务器应使用SIMPLE_SERVER_SEND
转发或者发送给服务器用SIMPLE_SERVER_SEND
转发或者发送给服务器用SIMPLE_CLIENT_SEND
第三个忽略的点,这里要用两个相同的账户String去接数据.不然email没地方去.输入也会变成乱码
最后说是之后的课要做数据本地化.用xml或者json之类的来接服务器的数据之类的
9.用户数据Json解析
构架及流程
创建用户数据并加入导出宏提供使用
在GameInstance存储用户数据
写入Json的接口.写入并序列化成字符串
反序列化并读取Json的接口
Json的数据结构
10.服务器的负载均衡架
负载均衡构架,除了构架注意序号.基本是实现顺序
1.添加网关协议,请求和响应(这里注意协议号别重了.之前已经有0和1了)
2.配置表(网关状态)
网关客户端(登录服务器里)每秒请求更新一次网关状态
网关客户端响应接收状态
3.4两步一起
db客户端判断网关选择最优最后返回并转发给服务器
更换选择逻辑
11.测试整套客户端登录服务器的流程
这节课的逻辑.主要就是从服务器拿到数据并判断响应
1.dbServer取到用户数据压为字符串发送成功登陆响应
数据解析之前做一次清理
2.db客户端接收dbServer的String,然后验证并加入网关信息发送给登录服务器
3.客户端做响应然后把数据解析到GameInstance的用户数据里.这里的网关是全局变量.本地需要存储一个将来做动画用的.
12.MD5和AES存储账户和密码
加密什么时候开始以及加密构架
加密解密的接口都写在了UI_Login里
在UI_LoginMain里的构造调用读取解析账号
加密的具体逻辑.其中最后面存储路径时之前删除该路径是关键.注意文件夹不要设定在根目录.要加个User.不然整个项目都给你删掉
在UI_LoginMain里的登录成功响应里调用开始对该路径进行文件加密写入
这一步是递归获取该路径下的所有文件和文件夹.最后两个参数是控制是否获取文件和文件夹的
AES加密时的怖位逻辑及原因
13.控件如何播放动画
创建登录显示和淡出的动画
登录淡入
在登录主界面构造的时候淡入
登录成功淡出
在登录成功的地方里面调用淡出
注意做动画的时候专门有个轴是控制在动画过程中不能点击输入之类的
把Log的UI单独提出来了.然后创建了一个提示动画
创建了一个C++父类
简单做了一下实现
记得要给蓝图的Log替换父类.然后再LoginMain里的C++和蓝图两个地方把组件都替换成新剥离的Log
加入播放动画和设置当前组件Text
提示动画
在UI_Base里做了一个通用播放对应UI动画名称的两个接口
上面的是找到对应名称的UI动画.下面是具体播放的地方.这里的二级指针可能有点绕.但是这里函数返回的是一个指针.声明的二级指针前面再加一个*的话相当于解.也就是返回二级指针的解开一级也就是一级指针.一级指针就是要返回的普通指针
最后注意一点.做测试的时候保证所有服务器包括数据库全部打开.不然测试的时候看不到效果
分支主题 14
from blog.
Week3 笔记
from blog.
week4 笔记
from blog.
1 架构分布式服务器
01A_01_安装UE5源码版本
https://docs.unrealengine.com/5.3/zh-CN/downloading-unreal-engine-source-code/
https://github.com/EpicGames/UnrealEngine
运行
GenerateProjectFiles.bat
回车 来设置项目文件
所有项目文件都是中间文件([虚幻引擎根目录]
\Engine\Intermediate\ProjectFiles
)。每次同步新构建时都必须生成项目文件,以确保它们是最新文件。如果你删除了Intermediate
文件夹,必须使用GenerateProjectFiles
批处理文件来重新生成项目文件。
安装 visual studio community https://visualstudio.microsoft.com/zh-hans/vs/ 仅用以编译虚幻引擎为二进制
从源代码构建虚幻引擎
https://docs.unrealengine.com/5.3/zh-CN/building-unreal-engine-from-source/
双击 UE5.sln 将项目加载到Visual Studio。
将解决方案配置设置为 开发编辑器(Development Editor)。或者 DebugGame Editor
Development 性能优于debug
将解决方案平台设置为 Win64。
右键单击UE目标并选择 构建(Build)。
构建只需要一次,除非更新虚幻版本。
编译耗时很长很长
运行编辑器
将启动项目设置为 UE5。
右键单击 UE 项目,将鼠标悬停于 Debug 上,然后单击 启动新实例(Start New Instance)** 以启动编辑器。
或者,你可以按键盘上的 F5键 来启动编辑器的新实例。
恭喜!你已经从源代码编译并启动了引擎。
新建 第三人称C++游戏项目,名称:mmoarpg
这将启动mmoarpg项目的VS编辑器
选择DebugGame Editor
和Win64
点击本地Windows调试器
启动该虚幻项目
01A_02_VS安装小番茄 【不需要】
Visual Assist X_10.9.2440_汉化And破解VS2022
01A_03_安装UE5相关开发插件
首次编译游戏
引擎插件
安装路径为
虚幻引擎 - Engine - Plugins
目录
以下插件目录复制到 虚幻引擎 - Engine - Plugins
SimpleHTTP
SimpleMySQL
SimpleNetChannel
SimpleThread
刷新引擎
运行引擎跟目录下
GenerateProjectFiles.bat
重新设置引擎
刷新项目
右键 mmoarpg 项目目录 mmoarpg.uproject 文件- Geraneta Visual Studio Project files
编辑器重新打开 mmoarpg 项目代码
在Engine - UE5 - Plugins
下即可发现新增的 SimpleHTTP 等插件
先择 Engine - UE5 右键 -生成 编译项目中引擎
先择 Games - mmoarpg 右键 -生成 编译项目
项目插件
01A_04_准备db和网关和登陆服务器启动结构
01A_05_数据库服务器架构概念
01A_06_架构db服务器全局配置
01A_07_部署远程数据库的准备工作
01A_08_手把手部署远端WP数据库
01A_09_架构数据库服务器
01A_10_分布式插件架构讲解
01A_11_架构数据库服务器读和写
01A_12_分离数据库日志
01A_13_架构网关服务器
01A_14_架构登陆服务器
01A_15_架构客户端网络驱动
from blog.
Related Issues (20)
- ControlNet [stable diffusion] HOT 2
- Unity HOT 1
- GPT Prompt 提示词工程 HOT 2
- MetaGPT 源码分析报告 HOT 2
- ADI 亚德诺半导体 电子电气术语表 Glossary of EE Terms HOT 2
- stanford-agent-生成式代理 - 人类行为的交互式仿真
- Blender HOT 1
- 更便宜的3D MMO服务器:GPGPU
- C++ HOT 1
- Unreal Engine 虚幻引擎 HOT 9
- C/C++ 工程化 HOT 12
- Cake(C# Make) HOT 6
- NUnit HOT 1
- KiCad HOT 3
- DALL-E 3 HOT 1
- 虚幻引擎 表演捕捉 Live Link HOT 1
- Unreal Engine 5 程序化内容生成框架(PCG) HOT 5
- 虚幻引擎 Unreal Engine 5 C++ HOT 14
- 虚幻引擎5 材质系统 Unreal Engine 5 Material HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blog.