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의 위치를 조절한다.

image
(UCameraComponent의 Details 패널)

image
(PIE 모드에서 카메라의 시점)


카메라 조작

키보드의 화살표키를 누르거나 마우스 커서를 화면 끝으로 이동하면 카메라가 이동하게 만들겠다. (Starcraft의 것 처럼)
키를 입력받고 폰을 움직이는 것은 어렵지 않으니 패스
mouse_input


완성된 코드

/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);
			}
		}
	}
}
⚠️ **GitHub.com Fallback** ⚠️