描述
- 相机朝下看,高度可调,小蚂蚁头顶上
- 场景中动态生成车子,结合感知消息显示车子
相机朝下看的空场景
开始
创建一个带初学者内容的空项目
相机朝下看
思路来源:
https://docs.unrealengine.com/4.26/zh-CN/ProgrammingAndScripting/ProgrammingWithCPP/CPPTutorials/PlayerCamera/
// 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 HOWTO_PLAYERCAMERA_API APawnWithCamera : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
APawnWithCamera();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
protected:
UPROPERTY(EditAnywhere,Category="my_mesh")
class USpringArmComponent* SpringArmComp;
UPROPERTY(EditAnywhere, Category = "my_mesh")
class UCameraComponent* CameraComp;
UPROPERTY(EditAnywhere, Category = "my_mesh")
UStaticMeshComponent* StaticMeshComp;
UPROPERTY(EditAnywhere, Category = "my_mesh")
UStaticMeshComponent* cnm;
//输入变量
FVector2D MovementInput;
FVector2D CameraInput;
float ZoomFactor;
bool bZoomingIn;
float one_second_move_x = 1000;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// 输入函数
void MoveForward(float AxisValue);
void MoveRight(float AxisValue);
void PitchCamera(float AxisValue);
void YawCamera(float AxisValue);
void ZoomIn();
void ZoomOut();
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "PawnWithCamera.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.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("RootSceneComponent"));
StaticMeshComp = CreateDefaultSubobject <UStaticMeshComponent>(TEXT("StaticMeshComponent"));
cnm = CreateDefaultSubobject <UStaticMeshComponent>(TEXT("cnm"));
SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComponent"));
CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
//绑定组件
StaticMeshComp->SetupAttachment(RootComponent);
cnm->SetupAttachment(RootComponent);
SpringArmComp->SetupAttachment(StaticMeshComp);
CameraComp->SetupAttachment(SpringArmComp, USpringArmComponent::SocketName);
//为SpringArm类的变量赋值。
SpringArmComp->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, 200.0f), FRotator(-90.0f, 0.0f, 0.0f));
SpringArmComp->TargetArmLength = 400.f;
SpringArmComp->bEnableCameraLag = true;
SpringArmComp->CameraLagSpeed = 3.0f;
//控制默认玩家
AutoPossessPlayer = 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);
// 绑定"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);
//如果按下了放大按钮则放大,否则就缩小
{
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<float>(ZoomFactor, 0.0f, 1.0f);
//根据ZoomFactor来设置摄像机的视场和弹簧臂的长度
CameraComp->FieldOfView = FMath::Lerp<float>(90.0f, 60.0f, ZoomFactor);
SpringArmComp->TargetArmLength = FMath::Lerp<float>(2000.0f, 1000.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);
}
}
//自己走
{
float one_frame_move_x = one_second_move_x / (1 / DeltaTime);
FVector NewLocation = GetActorLocation();
NewLocation.Y += one_frame_move_x/10;
//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);
}
// 输入函数
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;
}
添加一辆车子
h
UStaticMeshComponent* one_car;
cpp
构造函数
//
one_car = CreateDefaultSubobject <UStaticMeshComponent>(TEXT("one_car"));
one_car->SetupAttachment(RootComponent);
static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/StarterContent/Architecture/Wall_Door_400x400.Wall_Door_400x400"));
one_car->SetStaticMesh(CubeVisualAsset.Object);
one_car->SetWorldLocation(FVector(0.0f, 0.0f, 0.0f));
tick函数
one_car->SetWorldLocation(FVector(0.0f, 0.0f, 0.0f));
one_car->SetVisibility(false);
添加一堆车子
h
声明
vector<UStaticMeshComponent*> multi_car;
cpp
构造
for (int i = 0; i < 10; i++)
{
UStaticMeshComponent* tmp;
FString tmp_str = FString::FromInt(i);
FName tmp_name = FName(tmp_str);
tmp = CreateDefaultSubobject <UStaticMeshComponent>(tmp_name);
tmp->SetupAttachment(RootComponent);
tmp->SetStaticMesh(CubeVisualAsset.Object);
float tmp_p = i * 100;
tmp->SetWorldLocation(FVector(tmp_p, tmp_p, 0.0f));
multi_car.push_back(tmp);
}
tick
for (int i = 0; i < 10; i++)
{
float tmp_p = i * 100;
tmp_p = FMath::Sin(tmp_p/90) * tmp_p;
multi_car[i]->SetWorldLocation(FVector(tmp_p, tmp_p, 0.0f));
//float one_frame_move_x = one_second_move_x / (1 / DeltaTime);
//FVector NewLocation = multi_car[i]->world;
//NewLocation.Y += one_frame_move_x/10;
NewLocation += GetActorForwardVector() * MovementInput.X * DeltaTime;
NewLocation += GetActorRightVector() * MovementInput.Y * DeltaTime;
//SetActorLocation(NewLocation);
}