Unreal

언리얼 엔진(Unreal Engine) 오브젝트 움직이기 C++

TIM_0529 2023. 1. 1. 18:00
반응형

언리얼 공식 문서에 있는 따라하기 컨텐츠를 정리하여 올린 글입니다.

 

프로젝트를 생성하고 처음으로 할 것은 인풋을 감지할 키를 정해줘야 합니다.

Edit > Project Settings 에 들어갑니다.

 

 

Setting > Input 을 눌러 Bindins 에서 필요한 키들을 등록해 줘야 합니다.

 

Action Mappings는 어떠한 동작을 바로 발동시키도록 실행하는 작업에 대한 키를 등록합니다.

 - Grow를 통해 스페이스바를 누르면 오브젝트에 크기가 커지도록 구현해 보겠습니다.

 - Dash를 통해 시프트 키를 누르면 오브젝트에 속도가 증가하도록 구현해 보겠습니다.

 

Action Mappins 는 지속적 폴링에 의해 값이 서서히 증가/증감 시킵니다.

 - MoveX를 통해 앞 , 뒤 이동을 구현해 보겠습니다.

 - MoveY를 통해 좌, 우 이동을 구현해 보겠습니다.

 

다음은 Content Browser에서 C++ Classes 파일 안에 있는 파일로 들어가서 우 클릭 후 C++ 클래스를 만들겠습니다.

 

폰을 상속 받은 클래스르 만들겠습니다.

폰이란 사람 플레이어 또는 AI 의 제어를 받을 것으로 디자인된 액터 클래스 입니다.

 

파을을 열고 헤더파일로 이동하겠습니다.

이동을 구현하기 전에 먼저 액터에 카메라를 먼저 추가하겠습니다.

	UPROPERTY(EditAnywhere)
	USceneComponent* OurVisibleComponent;

클래스에 가장 아래부분에 다음을 추가합니다.

USceneComponent는 위치와 회전과 같은 트랜스 정보를 갖고 있는 컴포넌트이면서 랜더링 및 충돌 계산이 없어서 가벼운 컴포넌트입니다.

다음은 CPP 파일로 이동하겠습니다.

생성자에서 다음 코드를 작성합니다.

	// 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;

	// 이 폰을 플레이어가 조종하도록 설정합니다.
	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(-700.f, 0.f, 400.f));
	OurCamera->SetRelativeRotation(FRotator(-40.f, 0.f, 0.f));

	OurVisibleComponent->SetupAttachment(RootComponent);

 

위치와 회전값은 제가 원하는 값으로 수정하였습니다.

 

다음은 이동을 구현하겠습니다. 헤더 파일로 이동합니다.


	void Move_XAxis(float AxisValue);// 앞, 뒤 이동
	void Move_YAxis(float AxisValue);// 좌, 우 이동
	void StartGrowing();// bGrowing 참으로 변경
	void StopGrowing();// bGrowing 거짓으로 변경
	void StartDash();// bDash 참으로 변경
	void StopDash();// bDash 거짓으로 변경

	FVector CurrentVelocity;// 입력함수
	bool bGrowing;// 크기 조정 여부
	bool bDash;// 대쉬 실행 여부

	UPROPERTY(EditAnywhere)
	float MaxSpeed;// 최대 스피드

	UPROPERTY(EditAnywhere)
	float Default_Speed;// 기본 스피드
	float Accel;// 가속도

클래스에 맨 아래에 위에 코드를 추가합니다.

 

다음은 CPP 파일로 이동합니다.

생성자에서 Accel 을 1로 초기화 합니다.

다음은 헤더파일에서 만든 함수들을 정의 합니다.

void AMyPawn::Move_XAxis(float AxisValue)
{
	CurrentVelocity.X = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f; //Clamp를 사용해 min 과 max 값을 정의합니다.
}

void AMyPawn::Move_YAxis(float AxisValue)
{
	CurrentVelocity.Y = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}

void AMyPawn::StartGrowing()
{
	bGrowing = true;
}

void AMyPawn::StopGrowing()
{
	bGrowing = false;
}

void AMyPawn::StartDash()
{
	bDash = true;
}

void AMyPawn::StopDash()
{
	bDash = false;
}

다음은 함수들을 입력 값에 따라 바인딩을 해 줄 차례입니다.

함수들이 반응할 시점을 알려줍니다.

void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) 함수로 이동합니다.

	// 커지기
	PlayerInputComponent->BindAction("Grow", IE_Pressed, this, &AMyPawn::StartGrowing);
	PlayerInputComponent->BindAction("Grow", IE_Released, this, &AMyPawn::StopGrowing);

	// 달리기
	PlayerInputComponent->BindAction("Dash", IE_Pressed, this, & AMyPawn::StartDash);
	PlayerInputComponent->BindAction("Dash", IE_Released, this, & AMyPawn::StopDash);

	// 앞 뒤  움직이기
	PlayerInputComponent->BindAxis("MoveX", this, &AMyPawn::Move_XAxis);
	PlayerInputComponent->BindAxis("MoveY", this, &AMyPawn::Move_YAxis);

커지기와 달리기는 눌렀을때와 땠을때 를 구별짓기 위해 Enum을 사용해서 누르면 0 때면 1 값을 전달합니다.

다음은 Tick() 함수로 이동합니다.

{
		float CurrentScale = OurVisibleComponent->GetComponentScale().X;	// 현재 위치값을 가져온다.
		if (bGrowing) // Grow 버튼이 눌리면 실행
		{
			CurrentScale += DeltaTime*1.5f;
		}
		else
		{
			CurrentScale -= DeltaTime * 1.2f;
		}
		CurrentScale = FMath::Clamp(CurrentScale, 1.f, 3.f);
		OurVisibleComponent->SetWorldScale3D(FVector(CurrentScale));
	}
	{
		if (bDash) // bDash 버튼이 눌리면 실행
		{
			Accel = (Accel < MaxSpeed) ? MaxSpeed : DeltaTime;		// MaxSpeed 로 지정한 값보다 작으면 DeltaTime을, 크다면 MaxSpeed 를 반환
		}
		else
		{
			Accel = 1; 
		}
	}
	{
		if (!CurrentVelocity.IsZero())		// 입력이 0이 아닐때
		{
			UPROPERTY(EditAnywhere)
			FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime* (Accel+Default_Speed)); // 오브젝트에 현재 위치에 값을 더하면서 이동
			SetActorLocation(NewLocation);
		}
	}

실행결과 정상적으로 움직입니다.

 

다음은 점프에 관련해서 정리해 보겠습니다.

 

 

반응형