02. 플레이어 카메라 - Elysia-ff/UE4-Custom_Stencil_Tutorial GitHub Wiki
이제 Top-Down Camera를 만들 차례다.
APawn
을 상속받는 AStealthPlayerCamera
를 생성하고 UCameraComponent
를 추가한 다음, Blueprint BP_PlayerCamera
를 만들어서 DefaultPawn으로 등록한다.
그 다음 카메라의 Projection Mode를 Orthographic으로 변경하고 카메라의 방향, Ortho Width와 Level에서 Player Start의 위치를 조절한다.
(UCameraComponent
의 Details 패널)
(PIE 모드에서 카메라의 시점)
키보드의 화살표키를 누르거나 마우스 커서를 화면 끝으로 이동하면 카메라가 이동하게 만들겠다. (Starcraft의 것 처럼)
키를 입력받고 폰을 움직이는 것은 어렵지 않으니 패스
/Player/StealthPlayerCamera.h
// Copyright 2021. Elysia-ff
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "StealthPlayerCamera.generated.h"
class UCameraComponent;
UCLASS()
class STEALTHTUTORIAL_API AStealthPlayerCamera : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AStealthPlayerCamera(const FObjectInitializer& ObjectInitializer);
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
void AddMoveInput(const FVector2D& Value);
private:
void MoveForward(float AxisValue);
void MoveRight(float AxisValue);
public:
UPROPERTY(VisibleAnywhere, Category = "Camera")
UCameraComponent* CameraComponent;
UPROPERTY(EditAnywhere, Category = "Camera")
float EdgePixel;
UPROPERTY(EditAnywhere, Category = "Movement")
float MoveSpeed;
private:
FVector2D MoveInput;
};
/Player/StealthPlayerCamera.cpp
// Copyright 2021. Elysia-ff
#include "Player/StealthPlayerCamera.h"
#include <Engine/Classes/Camera/CameraComponent.h>
// Sets default values
AStealthPlayerCamera::AStealthPlayerCamera(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
// 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("RootComponent"));
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
CameraComponent->SetupAttachment(RootComponent);
}
// Called every frame
void AStealthPlayerCamera::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!MoveInput.IsZero())
{
FVector NewLocation = GetActorLocation();
NewLocation.X += MoveInput.X * MoveSpeed * DeltaTime;
NewLocation.Y += MoveInput.Y * MoveSpeed * DeltaTime;
SetActorLocation(NewLocation);
}
}
// Called to bind functionality to input
void AStealthPlayerCamera::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &AStealthPlayerCamera::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AStealthPlayerCamera::MoveRight);
}
void AStealthPlayerCamera::AddMoveInput(const FVector2D& Value)
{
MoveInput.X = FMath::Clamp(MoveInput.X + Value.X, -1.0f, 1.0f);
MoveInput.Y = FMath::Clamp(MoveInput.Y + Value.Y, -1.0f, 1.0f);
}
void AStealthPlayerCamera::MoveForward(float AxisValue)
{
MoveInput.X = FMath::Clamp(AxisValue, -1.0f, 1.0f);
}
void AStealthPlayerCamera::MoveRight(float AxisValue)
{
MoveInput.Y = FMath::Clamp(AxisValue, -1.0f, 1.0f);
}
/Player/StealthPlayerController.h
// Copyright 2021. Elysia-ff
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "StealthPlayerController.generated.h"
/**
*
*/
UCLASS()
class STEALTHTUTORIAL_API AStealthPlayerController : public APlayerController
{
GENERATED_BODY()
public:
AStealthPlayerController(const FObjectInitializer& ObjectInitializer);
virtual void PlayerTick(float DeltaTime) override;
};
/Player/StealthPlayerController.cpp
// Copyright 2021. Elysia-ff
#include "StealthPlayerController.h"
#include "Player/StealthPlayerCamera.h"
AStealthPlayerController::AStealthPlayerController(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
PrimaryActorTick.bCanEverTick = true;
bShowMouseCursor = true;
}
void AStealthPlayerController::PlayerTick(float DeltaTime)
{
Super::PlayerTick(DeltaTime);
AStealthPlayerCamera* PossessedPawn = GetPawn<AStealthPlayerCamera>();
if (PossessedPawn != nullptr && GEngine != nullptr)
{
FVector2D MouseInput;
if (GetMousePosition(MouseInput.X, MouseInput.Y))
{
FVector2D MoveInput;
const FIntPoint ViewportSize = GEngine->GameViewport->Viewport->GetSizeXY();
if (MouseInput.X <= PossessedPawn->EdgePixel)
{
MoveInput.Y = -1.0f;
}
else if (MouseInput.X >= ViewportSize.X - PossessedPawn->EdgePixel)
{
MoveInput.Y = 1.0f;
}
if (MouseInput.Y <= PossessedPawn->EdgePixel)
{
MoveInput.X = 1.0f;
}
else if (MouseInput.Y >= ViewportSize.Y - PossessedPawn->EdgePixel)
{
MoveInput.X = -1.0f;
}
if (!MoveInput.IsZero())
{
PossessedPawn->AddMoveInput(MoveInput);
}
}
}
}