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

成都网站登记备案查询互联网广告投放公司

成都网站登记备案查询,互联网广告投放公司,微信模板编辑器,怎么对网站标注做记号在这一篇文章里#xff0c;我们接着实现存档的功能#xff0c;保存当前玩家的生成位置#xff0c;游戏里有很多中方式去实现玩家的位置存储#xff0c;这里我们采用检查点的方式#xff0c;当玩家接触到当前检查点后#xff0c;我们可以通过检查点进行保存玩家的状态我们接着实现存档的功能保存当前玩家的生成位置游戏里有很多中方式去实现玩家的位置存储这里我们采用检查点的方式当玩家接触到当前检查点后我们可以通过检查点进行保存玩家的状态后续也能够实现检查点移动玩家等等功能。 实现定义角色生成位置 存档加载关卡后需要一个出生位置如果场景里有多个PlayerStart我们如何确定让角色在哪个PlayerStart生成呢 答案是我们可以为每个PlayerStart设置标签然后覆写GameMode的选择初始点的函数来实现。 首先我们实现对数据的全局存储这里需要使用到GameInstance我们将其作为父类实现一个派生类来实现自定义的需求。 设置自定义命名 在类里我们存储几个值一个是切换关卡时需要获取的PlayerStart的标签命名另外就是如果需要保存所需的存档名称和索引。 UCLASS() class RPG_API URPGGameInstance : public UGameInstance {GENERATED_BODY()public://角色进入关卡后默认生成的PlayerStart的TagUPROPERTY()FName PlayerStartTag FName();//当前使用的或后续保存内容到的存档名称UPROPERTY()FString LoadSlotName FString();//当前使用活后续保存的存档索引UPROPERTY()int32 LoadSlotIndex 0; };然后在我们自定义的GameMode里增加一个参数用于设置玩家生成的PlayerStart的标签 //角色切换关卡后默认生成位置的PlayerStart的标签UPROPERTY(EditDefaultsOnly)FName DefaultPlayerStartTag;//覆写父类的选择PlayerStart函数修改为可以通过Tag获取生成位置virtual AActor* ChoosePlayerStart_Implementation(AController* Player) override;函数实现这里我们会获取到关卡里的所有的PlayerStart然后从GameInstance获取需要生成的标签遍历获取到对应的PlayerStart生成所以只需要在进入关卡前将GameInstance的标签修改了然后进入场景时就可以自动寻找对应的PlayerStart去生成。 AActor* ARPGGameMode::ChoosePlayerStart_Implementation(AController* Player) {const URPGGameInstance* RPGGameInstance CastURPGGameInstance(GetGameInstance());//获取关卡里的所有PlayerStart实例TArrayAActor* Actors;UGameplayStatics::GetAllActorsOfClass(GetWorld(), APlayerStart::StaticClass(), Actors);if(Actors.Num() 0){//获取到第一个实例对象AActor* SelectedActor Actors[0];for(AActor* Actor : Actors){if(APlayerStart* PlayerStart CastAPlayerStart(Actor)){//判断PlayerStart的Tag设置是否为指定的Tagif(PlayerStart-PlayerStartTag RPGGameInstance-PlayerStartTag){SelectedActor PlayerStart;break;}}}return SelectedActor;}return nullptr; }添加PlayerStart标签配置 我们需要在存档里实现对关卡里的开始标签的存储在读取存档进入关卡时可以明确知道角色需要在哪里生成。 所以我们需要在LoadScreenSaveMode存档类和存档ViewModel视图模型里增加PlayerStart标签配置属性。 //存储玩家关卡出生位置的标签UPROPERTY()FName PlayerStartTag;在创建新存档时使用GameMode设置的默认PlayerStart标签 接着在GameMode存储存档时将存档的视图模型的中的PlayerStart标签存储到存档 存储没问题了就是读取存档时将存档里存储的PlayerStart标签设置给存档的视图模型 最后在我们在加载界面视图模型进入游戏的函数里在调用加载关卡之前将PlayerStart标签存储到GameInstance里进入关卡后然后再通过我们覆写的函数获取对应标签的PlayerStart void UMVVM_LoadScreen::EnterGameButtonPressed(const int32 Slot) {ARPGGameMode* RPGGameMode CastARPGGameMode(UGameplayStatics::GetGameMode(this));//设置全局数据方便后续使用URPGGameInstance* RPGGameInstance CastURPGGameInstance(RPGGameMode-GetGameInstance());RPGGameInstance-LoadSlotName LoadSlots[Slot]-GetSlotName();RPGGameInstance-LoadSlotIndex LoadSlots[Slot]-SlotIndex;RPGGameInstance-PlayerStartTag LoadSlots[Slot]-PlayerStartTag;//进入场景RPGGameMode-TravelToMap(LoadSlots[Slot]); }创建蓝图 接下来我们编译打开UE在BP_GameMode里设置默认选择的PlayerStart的标签 接着我们基于GameInstance类创建一个蓝图 设置命名 在项目设置里将默认的GameInstance修改为我们所需的GameInstance 最后我们在场景里设置PlayerStart的标签注意如果多个PlayerStart设置了相同的对应的标签角色将在第一个获取的PlayerStart的位置生成。 创建检查点 在正常游戏流程里为了保存游戏进度开发者会使用某种方式让进度保存下来比如到达某个进度后自动保存又或者像生化危机里的打字机。 这里我们将实现一种检查点的类在角色接触后自动保存当前进度。 命名为检查点类我们将在里面增加一些额外的内容。 在类里我们将增加两个属性用于显示检查点的模型和触发保存游戏的碰撞盒子 private://检查点显示的模型UPROPERTY(VisibleAnywhere)TObjectPtrUStaticMeshComponent CheckpointMesh;//检查点模型使用的碰撞体UPROPERTY(VisibleAnywhere)TObjectPtrUSphereComponent Sphere;然后增加一个函数用于玩家角色和碰撞球碰撞后的逻辑处理 /*** 球碰撞体和物体发生碰撞后的回调* param OverlappedComponent 发生重叠事件的自身的碰撞体对象* param OtherActor 目标的actor对象* param OtherComp 目标的碰撞体组件* param OtherBodyIndex 目标身体的索引* param bFromSweep 是否为瞬移检测到的碰撞* param SweepResult 如果位置发生过瞬移直接设置到某处两个位置中间的内容会记录到此对象内*/UFUNCTION()virtual void OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult SweepResult); 接着增加一个函数玩家角色碰撞后的函数处理主要里面是创建了一个新的材质实例修改自发光表示检查点已经激活。 //当玩家角色和检测点产生碰撞后检查点被激活触发此函数void HandleGlowEffects();由于自发光亮起需要时间轴这个比较方便在蓝图里实现我们再增加一个需蓝图实现的函数。 /*** 检查点激活后的处理需要在蓝图中对其实现* param DynamicMaterialInstance 传入检查点模型的材质实例*/UFUNCTION(BlueprintImplementableEvent)void CheckpointReached(UMaterialInstanceDynamic* DynamicMaterialInstance);以下是整个.h文件 // 版权归暮志未晚所有。#pragma once#include CoreMinimal.h #include GameFramework/PlayerStart.h #include CheckPoint.generated.hclass USphereComponent; /*** */ UCLASS() class RPG_API ACheckPoint : public APlayerStart {GENERATED_BODY()public://构造函数ACheckPoint(const FObjectInitializer ObjectInitializer);protected:virtual void BeginPlay() override;/*** 球碰撞体和物体发生碰撞后的回调* param OverlappedComponent 发生重叠事件的自身的碰撞体对象* param OtherActor 目标的actor对象* param OtherComp 目标的碰撞体组件* param OtherBodyIndex 目标身体的索引* param bFromSweep 是否为瞬移检测到的碰撞* param SweepResult 如果位置发生过瞬移直接设置到某处两个位置中间的内容会记录到此对象内*/UFUNCTION()virtual void OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult SweepResult);/*** 检查点激活后的处理需要在蓝图中对其实现* param DynamicMaterialInstance 传入检查点模型的材质实例*/UFUNCTION(BlueprintImplementableEvent)void CheckpointReached(UMaterialInstanceDynamic* DynamicMaterialInstance);//当玩家角色和检测点产生碰撞后检查点被激活触发此函数void HandleGlowEffects(); private://检查点显示的模型UPROPERTY(VisibleAnywhere)TObjectPtrUStaticMeshComponent CheckpointMesh;//检查点模型使用的碰撞体UPROPERTY(VisibleAnywhere)TObjectPtrUSphereComponent Sphere; }; 在cpp里我们对函数进行实现首先在构造函数里我们实例化模型和碰撞体。 ACheckPoint::ACheckPoint(const FObjectInitializer ObjectInitializer): Super(ObjectInitializer) {//关闭帧更新PrimaryActorTick.bCanEverTick false;//创建检测点显示模型CheckpointMesh CreateDefaultSubobjectUStaticMeshComponent(CheckpointMesh);CheckpointMesh-SetupAttachment(GetRootComponent());CheckpointMesh-SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); //设置查询并产生物理CheckpointMesh-SetCollisionResponseToChannels(ECR_Block); //设置阻挡所有物体与其重叠//设置球碰撞体Sphere CreateDefaultSubobjectUSphereComponent(Sphere);Sphere-SetupAttachment(CheckpointMesh);Sphere-SetCollisionEnabled(ECollisionEnabled::QueryOnly); //设置其只用作查询使用Sphere-SetCollisionResponseToChannels(ECR_Ignore); //设置其忽略所有碰撞检测Sphere-SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); //设置其与Pawn类型物体产生重叠事件 }在游戏开始时绑定球碰撞体的重叠函数 void ACheckPoint::BeginPlay() {Super::BeginPlay();//绑定重叠事件Sphere-OnComponentBeginOverlap.AddDynamic(this, ACheckPoint::OnSphereOverlap); }接着实现重叠函数在触发重叠时我们需要实现保存当前的检查点标签然后在调用碰撞后处理函数 void ACheckPoint::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult SweepResult) {//if(OtherActor-ActorHasTag(Player)) //如果只需要判断是不是玩家角色通过标签判断即可if(OtherActor-ImplementsUPlayerInterface()){//修改存档当的检测点IPlayerInterface::Execute_SaveProgress(OtherActor, PlayerStartTag);//如果与碰撞体重叠的是HandleGlowEffects();} }然后我们取消碰撞检测提升性能并创建一个新的材质实例调用蓝图函数实现渐变发光效果。 void ACheckPoint::HandleGlowEffects() {//取消碰撞检查Sphere-SetCollisionEnabled(ECollisionEnabled::NoCollision);//创建一个新材质实例修改效果UMaterialInstanceDynamic* DynamicMaterialInstance UMaterialInstanceDynamic::Create(CheckpointMesh-GetMaterial(0), this);CheckpointMesh-SetMaterial(0, DynamicMaterialInstance);CheckpointReached(DynamicMaterialInstance); //触发检查点修改材质后的回调 }编译代码打开UE创建一个基于类的蓝图 在检测点里我们需要修改碰撞体大小和检查点的模型 大致效果如下可以按需设置 在平视角我们需要将PlayerStart和模型水平这样保证放置的时候防止PlayerStart的位置靠下生成角色生成到地面以下。 拖入场景中点击End建检测点将会自动附着到地面青蓝色箭头是玩家在检查点生成位置和朝向黄色碰撞球是激活检测点范围。 接着我们修改材质增加自发光相关节点设置GlowEnd最大亮度以及GlowControl来控制进度GlowControl值为1时将达到亮度的最大值。 接着我们创建一个实例去调节对应的参数。 接着在蓝图里实现碰撞函数回调使用时间轴修改GlowControl 在时间轴里去修改更新的值 我们将放置到场景里的检查点的设置其标签可以用来实现保存通过标签去寻找位置。 实现PlayerStart标签的保存 我们要实现玩家角色在场景中接触到检查点后更新存档将当前的检查点的值保存到存档里。 首先在GameMode类里增加两个函数一个用于获取当前使用的存档另一个是将修改后的存档保存下来。 //获取到当前游戏进行中所使用的存档数据ULoadScreenSaveGame* RetrieveInGameSaveData() const;/*** 保存游戏中的进度* param SaveObject 需要保存的数据*/void SaveInGameProgressData(ULoadScreenSaveGame* SaveObject) const;实现这里我们可以在GameInstance身上获取到存档使用的Name和Index通过这两项获取到存档数据。 保存函数这里我们还需要使用存档的标签去修改GameInstance身上的PlayerStart的标签。然后保存。 ULoadScreenSaveGame* ARPGGameMode::RetrieveInGameSaveData() const {const URPGGameInstance* RPGGameInstance CastURPGGameInstance(GetGameInstance());//从游戏实例获取到存档名称和索引const FString InGameLoadSlotName RPGGameInstance-LoadSlotName;const int32 InGameLoadSlotIndex RPGGameInstance-LoadSlotIndex;//获取已保存的存档数据return GetSaveSlotData(InGameLoadSlotName, InGameLoadSlotIndex); }void ARPGGameMode::SaveInGameProgressData(ULoadScreenSaveGame* SaveObject) const {URPGGameInstance* RPGGameInstance CastURPGGameInstance(GetGameInstance());//修改下一次复活的检测点RPGGameInstance-PlayerStartTag SaveObject-PlayerStartTag;//从游戏实例获取到存档名称和索引const FString InGameLoadSlotName RPGGameInstance-LoadSlotName;const int32 InGameLoadSlotIndex RPGGameInstance-LoadSlotIndex;//保存存档UGameplayStatics::SaveGameToSlot(SaveObject, InGameLoadSlotName, InGameLoadSlotIndex); }接着在玩家角色接口这里增加一个函数用于碰撞触发后保存存档使用 //保存游戏进度UFUNCTION(BlueprintNativeEvent, BlueprintCallable)void SaveProgress(const FName CheckpointTag);在玩家基类里覆写 virtual void SaveProgress_Implementation(const FName CheckpointTag) override;实现这里我们获取到GameMode然后获取存档修改存档数据并保存回去。 void ARPGHero::SaveProgress_Implementation(const FName CheckpointTag) {if(const ARPGGameMode* GameMode CastARPGGameMode(UGameplayStatics::GetGameMode(this))){//获取存档ULoadScreenSaveGame* SaveGameData GameMode-RetrieveInGameSaveData();if(SaveGameData nullptr) return;//修改存档数据SaveGameData-PlayerStartTag CheckpointTag;//保存存档GameMode-SaveInGameProgressData(SaveGameData);} }我们在与检查点碰撞时已经调用此函数实现了存档的修改保存。 最后我们在场景里多加几个检查点来测试效果。创建文档角色会生成在一个检查点上然后我们走到另一个检查点上重新进入游戏查看角色下一次会不会生成在最后退出的检查点旁边如果能够证明代码无误。 实现角色已经激活的检测点一直高亮 我们现在制作的当前检查点效果还没有实现的一项是让玩家已经激活的检查点一直保持高亮状态这样如果玩家迷路了可以清除的得知这一段路之前探索过。 为了实现这个效果我们需要将之前已经探索到的检查点都记录下来然后在进入场景后每次激活将信息记录到存档里。在进入一个新关卡时在GameMode的BeginPlayer会触发我们会在此函数里处理检查点是否需要高亮。 首先我们在SaveGame类增加一个参数用于存储检查点数组用于存储角色已经激活的检查点 //当前已经激活的检测点UPROPERTY()TArrayFName ActivatedPlayerStatTags TArrayFName();然后将检查点类的激活函数修改为public这样可以在类以外调用 接着我们增加一个私有函数用于高亮已经激活的检查点 private://高亮已经激活的检查点void HighlightEnabledCheckpoints(TArrayAActor* CheckPoints) const;函数实现我们将获取存档并遍历所有的检查点如果检查点的Tag存在于已激活的数组内我们将检查点进行高亮显示。 void ARPGGameMode::HighlightEnabledCheckpoints(TArrayAActor* CheckPoints) const {//获取存档ULoadScreenSaveGame* SaveGameData RetrieveInGameSaveData();if(SaveGameData nullptr) return;//遍历关卡内的所有的检查点如果数组里存在将高亮显示for(AActor* Actor : CheckPoints){if(ACheckPoint* CheckPoint CastACheckPoint(Actor)){if(SaveGameData-ActivatedPlayerStatTags.Contains(CheckPoint-PlayerStartTag)){CheckPoint-HandleGlowEffects();}}} }在关卡打开后生成角色时我们调用此函数进行场景关卡的检查点进行初始化高亮 最后还有保存已经激活的检查点我们可以选择在保存角色的存档时候将当前检查点的标签保存进去。 重点你每个添加到关卡的检查点要做到全局不同也就是每个关卡的检查点都不要重名我们可以考虑关卡检查点的索引方式去设置检查点的tag。
http://www.laogonggong.com/news/110582.html

相关文章:

  • 上海建站中心夫妻网站开发
  • 建设银行的网站用户名是什么意思厦门营销型网站
  • 网站设计合同模板wordpress还是shopfiy
  • 企业网站搭建费用wordpress微信公众号插件
  • 初级网站开发的自我推荐网络公司 给 客户网站备案
  • 做网站gzip压缩郑州做网站要多少钱
  • 网站服务器崩溃宁波网站建设哪里好
  • 江门当地的免费网站优化网站域名建设怎么填写
  • 2017流行的网站风格绍兴网络推广公司
  • 花都网站建设设计dedecms导航网站模板
  • 安徽网站建设流程昆明市做网站
  • 企业网站建设方案 功能规划wordpress极简风
  • 西宁高端企业网站建设广州市白云区最新消息
  • 东莞seo建站投放百度推广怎么登陆
  • 网站怎么接广告赚钱网站解封
  • 网页设计和网站开发哪个好婚庆公司网页设计模板
  • 做网站的网站赚钱吗晋城市企业网站
  • 如何做网站优化并快速提高权重做优化关键词
  • 网站模板的制作怎么做wordpress 静态文件大
  • 中国建设银行信用卡网站首页网站建设一条龙服务
  • 如何把旅行社网站做的好看wordpress 镜像
  • 简约的网站设计界面织梦cms做多语言的网站
  • 东莞做网站推广建筑企业名单和电话
  • 一个域名两个网站魏县网站建设推广
  • 网页设计与网站建设景点介绍dz论坛seo
  • 动易网站模板制作方法高端开发网站系统
  • 网络编辑的网站建设题网站开发前端的工作内容是什么
  • 为进一步加强网站建设医院工程建设网站
  • 农家乐网站建设网站首页被k怎么办
  • 秦皇岛制作网站网站建设更新维护工作