프로그래밍 / C++ / 언리얼

Programming/C | C++ | Unreal

[언리얼 엔진] PlayerInput, BindAxis 움직임 구현

아트성 2022. 2. 27. 13:18

tank.h 

#pragma once

#include "CoreMinimal.h"
#include "Tank.generated.h"

UCLASS()
class TOONTANKS_API ATank : public ABasePawn
{
	GENERATED_BODY()

public:
	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	// Called every frame
	virtual void Tick(float DeltaTime) override;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

private:	

	UPROPERTY(EditAnywhere, Category = "Movement")
	float Speed = 200.f;
   	UPROPERTY(EditAnywhere, Category = "Movement")
	float TurnRate = 45.f;
    
   	void Move(float Value);
	void Turn(float value);
    
};

UPROPERTYSppedTurnRate를 변수를 설정해주면 언리얼 디테일창에 Movement카테고리에 위와같이 설정이 된다.

 

그외에 public에 SetupPlayerInputComponent 함수를 선언그리고 private에 Move와 Turn을 선언한다.

 

 

 

 

 

 

 

 

tnak.cpp

Edit - Project Settings - Engine - Input 창으로 들어가서 

각 상황에 맞는 키를 설정해준다.

 

 

 

추가할 헤더파일

#include "Components/InputComponent.h"
#include "Kismet/GameplayStatics.h"

 

함수세팅

// 액터 전진(↑↓)
void ATank::Move(float Value) 
{
	FVector DeltaLocation = FVector::ZeroVector;
	// X = Value * DeltaTime * Speed
	DeltaLocation.X = Value * Speed * UGameplayStatics::GetWorldDeltaSeconds(this);
	AddActorLocalOffset(DeltaLocation, true); // true로 설정하면 물체끼리 충돌할때 멈추게할수있음, 주의할점 : 바닥과 액터가 겹치면 액터가 안움직일수있음!
}

// 액터 회전(←→)
void ATank::Turn(float Value)
{
	FRotator DeltaRotation = FRotator::ZeroRotator;
	// Yaw = Value * DeltaTime * TurnRate
	DeltaRotation.Yaw = Value * TurnRate * UGameplayStatics::GetWorldDeltaSeconds(this);
	AddActorLocalRotation(DeltaRotation, true);

FVector : 액터의 현재 위치정보를 저장한다. // ZeroVector = (0.f, 0.f, 0.f)

FRotator : 각 회전축을 기준으로 플레이어의 회전각을 저장한다. roll, pitch, yaw 순서이다.

 

UGameplayStatics 클래스는 특수효과, 데미지설정, 오디오 기능들을 다양하게 설정하도록 도와준다.  다른 클래스와 달리 어느 한쪽에 국한되어있는게아니라는게 특징, 게임 플레이를 위한 필요한 요소들을 멤버함수로 가지고있어서 알아두면 정말 편리하다.

 

UGameplayStatics::GetWorldDeltaSeconds : 월드내 프레임 사이의 시간을 호출 (10ms -> 0.01반환)

(Kismet/GameplayStatics.h 을 선언해주어야한다.) 컴퓨터가 느려지거나 사양에따라서 각 플레이어마다 프레임이 달라 프레임변동이 생길수있는데 이때 플레이어의 동작들을 최대한 동기화시키기위해 쓴다고한다.. 

 

AActor::AddActorLocalOffset / AActor::AddActorLocalRotation : 설정한 값만큼 액터가 움직이도록 설정한다. 여기서 bsweep값을 true로하면 물체끼리 충돌할때 멈추게 설정된다. 그 외에 HitResult랑 Teleport는 자주 쓰이지 않으므로 로케이션과 스윕만 설정해준다.


void AddActorLocalOffset
(
     FVector DeltaLocation, // 설정한 값만큼 위치 변경.
     bool bSweep, // true : 무언가에 의해 막히면 멈춤
     FHitResult * OutSweepHitResult,
     ETeleportType Teleport
)

void void AddActorRotation
(
     FRotator DeltaRotation, // 설정한 값만큼 위치 변경.
     bool bSweep, // true : 무언가에 의해 막히면 멈춤
     FHitResult * OutSweepHitResult,
     ETeleportType Teleport
)

 

함수대입

void ATank::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) // 매개변수는 사용자가 입력한 key (w,a,s,d등)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	PlayerInputComponent->BindAxis(TEXT("MoveForward"), this, &ATank::Move); // 입력시 전후진
	PlayerInputComponent->BindAxis(TEXT("Turn"), this, &ATank::Turn); // 입력시 회전
}

 

UInputComponent : 사용자가 입력한 키값을 바인딩 처리해주는 역할을 하는 클래스이다. 멤버함수들은 일시적으로 스택에 남아있다가 호출이 끝나면 사라지는것들로 구성되어있다. (Components/InputComponent.h 을 선언해주어야한다.)

 

BindAxis : UInputComponent의 멤버함수로 플레이어가 키를입력하면 이벤트가 발생하고 그 즉시, 키값을 바인딩함. 키 값이 처리되면 스택에서 즉시 처리가 된다. 인스턴스가 포인터역할로써 호출될 수 있다. 

 

 - 플레이어가 w,s를 입력하면 이벤트가 발생해 Move함수가 호출되고, a,d 를 누르면 Turn함수가 호출된다.

 - move는 AddActorLocalOffset /  Turn은 AddActorLocalRotation 각각 함수가 호출된다.

 - 캐릭터가 전진 또는 회전을 진행한다.

 

 

반응형