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…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
