UE5 C++ 跑酷游戏练习 Part1

一.修改第三人称模板的 Charactor

1.随鼠标将四处看的功能的输入注释掉。

void ARunGANCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{// Set up action bindingsif (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {//JumpingEnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump);EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);//MovingEnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ARunGANCharacter::Move);//Looking//EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ARunGANCharacter::Look);}

2.在Tick里,注释掉计算左右方向的部分。只让它获得向前的方向。再加个每帧都朝,正前方输入的逻辑。

void ARunGANCharacter::Tick(float DeltaSeconds)
{Super::Tick(DeltaSeconds);GetController()->SetControlRotation(FMath::RInterpConstantTo(GetControlRotation(),DesireRotation,GetWorld()->GetRealTimeSeconds(),10.f));//const FRotator Rotation = Controller->GetControlRotation();const FRotator YawRotation(0, Rotation.Yaw, 0);// get forward vectorconst FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);// get right vector //const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);//AddMovementInput(ForwardDirection, 1);
}

3.修改按下输入,调用的Move里的逻辑。让它如果转向,就按自己输入的X方向。旋转90度。

如果不转向,按照人物控制当前的朝向,计算左右的向量,并添加左右输入。

相当于一直向前跑,不转向可以左右调整。

if (bTurn)
{ //GEngine->AddOnScreenDebugMessage(-1,5.0f,FColor::Red,TEXT("Turn"));FRotator NewRotation = FRotator(0.f,90.f*(MovementVector.X), 0.f);FQuat QuatA = FQuat(DesireRotation);FQuat QuatB = FQuat(NewRotation);DesireRotation = FRotator(QuatA * QuatB);bTurn = false;
}
else
{// find out which way is forwardconst FRotator Rotation = Controller->GetControlRotation();const FRotator YawRotation(0, Rotation.Yaw, 0);// get forward vector//const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);// get right vector const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);//ForwardDirection = FVector(0,0,0);// add movement //AddMovementInput(ForwardDirection, 0);  //   AddMovementInput(RightDirection, MovementVector.X);/*	if (Controller->IsLocalPlayerController()){APlayerController* const PC = CastChecked<APlayerController>(Controller);}*///GetCharacterMovement()->bOrientRotationToMovement = false;//
}

4.这里转向的方向DesireRotation,会被一直赋值到控制器(Controller->GetControlRotation)。进而影响我们 向前方向。因为Tick里一直在修正。左右会在,Move回调函数里添加,也受控制器的影响。

void ARunGANCharacter::Tick(float DeltaSeconds)
{Super::Tick(DeltaSeconds);GetController()->SetControlRotation(FMath::RInterpConstantTo(GetControlRotation(),DesireRotation,GetWorld()->GetRealTimeSeconds(),10.f));//const FRotator Rotation = Controller->GetControlRotation();const FRotator YawRotation(0, Rotation.Yaw, 0);// get forward vectorconst FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);// get right vector //const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);//AddMovementInput(ForwardDirection, 1);
}

人物逻辑就写好了,一直跑,Turn为True时转90.其余时间,相当于一直按W,你自己决定要不要A,D,斜向跑。

二.写碰撞,碰撞时,能实现转向。

创建TurnBox C++ Actor类。在里面,添加UBoxComponent组件,添加碰撞的回调函数。内容也很简单,如果是 角色碰撞,让它的装箱变量变为True。

#include "TurnBox.generated.h"class UBoxComponent;
UCLASS()
class RUNGAN_API ATurnBox : public AActor
{GENERATED_BODY()UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = Box,meta = (AllowPrivateAccess = "true"))UBoxComponent* Box;public:	// Sets default values for this actor's propertiesATurnBox();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;UFUNCTION()void CharacterOverlapStart(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool  bFromSweep, const FHitResult& SweepResult);// UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);UFUNCTION()void CharacterOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);//UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex);
};

这里实例化组件,就不写了。把角色的头文件,包含进去。绑定回调,回调里判断逻辑。

// 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;}
}

三.开始写路的逻辑,随机生成。

1.准备好道路资源

2.这里将道路,分为直道,转弯道,上下道。使用了UE创建枚举的方式。

#pragma once
#include"CoreMinimal.h"
#include "RunGANType.generated.h"
UENUM()
enum class FRoadType :uint8   //只需要一个字节,更高效 0-255
{StraitFloor,TurnFloor,UPAndDownFloor,MAX,
};

3.然后我们创建道路类,写上通用逻辑。在头文件,将道路类型加上,并前项声明 指针 指向的组件类。

#include "../../RunGANType.h"
#include "RunRoad.generated.h"
class UBoxComponent;
class USceneComponent;
class UStaticMeshComponent;
class UArrowComponent;UCLASS()
class RUNGAN_API ARunRoad : public AActor
{GENERATED_BODY()//场景组件UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "C_J", meta = (AllowPrivateAccess = "true"))USceneComponent* SceneComponent;//根组件UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "C_J", meta = (AllowPrivateAccess = "true"))USceneComponent* RunRoadRootComponent;//碰撞UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "C_J",meta = (AllowPrivateAccess = "true"))UBoxComponent* BoxComponent;//模型UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "C_J",meta = (AllowPrivateAccess = "true"))UStaticMeshComponent* RoadMesh;//方向UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "C_J",meta = (AllowPrivateAccess = "true"))UArrowComponent* SpawnPointMiddle;UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "C_J",meta = (AllowPrivateAccess = "true"))UArrowComponent* SpawnPointRight;UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "C_J",meta = (AllowPrivateAccess = "true"))UArrowComponent* SpawnPointLeft;//地板类型UPROPERTY(EditDefaultsOnly,Category = "TowerType")  //EditDefaultsOnly:蓝图可以编译,但是在主编译器不显示所以不可以编译FRoadType RoadType;public:	// Sets default values for this actor's propertiesARunRoad();FTransform GetAttackToTransform(const FVector& MyLocation);
protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;UFUNCTION()void CharacterOverlapStart(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool  bFromSweep, const FHitResult& SweepResult);// UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);UFUNCTION()void CharacterOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

4.实现逻辑

#include"Components/BoxComponent.h"
#include"Components/SceneComponent.h"
#include"Components/StaticMeshComponent.h"
#include"Components/ArrowComponent.h"

CreateDefaultSubobject<T>实例化组件,SetupAttachment添加组件,Root根组件,Father在根组件下,其余在Father组件下。

ARunRoad::ARunRoad()
{// 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;//generateBox = CreateDefaultSubobject<UBoxComponent>(TEXT("GenerateBox"));//实例化SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Father"));RunRoadRootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));RootComponent = RunRoadRootComponent;RoadMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("RoadMesh"));BoxComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("Box"));SpawnPointMiddle = CreateDefaultSubobject<UArrowComponent>(TEXT("SpawnPointMiddle"));SpawnPointRight = CreateDefaultSubobject<UArrowComponent>(TEXT("SpawnPointRight"));SpawnPointLeft = CreateDefaultSubobject<UArrowComponent>(TEXT("SpawnPointLeft"));//附加顺序SceneComponent->SetupAttachment(RootComponent);RoadMesh->SetupAttachment(SceneComponent);BoxComponent->SetupAttachment(SceneComponent);SpawnPointMiddle->SetupAttachment(SceneComponent);SpawnPointRight->SetupAttachment(SceneComponent);SpawnPointLeft->SetupAttachment(SceneComponent);
}

这样初步就将路结构搭建好了。后续开始写GameMode生成每一个路面。

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

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

相关文章

python+unity手势控制地球大小

效果图如下 具体操作如下 1 在unity窗口添加一个球体 2 给球体添加材质,材质图片使用地球图片 地球图片如下 unity材质设置截图如下 3 编写地球控制脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class test : MonoBehavio…

RK3588/算能/Nvidia智能盒子:加速山西铝业智能化转型,保障矿业皮带传输安全稳定运行

近年来&#xff0c;各类矿山事故频发&#xff0c;暴露出传统矿业各环节的诸多问题。随着全国重点产煤省份相继出台相关政策文件&#xff0c;矿业智能化建设进程加快。皮带传输系统升级是矿业智能化的一个重要环节&#xff0c;同时也是降本增效的一个重点方向。 △各省份智能矿山…

《UNIX环境高级编程》第三版(电子工业出版社出品)——两年磨一剑的匠心译作

历时两年&#xff0c;《UNIX环境高级编程》的翻译工作终于落下帷幕。这一路走来&#xff0c;真可谓是如鱼饮水&#xff0c;冷暖自知。还记得最初看到招募译者消息的那一刻&#xff0c;内心的激动难以言表。我毫不犹豫地报名&#xff0c;而后经历了试译、海选等激烈的角逐&#…

【CMake】Linux 下权限丢失与软链接失效问题

【CMake】Linux 下权限丢失与软链接失效问题 文章目录 【CMake】Linux 下权限丢失与软链接失效问题问题概述解决方法1 - 安装目录2 - 安装文件3 - 手动指定 使用 Linux 下原生命令行注意事项参考链接 问题概述 一般使用 CMake 安装&#xff0c;在 Windows 平台不会出问题&…

基于块生成最大剩余空间的三维装箱算法

问题简介 三维装箱问题&#xff08;3D Bin Packing Problem&#xff0c;3D BPP&#xff09;是一类组合优化问题。它涉及到将一定数量的三维物品放入一个或多个三维容器&#xff08;称为“箱子”&#xff09;中&#xff0c;同时遵循一定的约束&#xff0c;通常目标是最大化空间…

后端开发中缓存的作用以及基于Spring框架演示实现缓存

缓存的作用及演示 现在我们使用的程序都是通过去数据库里拿数据然后展示的 长期对数据库进行数据访问 这样数据库的压力会越来越大 数据库扛不住了 创建了一个新的区域 程序访问去缓存 缓存区数据库 缓存里放数据 有效降低数据访问的压力 我们首先进行一个演示 为了演示…

力扣207题“课程表”

在本篇文章中&#xff0c;我们将详细解读力扣第207题“课程表”。通过学习本篇文章&#xff0c;读者将掌握如何使用拓扑排序和深度优先搜索&#xff08;DFS&#xff09;来解决这一问题&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0…

滚球游戏笔记

1、准备工作 (1) 创建地面&#xff1a;3D Object-Plane&#xff0c;命名为Ground (2) 创建小球&#xff1a;3D Object-sphere&#xff0c;命名为Player&#xff0c;PositionY 0.5。添加Rigidbody组件 (3) 创建文件夹&#xff1a;Create-Foder&#xff0c;分别命名为Material…

css3多列布局

css3多列布局 colmns属性 columns属性是一个简写属性 column-count属性&#xff1a;定义列的数量或者允许的最大列数 auto 为默认值&#xff0c;用于表示列的数量由其他css属性决定number 必须是正整数&#xff0c;用于定义列数量 column-width属性&#xff1a;定义列的宽度 …

Java入门第01篇

文章目录 前言 一、Java是什么&#xff1f; 二、Java开发工具 1.Java 2.开发工具 3.构建工具 三、Java开发过程 1.IDEA操作 2.Maven操作 2.1本地jar包的情况 3.docker操作 总结 前言 机缘巧合&#xff0c;接触到了Java开发&#xff0c;那就把了解学习到的一些东西…

【Arc gis】使用DEM提取流域范围

地址&#xff1a;arcgis DEM 提取流域范围&#xff08;详细教程&#xff09;(空间分析--Hydrology)_gis的gridcode是什么意思-CSDN博客

AUTOSAR学习

文章目录 前言1. 什么是autosar&#xff1f;1.1 AP&#xff08;自适应平台autosar&#xff09;1.2 CP&#xff08;经典平台autosar)1.3 我的疑问 2. 为什么会有autosar3.autosar的架构3.1 CP的架构3.1.1 应用软件层3.1.2 运行时环境3.1.3 基础软件层 3.2 AP的架构 4. 参考资料 …

shell脚本中的变量

关于Linux操作系统中当前shell进程与子shell进程的详细解释 如上图所示&#xff0c;使用ps -f可以当前查看Linux操作系统中当前正在运行的进程。 然后敲bash后&#xff0c;相当于在当前的bash shell环境下又创建了一个子bash shell的进程&#xff0c; 如上图所示&#xff0c;…

Qt | QPalette 类(调色版)

01、简介 1、需要用到 QWidget类中的如下属性 palette:QPalette 访问函数:const QPalette &palette() const; void setPalette(const QPalette&);  该属性描述了部件的调色板。在渲染标准部件时,窗口部件的样式会使用调色板,而且不同的平台或不同的样式通常具…

win环境安装Node.js的多种方式

今天我们分享win环境安装Node.js的多种方式&#xff1a; 首先要明白Node.js是一个JavaScript运行环境&#xff0c;它基于Google的V8引擎进行封装&#xff0c;允许JavaScript运行在服务器端。Node.js让JavaScript成为一种与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语…

图神经网络入门(1)-networkx

简介 NetworkX是一个Python语言的图论建模工具&#xff0c;用于创建、操作复杂网络结构&#xff08;如图、有向图等&#xff09;。它提供了许多用于分析网络、生成随机网络、以及可视化网络的函数和工具。用户可以利用NetworkX来研究复杂网络的拓扑结构、节点间的关系以及路径查…

【GIS案例】居住环境适宜性评价

目的: 拟购买住宅,需在现有条件下,基于地理空间分析方法和空间认知模型对居住环境进行综合评价。通过该实验掌握基于GIS的地理空间认知方法及土地适宜性评价基本原理与方法。 数据: (1)人口调查图(pop); (2)公园入口图(parkgate); (3)医院分布图(hospital…

【RK3588/算能/Nvidia智能盒子】挑战「无电无网」部署AI算法,守护大亚湾荃美石化码头工地安全

“万顷碧波之上&#xff0c;一座千米钢栈桥如蛟龙出水&#xff0c;向大海蜿蜒。钢栈桥上的项目建设者正在加紧作业&#xff0c;为助推惠州大亚湾加快建设成为世界级绿色石化基地全力奋战。”这是不久前北京日报对大亚湾惠州港荃湾港区荃美石化码头工地的描述。 △ 图片来源于北…

vue项目cnpm i 报错

报错内容&#xff1a; Install fail! TypeError: Cannot convert undefined or null to object npminstall version: 3.28.1 npminstall args: C:\Program Files\nodejs\node.exe C:\Users\user\AppData\Roaming\nvm\v12.4.0\node_modules\cnpm\node_modules\npminstall\bin\i…

序列化与反序列化漏洞实例

实验环境&#xff1a; 本次的序列化与反序列化漏洞为2021年强网杯上的一道比赛题目&#xff0c;我使用phpstudy集成环境将其测试环境搭建在了本地&#xff0c;如下。涉及的几个页面php为&#xff1a; index.php function.php myclass.php index.php : <?php // inde…