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

怎么做简单的钓鱼网站谷歌seo价格

怎么做简单的钓鱼网站,谷歌seo价格,网站建设与维护实训ppt,十九冶成都建设网站UE4 C联网RPC教程笔记#xff08;一#xff09;#xff08;第1~4集#xff09; 前言1. 教程介绍与资源2. 自定义 Debug 功能3. Actor 的复制4. 联网状态判断 前言 本系列笔记将会对梁迪老师的《UE4C联网RPC框架开发吃鸡》教程进行个人的知识点梳理与总结#xff0c;此课程… UE4 C联网RPC教程笔记一第1~4集 前言1. 教程介绍与资源2. 自定义 Debug 功能3. Actor 的复制4. 联网状态判断 前言 本系列笔记将会对梁迪老师的《UE4C联网RPC框架开发吃鸡》教程进行个人的知识点梳理与总结此课程也像全反射零耦合框架的课程那样已经超过报名截止时间了无法通过正常方法观看。 笔者依旧是采取神奇的方法通过手机浏览器不同浏览器的效果有差别有的会直接要求你登录遇到这样的就换一个还有可能点开网页会发现没有播放按钮遇到这样的就换一个网页搜索该课程后可以在课程预览界面观看也可以在目录进行跳转不过没有字幕。建议是在 PC 端的手机模拟器观看。 本课程集数不多可以通过目录跳转看完就不需要复制一串数字到 URL 来切换集数了。 笔者用的引擎版本是 4.26.2老师推荐的引擎版本是 4.20不同的版本可能在代码上有所区别笔者会通过注释标明。 本系列文章不允许转载。 本系列笔记可供读者学习后用于复习回顾或参考代码来解决一些敲错了代码导致的 Bug。并且笔者只会贴出对应集数修改的代码内容已经有了的部分代码基本都不会贴出来以免笔记篇幅过长。 1. 教程介绍与资源 此处列出本课程需要翻阅的网址虚幻文档关于 RPC 的讲解 【】 RPC 的全称是 Remote Procedure Calls 远程过程调用。 本课程篇幅较短分两步走1. RPC 基础 2. 分别用蓝图和 C 实现监听服务器。 2. 自定义 Debug 功能 打开 UE4创建一个新的 C 第三人称游戏项目需带有初学者内容包命名为 RPCCourse。 如果学过梁迪老师另一个课程《UE4全反射零耦合框架开发坦克游戏》的读者可能会有印象因为这个自定义 Debug 功能也在那个课程里面实现了学过的读者可自行决定是否再看一遍。 创建以下 C 类 创建一个 Object命名为 RPCHelper路径为默认。 要实现自定义 Debug 功能我们需要用到单例模式 RPCHelper.h #include CoreMinimal.h // 引入头文件 #include Engine/GameEngine.hclass RPCCOURSE_API DDRecord { private:// 自身单例static TSharedPtrDDRecord RecordInst;// 最终输出的字符串FString RecordInfo;// 显示时长float ShowTime;// 显示的颜色FColor ShowColor;public:// 构造和析构函数不写内容并且由于可能会被大量调用所以写成内联函数inline DDRecord() {}~DDRecord() {}static TSharedPtrDDRecord Get();// 初始化显示时长和颜色inline void InitParam(float InTime, FColor InColor){ShowTime InTime;ShowColor InColor;}// 实际依赖引擎自带输出逻辑inline void Output(){if (GEngine)GEngine-AddOnScreenDebugMessage(-1, ShowTime, ShowColor, RecordInfo);// 清空最终输出字符串RecordInfo.Empty();}// 移位操作符重写将传入的各种类型数据都转换成 FString 然后加入最终输出字符串inline DDRecord operator(FString Info) { RecordInfo.Append(Info); return *this; }inline DDRecord operator(FName Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(FText Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(const char* Info) { RecordInfo Info; return *this; }inline DDRecord operator(const char Info) { RecordInfo.AppendChar(Info); return *this; }inline DDRecord operator(int32 Info) { RecordInfo.Append(FString::FromInt(Info)); return *this; }inline DDRecord operator(float Info) { RecordInfo.Append(FString::SanitizeFloat(Info)); return *this; }inline DDRecord operator(double Info) { RecordInfo.Append(FString::SanitizeFloat(Info)); return *this; }inline DDRecord operator(bool Info) { RecordInfo.Append(Info ? FString(true) : FString(false)); return *this; }inline DDRecord operator(FVector2D Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(FVector Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(FRotator Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(FQuat Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(FTransform Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(FMatrix Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(FColor Info) { RecordInfo.Append(Info.ToString()); return *this; }inline DDRecord operator(FLinearColor Info) { RecordInfo.Append(Info.ToString()); return *this; }// 在遇到 DDRecord 对象时即下文的 Endl输出即调用 Output()inline void operator(DDRecord Record) { Record.Output(); } };namespace DDH {FORCEINLINE DDRecord Debug(float InTime 3000.f, FColor InColor FColor::Yellow){DDRecord::Get()-InitParam(InTime, InColor);return *DDRecord::Get();}FORCEINLINE DDRecord Endl(){return *DDRecord::Get();} }RPCHelper.cpp TSharedPtrDDRecord DDRecord::RecordInst NULL;TSharedPtrDDRecord DDRecord::Get() {if (!RecordInst.IsValid())RecordInst MakeShareable(new DDRecord());return RecordInst; }接下来到第三人称项目自带的这个 RPCCourseCharacter重写它的 BeginPlay() 方法来测试一下我们的自定义 Debug 功能。 RPCCourseCharacter.h protected:void BeginPlay() override;RPCCourseCharacter.cpp // 引入头文件 #include RPCHelper.hvoid ARPCCourseCharacter::BeginPlay() {Super::BeginPlay();// 输出 DebugDDH::Debug(20.f, FColor::Red) Hello UE4 123 0.888 FVector(30, 40, 50) FColor::Red DDH::Endl(); }编译后运行游戏左上角输出红色的 Debug 语句20 秒后消失。 继续改进下让 Debug 支持更多输出方式比如输出到 Output Log 控制台里并且有日志记录、警告、报错模式。 RPCHelper.h class RPCCOURSE_API DDRecord { public:// 状态模式0Debug1Log2Warning3Erroruint8 PatternID;public:inline void Output(){switch (PatternID) {case 0:{if (GEngine)GEngine-AddOnScreenDebugMessage(-1, ShowTime, ShowColor, RecordInfo);}break;case 1:{UE_LOG(LogTemp, Log, TEXT(%s), *RecordInfo);}break;case 2:{UE_LOG(LogTemp, Warning, TEXT(%s), *RecordInfo);}break;case 3:{UE_LOG(LogTemp, Error, TEXT(%s), *RecordInfo);}break;}RecordInfo.Empty();} };namespace DDH {FORCEINLINE DDRecord Debug(float InTime 3000.f, FColor InColor FColor::Yellow){DDRecord::Get()-PatternID 0; // 初始化DDRecord::Get()-InitParam(InTime, InColor);return *DDRecord::Get();}// 只改变输出颜色不管显示时间FORCEINLINE DDRecord Debug(FColor InColor){return Debug(3000.f, InColor);}FORCEINLINE DDRecord Log(){DDRecord::Get()-PatternID 1;return *DDRecord::Get();}FORCEINLINE DDRecord Warning(){DDRecord::Get()-PatternID 2;return *DDRecord::Get();}FORCEINLINE DDRecord Error(){DDRecord::Get()-PatternID 3;return *DDRecord::Get();} }最后测试一下日志记录模式。 RPCCourseCharacter.cpp void ARPCCourseCharacter::BeginPlay() {Super::BeginPlay();DDH::Log() Hello UE4 123 0.888 FVector(30, 40, 50) FColor::Red DDH::Endl(); }编译后打开 Window - Develop Tools - Output Log运行游戏可以看到日志输出了 Debug 语句。 最后将 BeginPlay() 里的 Debug 语句删除掉。 3. Actor 的复制 以下知识点内容截取自梁迪老师准备的 RPC 联网文档 1bool 变量 bNetLoadOnClient 这个变量是给一开始就放置在场景中的对象使用的。 如果bNetLoadOnClient 设置为 true当客户端连接上服务端时客户端也会存在这个对象。 如果 bNetLoadOnClient 设置为 false当客户端连接上服务端时客户端不会存在这个对象。 SetReplicates 无论是否为 true 都不会影响这个变量的作用。关于 SetReplicates 下面会讲解 在默认路径下新建 3 个 C 的 Actor 类分别命名为 RPCActor、CubeReplicate 和 CubeNoReplicate。 我们先用 RPCActor 来测试 bNetLoadOnClient。 RPCActor.cpp ARPCActor::ARPCActor() {bNetLoadOnClient false; // 设置为 不网络同步到客户端 }来到角色类在 BeginPlay() 里输出场上 RPCActor 实例的数量。 RPCCourseCharacter.cpp // 引入头文件 #include Kismet/GameplayStatics.h #include RPCActor.hvoid ARPCCourseCharacter::BeginPlay() {Super::BeginPlay();// 寻找场景中的 RPCActorTArrayAActor* ActArray;UGameplayStatics::GetAllActorsOfClass(GetWorld(), ARPCActor::StaticClass(), ActArray);DDH::Debug() RPCActor Num -- ActArray.Num() DDH::Endl(); }编译后将 C 类的 RPCActor 拖进场景随后作以下设置对于 4.26 版本会多出第 2 步。运行后结果如图所示。 输出场景内 RPCActor 的数量为 1 的语句是服务端发出来的输出数量为 0 的语句则是客户端发出来的。至于为何会分别输出了两遍是因为在编辑器中调用引擎自带的屏幕输出方法会使语句在每个端都输出一次。 同时因为 RPCActor 设置了 bNetLoadOnClient 为 false所以 RPCActor 只存在于服务端。 RPCActor.cpp ARPCActor::ARPCActor() {// 重新设置为 网络同步到客户端bNetLoadOnClient true; }编译后将原本场景里的 RPCActor 删除重新放置一个 RPCActor。运行游戏结果如图所示 这时服务端和客户端的场景里都存在这个 RPCActor 的实例。 2SetReplicates(bool) 调用 SetReplicates(true) 设置 Actor 可以复制。 调用 SetReplicates(false) 设置 Actor 不可以复制。 当在服务端 Spawn 可复制的 Actor 时客户端会生成。 当在客户端 Spawn 可复制的 Actor 时其他端不会生成。 测试下 SetReplicates(bool) 和 bNetLoadOnClient 共同作用是什么样的效果。 RPCActor.cpp ARPCActor::ARPCActor() {// bNetLoadOnClient 设置为 true 时如果该对象是一开始就在场景中的对象// 客户端连接到服务端时该对象也会存在与 SetReplicates 是否为 true 没有关系SetReplicates(true);bNetLoadOnClient false; }编译后将原本场景里的 RPCActor 删除重新放置一个 RPCActor。运行游戏结果如图所示 又变成了客户端没有 RPCActor服务端有。说明确实 bNetLoadOnClient 的优先级比 SetReplicates(bool) 更高。 接下来单独测试一下 SetReplicates(bool)。我们给 CubeReplicate 和 CubeNoReplicate 添加一些组件方便观察前者设置可复制后者设置不可复制。 CubeReplicate.h protected:UStaticMeshComponent* CubeMesh;CubeReplicate.cpp // 引入头文件 #include Components/StaticMeshComponent.h #include UObject/ConstructorHelpers.h #include RPCHelper.hACubeReplicate::ACubeReplicate() {PrimaryActorTick.bCanEverTick true;// 设置复制SetReplicates(true);RootComponent CreateDefaultSubobjectUSceneComponent(TEXT(RootScene));CubeMesh CreateDefaultSubobjectUStaticMeshComponent(TEXT(CubeMesh));CubeMesh-SetupAttachment(RootComponent);// 附加模型ConstructorHelpers::FObjectFinderUStaticMesh StaticCubeMesh(TEXT(StaticMesh/Game/StarterContent/Shapes/Shape_Cylinder.Shape_Cylinder));CubeMesh-SetStaticMesh(StaticCubeMesh.Object); }CubeNoReplicate.h protected:UStaticMeshComponent* CubeMesh;CubeNoReplicate.cpp // 引入头文件 #include Components/StaticMeshComponent.h #include UObject/ConstructorHelpers.h #include RPCHelper.hACubeNoReplicate::ACubeNoReplicate() {PrimaryActorTick.bCanEverTick true;// 设置不复制SetReplicates(false);RootComponent CreateDefaultSubobjectUSceneComponent(TEXT(RootScene));CubeMesh CreateDefaultSubobjectUStaticMeshComponent(TEXT(CubeMesh));CubeMesh-SetupAttachment(RootComponent);// 附加模型ConstructorHelpers::FObjectFinderUStaticMesh StaticCubeMesh(TEXT(StaticMesh/Game/StarterContent/Shapes/Shape_WideCapsule.Shape_WideCapsule));CubeMesh-SetStaticMesh(StaticCubeMesh.Object); }来到 RPCActor让前面的两个 Cube 只在服务端生成。 RPCActor.cpp // 引入头文件 #include CubeReplicate.h #include CubeNoReplicate.h #include RPCHelper.hARPCActor::ARPCActor() {//SetReplicates(true);bNetLoadOnClient true; // 设置为 网络同步到客户端 }void ARPCActor::BeginPlay() {Super::BeginPlay();// 判断是不是服务端if (GetWorld()-IsServer()) {GetWorld()-SpawnActorACubeReplicate(ACubeReplicate::StaticClass(), GetActorLocation() FVector::RightVector * 300.f, FQuat::Identity.Rotator());GetWorld()-SpawnActorACubeNoReplicate(ACubeNoReplicate::StaticClass(), GetActorLocation() - FVector::RightVector * 300.f, FQuat::Identity.Rotator());} }编译后将场景内的 RPCActor 删除。 新建一个 Blueprint 文件夹在里面创建一个基于 RPCActor 的蓝图命名为 RPCActor_BP然后将其拖进场景内。 运行游戏得到效果如图。可以看到服务端出现了 CubeReplicate 和 CubeNoReplicate 的实例但是客户端没有 CubeNoReplicate 的实例。说明 SetReplicates(bool) 生效了。 再试一下只在客户端生成只需要在判断条件前面加个 ! 取反就可以了。 RPCActor.cpp void ARPCActor::BeginPlay() {Super::BeginPlay();// 判断是不是客户端if (!GetWorld()-IsServer()) {GetWorld()-SpawnActorACubeReplicate(ACubeReplicate::StaticClass(), GetActorLocation() FVector::RightVector * 300.f, FQuat::Identity.Rotator());GetWorld()-SpawnActorACubeNoReplicate(ACubeNoReplicate::StaticClass(), GetActorLocation() - FVector::RightVector * 300.f, FQuat::Identity.Rotator());} }编译后再次运行可以看到这回服务端场景内没有生成两个 Actor 的实例而客户端出现了 CubeReplicate 和 CubeNoReplicate 的实例。说明客户端内生成对象时即便这个对象是可复制的它也不会生成到服务端。 最后将 RPCCourseCharacter.cpp 的 BeginPlay() 方法里的 Debug 语句注释掉。 4. 联网状态判断 本节课需要看的官方参考文档网络概述 【】 以下知识点内容截取自梁迪老师准备的 RPC 联网文档 1AActor 的 HasAuthority()返回 true 是说明 Actor 是该端创建的角色。 在关卡蓝图或者是 GameMode 以及默认放在场景中的 Actor 等对象使用这个函数可以用来判断是否是服务端因为关卡蓝图和 GameMode 与默认放在场景中的对象可以看做是由服务端生成的。 不推荐用 HasAuthority() 来判断当前端是不是服务端。梁迪老师推荐的用法是用来它来做下面这个 Actor 的角色判断。 2Actor 的角色判断 AActor 里的 ENetRole Role 枚举是用来识别角色的 Actor 的身份的。ENetRole 的几个值 ROLE_None该 Actor 在网络游戏中无角色不会复制。 ROLE_SimulatedProxy这个 Actor 是其他客户端在本机客户端的一个模拟代理 ROLE_AutonomousProxy这个 Actor 是本机客户端的自己控制的角色 ROLE_Authority这个 Actor 是服务器上的 Actor ROLE_MAX官方没有解释笔者个人猜测应该是代表该枚举的最大枚举值。 3是否是服务端判断不推荐使用 HasAuthority() 来判断 推荐使用 GetWorld()-IsServer() 或者 GetNetMode() 判断 4端的判断 使用 GetNetMode() 函数可以获取端的属性 ENetMode分类如下 NM_Standalone单独端单机游戏 NM_DedicatedServer专用服务器 NM_ListenServer监听服务器 NM_Client客户端 NM_MAX官方没有解释笔者个人猜测应该是代表该枚举的最大枚举值。 接下来我们打算测试一下 IsServer() 和 HasAuthority() 在 “判断当前端是不是服务端” 的需求上表现如何。 在复制 Cube 和不复制 Cube 的 BeginPlay() 函数输出一下调用上面两个方法后返回的结果。 CubeReplicate.cpp void ACubeReplicate::BeginPlay() {Super::BeginPlay();DDH::Debug() IsServer -- GetWorld()-IsServer() ; HasAuthority() -- HasAuthority() ACubeReplicate BeginPlay DDH::Endl(); }CubeNoReplicate.cpp void ACubeNoReplicate::BeginPlay() {Super::BeginPlay();DDH::Debug() IsServer -- GetWorld()-IsServer() ; HasAuthority() -- HasAuthority() ACubeNoReplicate BeginPlay DDH::Endl(); }接上一节课结尾的代码此时两个 Cube 的生成逻辑是在客户端上运行的所以只有在客户端才会生成这两个 Cube服务端不会生成。 编译后运行可以看到左上角客户端输出的两句 Debug 信息IsServer() 返回的结果是 false符合预期而 HasAuthority() 返回的结果是 true说明这个方法不一定能判断当前端是服务端还是客户端。 重新调整下让两个 Cube 在服务端生成。 RPCActor.cpp void ARPCActor::BeginPlay() {Super::BeginPlay();// 将判断表达式的 ! 去掉if (GetWorld()-IsServer()) {GetWorld()-SpawnActorACubeReplicate(ACubeReplicate::StaticClass(), GetActorLocation() FVector::RightVector * 300.f, FQuat::Identity.Rotator());GetWorld()-SpawnActorACubeNoReplicate(ACubeNoReplicate::StaticClass(), GetActorLocation() - FVector::RightVector * 300.f, FQuat::Identity.Rotator());} }编译后运行下面和中间的 Debug 语句是服务端打印的上面的 Debug 语句是客户端打印的。此时 HasAuthority() 确实在服务端则输出了 true在客户端输出了 false。两次测试结果相比之下还是 IsServer() 更适合用于判断当前端的性质。 随后将 CubeReplicate 和 CubeNoReplicate 的 BeginPlay() 内的 Debug 语句注释掉。 接下来我们测试一下 AActor 的 GetNetMode() 方法用于获取当前端类型 ENetMode 的值。 RPCActor.h protected:// 获取端类型的枚举后以文本形式输出void EchoNetMode();RPCActor.cpp void ARPCActor::BeginPlay() {// 测试完毕后记得注释掉EchoNetMode(); }void ARPCActor::EchoNetMode() {ENetMode NetMode GetNetMode();switch (NetMode){case NM_Standalone:DDH::Debug() NM_Standalone DDH::Endl();break;case NM_DedicatedServer:DDH::Debug() NM_DedicatedServer DDH::Endl();break;case NM_ListenServer:DDH::Debug() NM_ListenServer DDH::Endl();break;case NM_Client:DDH::Debug() NM_Client DDH::Endl();break;case NM_MAX:DDH::Debug() NM_MAX DDH::Endl();break;} }编译后运行游戏很明显 Client 是客户端输出的ListenServer 是服务端输出的。 如果将运行模式调整如下后运行游戏则会显示 NM_Standalone。
http://www.w-s-a.com/news/939568/

相关文章:

  • 天津做网站的网络公司wordpress免费的模板
  • 有哪些关于校园内网站建设的法律如何申请免费网站空间
  • 玉溪市网站建设龙口网页定制
  • 网站开发都用什么软件上海景观设计公司10强
  • 网站建设氵金手指下拉十二深圳网站建设售后服务
  • 上海网站设计价青海企业网站制作
  • 静态网站做新闻系统深圳外贸网站建设哪家好
  • 网站如何做词360免费wifi老是掉线怎么办
  • 网站建设分金手指排名十八iis10 wordpress
  • 成都网站优化公司哪家好网站建设帮助中心
  • 做外单什么网站好佛山市建设企业网站服务机构
  • 哪些网站是单页面应用程序北京门头沟山洪暴发
  • 织梦(dedecms)怎么修改后台网站默认"织梦内容管理系统"标题关键词优化收费标准
  • 网站设计和备案企业官网网站建设免费
  • 公司概况-环保公司网站模板搜索引擎营销的基本流程
  • 门户网站建设经验天津市建设银行租房网站
  • 百度推广 帮做网站吗怎样修改网站的主页内容
  • 网站怎么做dns解析公司官网改版方案
  • 湛江市住房和城乡建设局网站杭州网站公司哪家服务好
  • 设计网站公司湖南岚鸿设计镜像的网站怎么做排名
  • 你注册过哪些网站微信app下载安装官方版2019
  • 杭州滨江的网站建设公司人才招聘网网站策划方案
  • 门户网站是指提供什么的网站网站优化需要工具
  • 和小男生做的网站代理公司注册步骤
  • 天猫网站建设的目标是什么seo有些什么关键词
  • 网站前端建设都需要什么莱芜信息港网页
  • 如何做360网站优化网站建设培训教程新手入门到精通
  • 做网站有的浏览器怎么做网站网站赚钱
  • 织梦 做网站 教程百度登录个人中心官网
  • ftp怎么修改网站wordpress分享积分