UE5 C++跑酷练习(Part2)

一.首先GameMode里有Actor数组,组装直线路,和左右路

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "RunGANGameMode.generated.h"UCLASS(minimalapi)
class ARunGANGameMode : public AGameModeBase
{GENERATED_BODY()UPROPERTY()TArray<TSubclassOf<class AActor>> StraitArray;UPROPERTY()TArray<TSubclassOf<class AActor>> LeftRightArray;UPROPERTY()TSubclassOf<AActor> NewRoad;UPROPERTY()FTransform NextTransforms;
public:ARunGANGameMode();TSubclassOf<AActor> RandomInputFloor();virtual void BeginPlay();//添加我们地板void AddFloor();
};

UPROPERTY()不会被GC掉

TSubclassOf

在Unreal中经常会有在蓝图或者C++中声明某些UClass,便于后续用来创建对应的对象,但是如果只是填了一个UClass指针的话,这并不好用。这是因为UClass*可以指代任意UObject,所以在蓝图或者编辑器中选择对应的UClass的时候不好选择,因为基本上所有的UClass都会出现在下拉框内。Unreal也提出对应的解决方案,那就是TSubclassOf,它能够避免能上面说的问题,TSubclassOf能够约束下拉框中只会出现继承于T的类或者T本身,并且C++层面也能实现类型安全,如果给TSubclassOf对象赋值一个类型不兼容的UClass,则会得到编译错误。

二.在GameMode构造函数时,可以使用动态加载 Actor到路面类型。静态加载主角到PlayerPawnBPClass类中,再设置到Gamemode默认的Pawn里(DefaultPawnClass)。


#include "RunGANGameMode.h"
#include "RunGANCharacter.h"
#include "UObject/ConstructorHelpers.h"
#include "Actor/CollisionInteraction/RunRoad.h"
ARunGANGameMode::ARunGANGameMode()
{// set default pawn class to our Blueprinted characterstatic ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter"));if (PlayerPawnBPClass.Class != NULL){DefaultPawnClass = PlayerPawnBPClass.Class;}StraitArray.Add(LoadClass<AActor>(NULL,TEXT("/Script/Engine.Blueprint'/Game/Environment/BP/BP_StraightRoad_1.BP_StraightRoad_1_C'")));StraitArray.Add(LoadClass<AActor>(NULL, TEXT("/Script/Engine.Blueprint'/Game/Environment/BP/BP_StraightRoad_2.BP_StraightRoad_2_C'")));StraitArray.Add(LoadClass<AActor>(NULL, TEXT("/Script/Engine.Blueprint'/Game/Environment/BP/BP_StraightRoad_3.BP_StraightRoad_3_C'")));StraitArray.Add(LoadClass<AActor>(NULL, TEXT("/Script/Engine.Blueprint'/Game/Environment/BP/BP_StraightRoad_4.BP_StraightRoad_4_C'")));LeftRightArray.Add(LoadClass<AActor>(NULL, TEXT("/Script/Engine.Blueprint'/Game/Environment/BP/BP_TurnLeftRoad.BP_TurnLeftRoad_C'")));LeftRightArray.Add(LoadClass<AActor>(NULL, TEXT("/Script/Engine.Blueprint'/Game/Environment/BP/BP_TurnRightRoad_2.BP_TurnRightRoad_2_C'")));
}

ConstructorHelpers::FClassFinder()和FObjectFinder()

静态加载指的是在构造函数中完成的加载方式,这种方式的弊端明显,就是需要写死路径,一旦改变路径读取失败很容易造成程序崩溃。

LoadObject<UClass>

也就是说LoadObject和LoadClass函数都用于在运行时加载UObject派生的对象,但是它们的用途和返回值有所不同。

`LoadObject`用于加载单个对象,可以是任何UObject派生类的实例,包括UClass、UTexture、UMaterial等。它会返回加载的对象,或者在加载失败时返回nullptr

同时,如果使用LoadClass()方法,路径名也必须带_C后缀(LoadObject不需要带_C后缀),例如,蓝图路径是:Blueprint'/Game/Blueprints/Test', 加后缀以后,则是:Blueprint'/Game/Blueprints/Test_C'

三.通过FMath::RandRange随机数从不同的类型中生成下个路面。并在一开始设置生成一个路面的位置。

TSubclassOf<AActor> ARunGANGameMode::RandomInputFloor()
{int32 i = FMath::RandRange(1,100);if (i <= 80){int32 Index = FMath::RandRange(0,StraitArray.Num()-1);return StraitArray[Index];}else{int32 Index = FMath::RandRange(0, LeftRightArray.Num() - 1);return LeftRightArray[Index];}return TSubclassOf<AActor>();
}
void ARunGANGameMode::BeginPlay()
{Super::BeginPlay();if (GetWorld()){NextTransforms = GetWorld()->GetFirstPlayerController()->GetPawn()->GetTransform();FVector InLocation = NextTransforms.GetLocation();InLocation.Y += 100.f;InLocation.Z -= 200.f;NextTransforms.SetLocation(InLocation);for (int32 i = 0; i < 9; i++){AddFloor();}}
}

四.添加地板逻辑,拼贴点位。

//添加我们的地板
void ARunGANGameMode::AddFloor()
{NewRoad = RandomInputFloor();if (NewRoad != NULL){FVector const MyLocation = NextTransforms.GetLocation();FRotator MyRotation(NextTransforms.Rotator());if (ARunRoad* MyRunRoad = GetWorld()->SpawnActor<ARunRoad>(NewRoad, MyLocation, MyRotation)){MyRunRoad->SetActorScale3D(FVector(10.f));NextTransforms = MyRunRoad->GetAttackToTransform(MyLocation);}}
}

五.AddFloor里使用的GetAttackToTransform是使用每个,路面自己对准的下一个路面的位置。

FTransform ARunRoad::GetAttackToTransform(const FVector& MyLocation)
{FTransform Transform;Transform.SetLocation(SpawnPointMiddle->GetComponentToWorld().GetLocation());Transform.SetRotation(SpawnPointMiddle->GetComponentQuat());return Transform;
}

六.通过跑步碰撞,判断。开启角色可以转弯的功能,

#include "TurnBox.h"
#include "Components/BoxComponent.h"
#include "../../RunGANCharacter.h"// Sets default values
ATurnBox::ATurnBox()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = false;Box = CreateDefaultSubobject<UBoxComponent>(TEXT("TurnBox"));RootComponent = Box;
}// Called when the game starts or when spawned
void ATurnBox::BeginPlay()
{Super::BeginPlay();	Box->OnComponentBeginOverlap.AddDynamic(this,&ATurnBox::CharacterOverlapStart);Box->OnComponentEndOverlap.AddDynamic(this, &ATurnBox::CharacterOverlapEnd);
}// Called every frame
void ATurnBox::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}void ATurnBox::CharacterOverlapStart(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{if (ARunGANCharacter* InCharacter =  Cast<ARunGANCharacter>(OtherActor)){InCharacter->bTurn = true;}
}void ATurnBox::CharacterOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{if (ARunGANCharacter* InCharacter = Cast<ARunGANCharacter>(OtherActor)){InCharacter->bTurn = false;}
}

TurnBox,位置不对。可以用蓝图具象化调整。

  碰撞显示

BP_TurnBox 的位置就是Arrow的位置,记住Dlay延迟一下,预防Scale位置会有问题偏差。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/876291.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

揭秘企业为何钟情定制红酒:品牌形象与不同的礼品的双重魅力

在商务世界的广阔天地里&#xff0c;红酒不仅仅是一种饮品&#xff0c;更是一种传递情感、展示品味的不同媒介。近年来&#xff0c;越来越多的企业开始钟情于定制红酒&#xff0c;其中洒派红酒&#xff08;Bold & Generous&#xff09;通过其品质和个性化的定制服务&#x…

网络访问(Socket/WebSocket/HTTP)

概述 HarmonyOS为用户提供了网络连接功能&#xff0c;具体由网络管理模块负责。通过该模块&#xff0c;用户可以进行Socket网络通滚、WebSocket连接、HTTP数据请求等网络通信服务。 Socket网络通信&#xff1a;通过Socket(嵌套字)进行数据通信&#xff0c;支持的协议包括UDP核…

《追问试面试》系列开篇

我们不管做任何事情&#xff0c;都是需要个理由&#xff0c;而不是盲目去做。 为什么写这个专栏&#xff1f; 就像我们被面试八股文时&#xff0c;市面上有很多面试八股文&#xff0c;随便一个八股文都是500&#xff0c;甚至1000面试题。诸多面试题&#xff0c;难道我们需要一…

基于微信小程序+SpringBoot+Vue的资料分享系统(带1w+文档)

基于微信小程序SpringBootVue的资料分享系统(带1w文档) 基于微信小程序SpringBootVue的资料分享系统(带1w文档) 校园资料分享微信小程序可以实现论坛管理&#xff0c;教师管理&#xff0c;公告信息管理&#xff0c;文件信息管理&#xff0c;文件收藏管理等功能。该系统采用了Sp…

vue3中element tabs标签页 tab-click事件无法拿到最新值

element tabs标签页有2个常用的事件方法&#xff0c;tab-click 和 tab-change tab-click事件 tab-click事件&#xff1a;当用户点击Tab标签时触发&#xff0c;有2个返回参数&#xff0c; (pane: TabsPaneContext, ev: Event) pane.props.name 中可以获取到最新的tab页签绑定值 …

jenkins参数化构建在UI中定义脚本中使用

先看配置&#xff1a; 流水线脚本&#xff1a; pipeline {agent {//label "${server}"label "${28}"}stages {stage(Hello) {steps {echo "--------------------------"// 只有这个可以输出变量echo "${character_argument}"echo &q…

网络通信---TCP协议1

今日内容 三次握手: 指建立tcp连接时&#xff0c;需要客户端和服务端总共发送三次报文确认连接。 四次挥手&#xff1a; 断开一个tcp连接&#xff0c;需要客户端和服务端发送四个报文以确认断开。 编程模型 TCP报文 客户端 服务端

E21.“详解函数递归”文中的趣味练习的答案

详解函数递归原文 高考标答&#xff1a; 思路&#xff1a; 代码实现&#xff1a; //这里取αn1 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> double function(double n) {if (1 n){return 2;}else{return 1 1.0 / (function(n - 1));} } int main() {int n …

大自然的传奇——龙宫

我们1小时后就到了龙宫&#xff0c;导游给我们买票去了&#xff0c;让我们去观景台上&#xff0c;看游客中心后面“龙”字草书。龙字田采用两种农作物套种&#xff0c;按季节区分&#xff0c;春天由油菜花和蚕豆进行套种&#xff0c;秋天由黑糯米和一般水稻进行套种。我们来的夏…

【NPU 系列专栏 2.4 -- 高速互连 NVLink 详细介绍】

请阅读【嵌入式及芯片开发学必备专栏】 文章目录 NVLink 简介NVLink 主要特点NVLink 应用场景NVLink 工作原理NVLink 实例介绍DL 中使用 NVLinkHPC 中使用 NVLinkSummaryNVLink 简介 NVLink 是 NVIDIA 开发的一种高速互连技术,旨在提升 GPU 与 GPU 之间以及 GPU 与 CPU 之间的…

帕金森病(PD)诊断:三种基于语音的深度学习方法

帕金森病&#xff08;Parkinson’s disease, PD&#xff09;是世界上第二大流行的神经退行性疾病&#xff0c;全球影响着超过1000万人&#xff0c;仅次于阿尔茨海默症。人们通常在65岁左右被诊断出患有此病。PD的一些症状包括震颤、肌肉僵硬和运动迟缓。这些症状往往出现在较晚…

在线教育数仓项目(数据采集部分1)

文章目录 数据仓库概念项目需求及架构设计项目需求分析系统数据流程设计框架版本选型集群规模估算集群资源规划设计 数据生成模块目标数据页面事件曝光启动播放错误 数据埋点主流埋点方式&#xff08;了解&#xff09;埋点数据上报时机埋点数据日志结构 服务器和JDK准备服务器准…

白鲸开源CEO郭炜荣获「2024中国数智化转型升级先锋人物」称号

2024年7月24日&#xff0c;由数据猿主办&#xff0c;IDC协办&#xff0c;新华社中国经济信息社、上海大数据联盟、上海市数商协会、上海超级计算中心作为支持单位&#xff0c;举办“数智新质力拓未来 2024企业数智化转型升级发展论坛——暨AI大模型趋势论坛”数据猿“年中特别策…

探索 Electron:构建用户友好的登录页面流程

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

指针的面试题

这里写目录标题 判断链表中是否有环描述代码检测链表中是否存在环链表中存在环想检测链表中是否存在环&#xff0c;而不需要找到环的入口 判断链表中是否有环 题目 描述 判断给定的链表中是否有环。如果有环则返回true&#xff0c;否则返回false。 数据范围&#xff1a;链表…

Spring Boot集成canal快速入门demo

1.什么是canal&#xff1f; canal 是阿里开源的一款 MySQL 数据库增量日志解析工具&#xff0c;提供增量数据订阅和消费。 工作原理 MySQL主备复制原理 MySQL master 将数据变更写入二进制日志&#xff08;binary log&#xff09;, 日志中的记录叫做二进制日志事件&#xff…

二叉树_堆(下卷)

前言 接前面两篇的内容&#xff0c;接着往下讲二叉树_堆相关的内容。 正文 那么&#xff0c;回到冒泡排序与堆排序的比较。 我们知道冒泡排序的时间复杂度为 O ( N 2 ) O(N^2) O(N2)&#xff0c;这个效率是不太好的。 那么&#xff0c;我们的堆排序的时间复杂度如何呢&…

017、Vue动态tag标签

文章目录 1、先看效果2、代码 1、先看效果 2、代码 <template><div class "tags"><el-tag size"medium"closable v-for"item,index in tags":key"item.path":effect"item.title$route.name?dark:plain"cl…

数据结构 - AVL树

文章目录 一、AVL树的介绍二、AVL树的实现1、基本框架2、查找3、插入4、删除5、测试6、总代码 三、AVL树的性能 一、AVL树的介绍 1、概念 AVL树&#xff08;Adelson-Velsky and Landis Tree&#xff09;是一种自平衡的二叉搜索树。它得名于其发明者G. M. Adelson-Velsky和E. M…

Vue 状态管理 Vue CLI

Vue 状态管理 & Vue CLI 1、状态管理2、集中状态管理2.1 Vuex2.1.1 Vuex核心概念2.1.2 Vuex Store实例2.1.3 Vuex Getter2.1.4 Vuex Mutation2.1.4 Vuex Actions2.1.4 Vuex Module 2.2 Pinia2.2.1功能增强 3、Vuex 实现原理4、Pinia 实现原理5、CLI5.1 实现 1、状态管理 将…