# HowTo_PlayerCamera **Repository Path**: wblong/how-to_-player-camera ## Basic Information - **Project Name**: HowTo_PlayerCamera - **Description**: 学会使用玩家输入同时操控摄像机和Pawn。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-07-30 - **Last Updated**: 2021-10-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: Cpp, UE4 ## README # Player-Controlled Cameras 学会使用玩家输入同时操控摄像机和Pawn。 ## 创建相机 创建一个 SpringArmComponent,并在末端绑定一个 CameraComponent。弹簧臂是一种绑定摄像机(或其它 组件 )的简单方式,能让摄像机跟随拍摄对象时平稳自然。 ```cpp UPROPERTY(EditAnywhere) class USpringArmComponent* SpringArmComp; UPROPERTY(EditAnywhere) class UCameraComponent* CameraComp; UPROPERTY(EditAnywhere) UStaticMeshComponent* StaticMeshComp; ``` ```cpp #include "GameFramework/SpringArmComponent.h" #include "Camera/Component.h" //创建组件 RootComponent = CreateDefaultSubobject(TEXT("RootSceneComponent")); StaticMeshComp = CreateDefaultSubobject (TEXT("StaticMeshComponent")); SpringArmComp = CreateDefaultSubobject(TEXT("SpringArmComponent")); CameraComp = CreateDefaultSubobject(TEXT("CameraComponent")); //绑定组件 StaticMeshComp->SetupAttachment(RootComponent); SpringArmComp->SetupAttachment(StaticMeshComp); CameraComp->SetupAttachment(SpringArmComp,USpringArmComponent::SocketName); //为SpringArm类的变量赋值。 SpringArmComp->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, 50.0f), FRotator(-60.0f, 0.0f, 0.0f)); SpringArmComp->TargetArmLength = 400.f; SpringArmComp->bEnableCameraLag = true; SpringArmComp->CameraLagSpeed = 3.0f; ``` ## 配置输入及处理输入 创建函数来跟踪输入。 ```cpp //输入变量 FVector2D MovementInput; FVector2D CameraInput; float ZoomFactor; bool bZoomingIn; // 输入函数 void MoveForward(float AxisValue); void MoveRight(float AxisValue); void PitchCamera(float AxisValue); void YawCamera(float AxisValue); void ZoomIn(); void ZoomOut(); ``` ```cpp // 输入函数 void APawnWithCamera::MoveForward(float AxisValue) { MovementInput.X = FMath::Clamp(AxisValue, -1.0f, 1.0f); } void APawnWithCamera::MoveRight(float AxisValue) { MovementInput.Y = FMath::Clamp(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; } ``` 把Pawn的输入事件和函数相绑定。 ```cpp // 绑定"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); ``` 使用 Tick 函数中的这些值来每帧更新 Pawn 和 Camera。 ```cpp void APawnWithCamera::Tick(float DeltaTime) { Super::Tick(DeltaTime); //如果按下了放大按钮则放大,否则就缩小 { if (bZoomingIn) { ZoomFactor += DeltaTime / 0.5f; //Zoom in over half a second } else { ZoomFactor -= DeltaTime / 0.25f; //Zoom out over a quarter of a second } ZoomFactor = FMath::Clamp(ZoomFactor, 0.0f, 1.0f); //根据ZoomFactor来设置摄像机的视场和弹簧臂的长度 CameraComp->FieldOfView = FMath::Lerp(90.0f, 60.0f, ZoomFactor); SpringArmComp->TargetArmLength = FMath::Lerp(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); } } } ``` ## Result ![HowToPlayerCamera](./Images/HowToPlayCamera.png) ## Reference 1. [PlayerCamera - https://docs.unrealengine.com/4.26/zh-CN/ProgrammingAndScripting/ProgrammingWithCPP/CPPTutorials/PlayerCamera/](https://docs.unrealengine.com/4.26/zh-CN/ProgrammingAndScripting/ProgrammingWithCPP/CPPTutorials/PlayerCamera/)