UE4 - 플레이어 입력 및 폰
햇갈릴 만한것 / 코드만 기재한다.
플레이어 입력 및 폰
Pawn 클래스를 확장하여 플레이어 입력에 반응시킵니다.
docs.unrealengine.com
순서대로 진행해본다.
1.폰 커스터마이즈
1. 폰 커스터마이즈
폰에 대한 소개입니다.
docs.unrealengine.com
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "MyPawn.generated.h"
UCLASS()
class MYSTUDY_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(EditAnywhere)
USceneComponent* OurVisibleComponent;
};
헤더 코드, SceneComponent*를 하나 추가한다.
USceneComponent는 Transform정보만을 지닌 가벼운 컴포넌트라고 한다.
동시에 어떤 컴포넌트던 대체해서 집어넣는게 가능한 듯 하다.
#include "MyPawn.h"
#include "Camera/CameraComponent.h"
// Sets default values
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;
// 이 폰을 0번 플레이어가 조종하도록 설정합니다
AutoPossessPlayer = EAutoReceiveInput::Player0;
// 무언가를 붙일 더미 루트 컴포넌트를 만듭니다
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
// 카메라와 보이는 오브젝트를 만듭니다
UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera"));
OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent"));
// 루트 컴포넌트에 카메라와 보이는 오브젝트를 붙입니다. 카메라를 이격 및 회전시킵니다.
OurCamera->SetupAttachment(RootComponent);
OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f));
OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f));
OurVisibleComponent->SetupAttachment(RootComponent);
}
CPP코드의 앞부분, 언리얼 4.26.2 버전에서는
카메라 컴포넌트를 쓰기위해선 #include "Camera/CameraComponent.h"로
선언 해주어야 한다.
언리얼에서는 필요한 객체들을 우선 더미로 생성한 후, 안에 대상을 세팅하는 식으로 진행한다.
즉 CPP코드에 생성되어있는 객체들은, New 선언만 해준 상태라고 볼 수 있다.
가령 StaticMesh같이 리소스가 존재하는 객체라고해도 생성과 동시에 바로 연결 시키는것은 안되고,
생성을 일단 한 후 대상 객체를 연결시키는 식으로 진행한다.
(혹은 기능이 있는데 내가 모르는것일수도 있다. 일단 현재까지 공부한 내용상 그렇다.)
아래는 카메라의 기본 세팅이다.
RootComponent는 액터의 Transform정도라고 생각 할 수 있다.
(SceneComponent가 Transform정도만 들고있고, RootComponent는 액터의 최상위에 배치되기 때문에)
2.게임입력 환경설정
2. 게임 입력 환경설정
언리얼 엔진에서 입력 환경설정 입니다.
docs.unrealengine.com
3. 게임 액션 프로그래밍 및 바인딩
C++ 코드에 입력을 바인딩합니다.
docs.unrealengine.com
FMath::Clamp는 값의 최소치와 최대치를 정해놓는 코드이다.
축 매핑은, 실시간으로 입력을 받으나
액션 매핑은 한번만 호출된다.
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "MyPawn.generated.h"
UCLASS()
class MYSTUDY_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;
//입력 함수
void Move_XAxis(float AxisValue);
void Move_YAxis(float AxisValue);
void StartGrowing();
void StopGrowing();
//입력 함수
FVector CurrentVelocity;
bool bGrowing;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY(EditAnywhere)
USceneComponent* OurVisibleComponent;
};
헤더부분, 입력 대응함수와 보여주기위한 SceneComponent 세팅.(Static Mesh 용)
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyPawn.h"
#include "Camera/CameraComponent.h"
// Sets default values
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;
// 이 폰을 0번 플레이어가 조종하도록 설정합니다
AutoPossessPlayer = EAutoReceiveInput::Player0;
// 무언가를 붙일 더미 루트 컴포넌트를 만듭니다
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
// 카메라와 보이는 오브젝트를 만듭니다
UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera"));
OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent"));
// 루트 컴포넌트에 카메라와 보이는 오브젝트를 붙입니다. 카메라를 이격 및 회전시킵니다.
OurCamera->SetupAttachment(RootComponent);
OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f));
OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f));
OurVisibleComponent->SetupAttachment(RootComponent);
}
// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// "Grow" 액션에 따라 키우고 줄이는 것을 처리합니다
{
float CurrentScale = OurVisibleComponent->GetComponentScale().X;
if (bGrowing)
{
// 1 초에 걸쳐 두 배 크기로 키웁니다
CurrentScale += DeltaTime;
}
else
{
// 키운 속도대로 절반으로 줄입니다
CurrentScale -= (DeltaTime * 0.5f);
}
// 시작 크기 아래로 줄이거나 두 배 이상으로 키우지 않도록 합니다.
CurrentScale = FMath::Clamp(CurrentScale, 1.0f, 2.0f);
OurVisibleComponent->SetWorldScale3D(FVector(CurrentScale));
}
// "MoveX" 와 "MoveY" 축에 따라 이동을 처리합니다
{
if (!CurrentVelocity.IsZero())
{
FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
SetActorLocation(NewLocation);
}
}
}
// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
//함수 포인터
// "Grow" 키를 누르거나 뗄 때 반응합니다
InputComponent->BindAction("Grow", IE_Pressed, this, &AMyPawn::StartGrowing);
InputComponent->BindAction("Grow", IE_Released, this, &AMyPawn::StopGrowing);
// "MoveX" 와 "MoveY" 두 이동 충의 값에 매 프레임 반응합니다
InputComponent->BindAxis("MoveX", this, &AMyPawn::Move_XAxis);
InputComponent->BindAxis("MoveY", this, &AMyPawn::Move_YAxis);
}
void AMyPawn::Move_XAxis(float AxisValue)
{
// 초당 100 유닛을 앞 또는 뒤로 움직입니다
CurrentVelocity.X = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}
void AMyPawn::Move_YAxis(float AxisValue)
{
// 초당 100 유닛을 오른쪽 또는 왼쪽으로 움직입니다
CurrentVelocity.Y = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}
void AMyPawn::StartGrowing()
{
bGrowing = true;
}
void AMyPawn::StopGrowing()
{
bGrowing = false;
}
Cpp파일. 적용시 wasd로 움직이며, 스페이스바를 누르면 점점 커지는 객체가 만들어진다.
이러한 점 때문에 보통 UCharacterComponent를 상속 받아서 주인공을 만든다.