1. 初始化相机
1.1 创建组件
- 在
AMyGameMode
设置的APawn
中,创建相机:
UCLASS()
class TESTPROJECT01_API AMyPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AMyPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "MySceneComponent")
USceneComponent* m_pRootScene;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "MySceneComponent")
USpringArmComponent* m_pSpringArm;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "MySceneComponent")
UCameraComponent* m_pCamera;
};
1.2 初始化组件
AMyPawn::AMyPawn()
{
// 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;
// create
this->m_pRootScene = CreateDefaultSubobject<USceneComponent>(TEXT("MyRootScene"));
this->m_pSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("MySpringArm"));
this->m_pCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MyCamera"));
// setting
RootComponent = this->m_pRootScene;
this->m_pSpringArm->SetupAttachment(this->m_pRootScene);
this->m_pCamera->SetupAttachment(this->m_pSpringArm);
// 关闭碰撞检测
this->m_pSpringArm->bDoCollisionTest = false;
}
Tips: 这里相机的父类必须设置为机械臂,否则后续无法使用控制器修改相机的位姿。
1.3 设置初始位置
// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
Super::BeginPlay();
FVector initLoc = FVector(0.0, 0.0, 100.0);
FRotator initRot = FRotator(-50.0, 0.0, 0.0);
FVector initScale = FVector(1.0, 1.0, 1.0);
SetActorLocation(initLoc);
SetActorRotation(initRot);
SetActorScale3D(initScale);
}
2. 给相机绑定事件
2.1 实现控制Pawn的函数
/// <summary>
/// 鼠标滑轮移动镜头缩放
/// </summary>
/// <param name="fZoomSpeed">移动速率,正方向朝far。</param>
void ChangeArmLength(double fZoomSpeed);
static double ClampArmLength(double value, double lVal, double rVal)
{
double res = value < lVal ? lVal : value;
res = res > rVal ? rVal : res;
return res;
}
void AMyPawn::ChangeArmLength(double fZoomSpeed)
{
double dNear = 300.0;
double dFar = 5000.0;
this->m_pSpringArm->TargetArmLength += fZoomSpeed;
// 限制距离
this->m_pSpringArm->TargetArmLength = ClampArmLength(this->m_pSpringArm->TargetArmLength, dNear, dFar);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("argetArmLength: %f"), this->m_pSpringArm->TargetArmLength));
}
2.2 创建事件映射
2.3 绑定事件
- 头文件:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MyPlayerController.generated.h"
UCLASS()
class TESTPROJECT01_API AMyPlayerController : public APlayerController
{
GENERATED_BODY()
public:
virtual void SetupInputComponent();
void PressKeyQ();
void PressKeyE();
};
- 将事件与控制器中的两个回调函数进行绑定:
#include "MyPawn.h"
#include "MyPlayerController.h"
void AMyPlayerController::SetupInputComponent()
{
// 必须
Super::SetupInputComponent();
InputComponent->BindAction("KEY_Q", IE_Repeat, this, &AMyPlayerController::PressKeyQ);
InputComponent->BindAction("KEY_E", IE_Repeat, this, &AMyPlayerController::PressKeyE);
}
输入事件类型 | 含 义 |
---|---|
EInputEvent::IE_Pressed | 这个事件发生于输入(如按键或按钮)被按下的时刻。 |
IEInputEvent::E_Released | 这个事件发生于输入被释放的时刻。通常是指用户松开了按键或按钮。 |
EInputEvent::IE_Repeat | 当输入(如键盘按键)被长按并重复触发时,会发生此事件。这类似于在文本编辑器中长按键盘按键时,字符会连续输入。 |
EInputEvent::IE_DoubleClick | 当输入设备(如鼠标)快速连续点击两次时触发的事件。 |
EInputEvent::IE_Axis | 这个事件与模拟输入或轴输入有关,例如游戏手柄的摇杆或鼠标移动。 |
EInputEvent::IE_MAX | 这通常用作枚举的边界标识,表示枚举值的数量,不用于表示实际的输入事件。 |
- 实现回调函数:
void AMyPlayerController::PressKeyQ()
{
if (GetPawn())
{
AMyPawn* pCameraPawn = Cast<AMyPawn>(GetPawn());
if (pCameraPawn)
{
pCameraPawn->ChangeArmLength(10);
}
}
}
void AMyPlayerController::PressKeyE()
{
if (GetPawn())
{
AMyPawn* pCameraPawn = Cast<AMyPawn>(GetPawn());
if (pCameraPawn)
{
pCameraPawn->ChangeArmLength(-10);
}
}
}