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位置会有问题偏差。
相关文章:
 
UE5 C++跑酷练习(Part2)
一.首先GameMode里有Actor数组,组装直线路,和左右路 #include "CoreMinimal.h" #include "GameFramework/GameModeBase.h" #include "RunGANGameMode.generated.h"UCLASS(minimalapi) class ARunGANGameMode : public AG…...
 
从0开始搭建vue + flask 旅游景点数据分析系统(二):搭建基础框架
这一期目标是把系统的布局给搭建起来,采用一个非常简单的后端管理风格,可以参考官方的页面 https://element.eleme.cn/#/zh-CN/component/container 下面我们开始搭建,首先,安装一下vue-router,element-ui npm insta…...
【过滤器 vs 拦截器】SpringBoot中过滤器与拦截器:明智选择的艺术(如何在项目中做出明智选择)
文章目录 SpringBoot 过滤器 vs 拦截器过滤器 (Filter)定义特点使用场景实现步骤创建过滤器类注册过滤器(可选,如果不使用 WebFilter 注解) 拦截器 (Interceptor)定义特点使用场景实现步骤创建拦截器类注册拦截器 过滤器与拦截器的比较实际项…...
 
2024-06学习笔记
1.事务与数据库链接的占用 如果用Transactional注解,那在第一次与数据库交互的时候,就会打开数据库链接,再整个方法执行完,才会关闭数据库链接。 即使后边用的事务传播是required_new,那之前的事务也是被挂起,不会被…...
 
【VUE】封装一个追随鼠标的漂浮组件框架
红色箭头代表鼠标位置,蓝色区域跟随鼠标出现,鼠标进行其他操作的时候,蓝色区域隐藏。 vue全码 <template><divmousemove"updatePosition"mouseleave"hideDiv"class"container":style"{ positi…...
mapstruct与lombok结合使用
问题 如果同时使用mapstruct与lombok,需要多添加一个lombok支持mapstruct的依赖库。 解决 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId> </dependency><dependency><groupId&…...
【SpringBoot】Web开发之URL映射
RequestMapping("/getDataById/{id}") public String getDataById(PathVariable("id") Long id){ return "getDataById:"id; }46 如果URL中的参数名称与方法中的参数名称一致,则可以简化为: RequestMapping("/get…...
 
对递归的一些理解。力扣206题:翻转链表
今天在刷力扣的时候,在写一道翻转链表的题目的过程中,在尝试使用递归解决该问题的时候,第一版代码却每次都返回的是null,这个错误让我尝试去debug了一下,最终找出了问题,并且让我对递归有了一些更深的理解&…...
Kafka面试三道题
针对Kafka的面试题,从简单到困难,我可以给出以下三道题目: 1. Kafka的基本概念与优势 问题:请简要介绍Kafka是什么,并说明它相比传统消息队列的优势有哪些? 答案: Kafka定义:Apa…...
 
C/C++编程-算法学习-数字滤波器
数字滤波器 一阶低通滤波器结论推导11. 基本公式推导2. 截止频率 和 采样频率 推导 实现 二阶低通滤波器实现1实现2 一阶低通滤波器 结论 其基本原理基于以下公式: o u t p u t [ n ] α ∗ i n p u t [ n ] ( 1 − α ) ∗ o u t p u t [ n − 1 ] output[n] …...
 
maven介绍 搭建Nexus3(maven私服搭建)
Maven是一个强大的项目管理工具,它基于项目对象模型(POM:Project Object Model)的概念,通过XML格式的配置文件(pom.xml)来管理项目的构建 Maven确实可以被视为一种工程管理工具或项目自动化构…...
 
电商项目之如何判断线程池是否执行完所有任务
文章目录 1 问题背景2 前言3 4种常用的方法4 代码4.1 isTerminated()4.2 线程池的任务总数是否等于已执行的任务数4.3 CountDownLatch计数器4.4 CyclicBarrier计数器 1 问题背景 真实生产环境的电商项目,常使用线程池应用于执行大批量操作达到高性能的效果。应用场景…...
 
【前端 15】Vue生命周期
Vue生命周期 在Vue.js中,了解组件的生命周期对于开发者来说是至关重要的。Vue的生命周期指的是Vue实例从创建到销毁的一系列过程,每个阶段都对应着特定的生命周期钩子(或称为生命周期方法),允许我们在不同的时间点加入…...
 
PCIe总线-Linux内核PCIe软件框架分析(十一)
1.简介 Linux内核PCIe软件框架如下图所示,按照PCIe的模式,可分为RC和EP软件框架。RC的软件框架分为五层,第一层为RC Controller Driver,和RC Controller硬件直接交互,不同的RC Controller,其驱动实现也不相…...
 
视觉SLAM第二讲
SLAM分为定位和建图两个问题。 定位问题 定位问题是通过传感器观测数据直接或间接求解位置和姿态。 通常可以分为两类:基于已知地图的定位和基于未知地图的定位。 基于已知地图的定位 利用预先构建的地图,结合传感器数据进行全局定位。SLAM中的全局…...
 
mysql1055报错解决方法
目录 一、mysql版本 二、 问题描述 三、解决方法 1.方法一(临时) 2.方法二(永久) 一、mysql版本 mysql版本:5.7.23 二、 问题描述 在查询时使用group by语句,出现错误代码:1055…...
Java的@DateTimeFormat注解与@JsonFormat注解的使用对比
Java的DateTimeFormat注解与JsonFormat注解的使用对比 在Java开发中,处理日期和时间格式时,我们经常会使用到DateTimeFormat和JsonFormat注解。这两个注解主要用于格式化日期和时间,但在使用场景和功能上有所不同。本文将详细介绍这两个注解…...
 
德国云手机:企业移动办公解决方案
在现代商业环境中,移动办公已经成为一种趋势。德国云手机作为一种高效的解决方案,为企业提供了强大的支持。本文将探讨德国云手机如何优化企业的移动办公环境。 一、德国云手机的主要优势 高灵活性 德国云手机具有高度的灵活性,能够根据用户需…...
 
【React】useState:状态管理的基石
文章目录 一、什么是 useState?二、useState 的基本用法三、useState 的工作原理四、高级用法五、最佳实践 在现代前端开发中,React 是一个非常流行的库,而 useState 是 React 中最重要的 Hook 之一。useState 使得函数组件能够拥有自己的状态…...
商品中心关于缓存热key的解决方案
缓存热key一旦被击穿,流量势必会打到数据库,如果数据库崩了,游戏直接结束。 从两点来讨论:如何监控、如何解决。 如何监控 通过业务评估:比如营销活动推出的商品或者热卖的商品。基于LRU的命令,redis-cl…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
 
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
 
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
 
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
