【UE5 C++课程系列笔记】04——创建可操控的Pawn

embedded/2024/11/30 4:23:38/

根据官方文档创建一个可以控制前后左右移动、旋转视角、缩放视角的Pawn 。

步骤 

一、创建Pawn 

1. 新建一个C++类,继承Pawn类,这里命名为“PawnWithCamera”

2. 在头文件中申明弹簧臂、摄像机和静态网格体组件

3. 在源文件中引入组件所需库

 

在构造函数中创建组件实例

将StaticMesh组件附加在根组件上,再将SpringArm组件附加在StaticMesh组件上,最后将Camera组件附加在SpringArm组件的末端

设置一下SpringArm组件的相对位置和旋转、弹簧臂长度、开启相机滞后、相机滞后速度

设置自动控制该Pawn

4. 编译好后,创建基于“PawnWithCamera”的蓝图类“BP_PawnWithCamera”

将“BP_PawnWithCamera”拖入视口

然后运行,可以看到我们此时视角就是“BP_PawnWithCamera”中Camera组件的视角了,但是我们现在还无法通过鼠标键盘去操控这个Pawn。

二、操控Pawn

1. 打开项目设置,添加操作映射和轴映射如下,完成输入绑定

2. 下面开始响应输入。在头文件中定义如下输入变量

定义如下输入函数

在源文件中实现输入函数

现在已经有了存储输入数据的函数,接着要告知引擎何时调用该代码。需要把Pawn的输入事件和函数相互绑定:

在Tick中处理视角缩放逻辑,当按下鼠标右键时按钮时进行放大,否则恢复正常。

继续编辑旋转逻辑

最后编辑移动逻辑如下

此时就完成了Pawn的前后左右移动、旋转视角、缩放视角的功能了。

完整代码如下:

PawnWithCamera.h

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "PawnWithCamera.generated.h"UCLASS()
class STUDY_API APawnWithCamera : public APawn
{GENERATED_BODY()public:// Sets default values for this pawn's propertiesAPawnWithCamera();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;// Called to bind functionality to inputvirtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;protected:void MoveForward(float AxisValue);void MoveRight(float AxisValue);void PitchCamera(float AxisValue);void YawCamera(float AxisValue);void ZoomIn();void ZoomOut();protected:UPROPERTY(EditAnywhere)class USpringArmComponent* SpringArmComp;UPROPERTY(EditAnywhere)class UCameraComponent* CameraComp;UPROPERTY(EditAnywhere)class UStaticMeshComponent* StaticMeshComp;FVector2D MovementInput;FVector2D CameraInput;float ZoomFactor = 1.0f;bool bZoomingIn = false;};

PawnWithCamera.cpp

// Fill out your copyright notice in the Description page of Project Settings.#include "GameCamera/PawnWithCamera.h"#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/StaticMeshComponent.h"// Sets default values
APawnWithCamera::APawnWithCamera()
{// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;//创建组件RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootSenceComponent"));StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComponent"));SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComponent"));CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));//绑定组件StaticMeshComp->SetupAttachment(RootComponent);SpringArmComp->SetupAttachment(StaticMeshComp);CameraComp->SetupAttachment(SpringArmComp, USpringArmComponent::SocketName);//设置SpringArmSpringArmComp->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, 50.0f), FRotator(-60.0f, 0.0f, 0.0f));SpringArmComp->TargetArmLength = 400.0f;SpringArmComp->bEnableCameraLag = true;SpringArmComp->CameraLagSpeed = 3.0f;//设置默认控制玩家为本PawnAutoPossessPlayer = EAutoReceiveInput::Player0;}// Called when the game starts or when spawned
void APawnWithCamera::BeginPlay()
{Super::BeginPlay();
}// Called every frame
void APawnWithCamera::Tick(float DeltaTime)
{Super::Tick(DeltaTime);{if (bZoomingIn){ZoomFactor += DeltaTime / 0.5f;}else{ZoomFactor -= DeltaTime / 0.25f;}ZoomFactor = FMath::Clamp<float>(ZoomFactor, 0.0f, 1.0f);//根据ZoomFactor来设置摄像机的时长和弹簧臂的长度CameraComp->FieldOfView = FMath::Lerp<float>(90.0f, 60.0f, ZoomFactor);SpringArmComp->TargetArmLength = FMath::Lerp<float>(400.0f, 300.0f, ZoomFactor);}//旋转Actor的偏转角度,这样摄像机也能旋转,因为摄像机与Actor相互绑定{FRotator NewRotation = GetActorRotation();NewRotation.Yaw += CameraInput.X;SetActorRotation(NewRotation);}//旋转摄像机的俯仰角度,但要对其进行限制,这样我们就能始终俯视Actor{FRotator NewRotation = SpringArmComp->GetComponentRotation();NewRotation.Pitch = FMath::Clamp(NewRotation.Pitch + CameraInput.Y, -80.0f, -15.0f);SpringArmComp->SetWorldRotation(NewRotation);}//基于“MoveX”和“MoveY”坐标轴来处理移动if (!MovementInput.IsZero()){//把移动轴的输入数值放大100倍MovementInput = MovementInput.GetSafeNormal() * 100.0f;FVector NewLocation = GetActorLocation();NewLocation += GetActorForwardVector() * MovementInput.X * DeltaTime;NewLocation += GetActorRightVector() * MovementInput.Y * DeltaTime;SetActorLocation(NewLocation);}
}// Called to bind functionality to input
void APawnWithCamera::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);//绑定“ZoomIn”的事件InputComponent->BindAction("ZoomIn", IE_Pressed, this, &APawnWithCamera::ZoomIn);InputComponent->BindAction("ZoomIn", IE_Released, this, &APawnWithCamera::ZoomOut);//为四条轴绑定事件(每帧调用)InputComponent->BindAxis("MoveForward", this, &APawnWithCamera::MoveForward);InputComponent->BindAxis("MoveRight", this, &APawnWithCamera::MoveRight);InputComponent->BindAxis("CameraPitch", this, &APawnWithCamera::PitchCamera);InputComponent->BindAxis("CameraYaw", this, &APawnWithCamera::YawCamera);}void APawnWithCamera::MoveForward(float AxisValue)
{MovementInput.X = FMath::Clamp<float>(AxisValue, -1.0f, 1.0f);
}void APawnWithCamera::MoveRight(float AxisValue)
{MovementInput.Y = FMath::Clamp<float>(AxisValue, -1.0f, 1.0f);
}void APawnWithCamera::PitchCamera(float AxisValue)
{CameraInput.Y = AxisValue;
}void APawnWithCamera::YawCamera(float AxisValue)
{CameraInput.X = AxisValue;
}void APawnWithCamera::ZoomIn()
{bZoomingIn = true;
}void APawnWithCamera::ZoomOut()
{bZoomingIn = false;
}

官方参考文档:

https://dev.epicgames.com/documentation/zh-cn/unreal-engine/quick-start-guide-to-player-controlled-cameras-in-unreal-engine-cpp?application_version=5.3


http://www.ppmy.cn/embedded/141651.html

相关文章

k8s1.30.0高可用集群部署

负载均衡 nginx负载均衡 两台nginx负载均衡 vim /etc/nginx/nginx.conf stream {upstream kube-apiserver {server 192.168.0.11:6443 max_fails3 fail_timeout30s;#server 192.168.0.12:6443 max_fails3 fail_timeout30s;#server 192.168.0.13:6443 max_fails3…

2024 java大厂面试复习总结(二)(持续更新)

10年java程序员&#xff0c;2024年正好35岁&#xff0c;2024年11月公司裁员&#xff0c;记录自己找工作时候复习的一些要点。 JVM 说一下 JVM 运行时数据区 程序计数器&#xff08;Program Counter Register&#xff09;&#xff1a;当前线程所执行的字节码的行号指示器&…

英语知识网站开发:Spring Boot框架应用

3系统分析 3.1可行性分析 通过对本英语知识应用网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本英语知识应用网站采用SSM框架&#xff0c;JAVA作为开发语…

.cc扩展名是什么语言?主流编程语言扩展名?C语言必须用.c为扩展名吗?为什么看到Windows好多系统文件名的扩展名不超过3字符?

.cc扩展名是什么语言? .cc是C语言使用的扩展名&#xff0c;一种说法是它是c with class的简写&#xff0c;当然C语言使用的扩展名不止.cc和.cpp, 还包含.cxx, .c, .C等&#xff0c;这些在不同编译器系统采用的默认设定不同&#xff0c;需要区分使用。当然&#xff0c;编译器提…

RabbitMQ高级特性:TTL、死信队列与延迟队列

RabbitMQ高级特性&#xff1a;TTL、死信队列与延迟队列 RabbitMQ作为一款开源的消息代理软件&#xff0c;广泛应用于分布式系统中&#xff0c;用于实现消息的异步传递和系统的解耦。其强大的高级特性&#xff0c;包括TTL&#xff08;Time-To-Live&#xff09;、死信队列&#…

数据库学习记录03

DML【数据操作语言】 DQL是对数据的查操作&#xff0c;DML就是操作&#xff1a;增、删、改。数据库的基础操作就是&#xff1a;增删改查&#xff08;CRUD); 1.插入&#xff08;增&#xff09; #语法1 insert into 表名(字段名1,...) values(值1,...);#语法2 insert into 表名(…

本地化部署 私有化大语言模型

本地化部署 私有化大语言模型 本地化部署 私有化大语言模型Anaconda 环境搭建运行 代码概述环境配置安装依赖CUDA 环境配置 系统设计与实现文件处理与加载文档索引构建模型加载与推理文件上传与索引更新实时对话与文档检索Gradio 前端设计 主要功能完整代码功能说明运行示例文件…

Docker安装ubuntu1604

首先pull镜像 sudo docker run -d -P m.daocloud.io/docker.io/library/ubuntu:16.04国内使用小技巧&#xff1a; https://github.com/DaoCloud/public-image-mirror pull完成之后查看 sudo docker images 运行docker sudo docker run -d -v /mnt/e:/mnt/e m.daocloud.io/…