본문 바로가기

Unreal 공부

4일차 (Unreal Document 튜토리얼 따라하기 1)

따라할 튜토리얼
https://docs.unrealengine.com/ko/Programming/Tutorials/index.html

 

C++ 프로그래밍 튜토리얼

언리얼 엔진 프로그래밍에 대한 실전 학습용 단계별 안내서입니다.

docs.unrealengine.com

게임 조종 카메라

기존 게임 조종 카메라 튜토리얼에서는 아래와 같이 Camera를 셋팅한다. 

UPROPERTY(EditAnywhere)
AActor* CameraOne;

UPROPERTY(EditAnywhere)
AActor* CameraTwo;

기존 카메라 셋팅

이 튜토리얼의 마지막에는 직접 해보기라는 항목이 있었다.
나는 여기서 2번째인 "하나의 배열 변수를 사용하여 카메라를 저장하면, CameraOne & CameraTwo를 사용했을 때와는 달리 카메라가 몇 개든 순서대로 변경하여 사용할 수 있습니다."를 보고 이것을 해보기로 했다.

 

직접 해보기 항목

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CameraDirector.generated.h"

UCLASS()
class FIRSTPROJECT_API ACameraDirector : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ACameraDirector();

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

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

	// 카메라들이 저장될 배열
	UPROPERTY(EditAnywhere)
	TArray<AActor*> Cameras;

	// 현재 카메라의 Number(즉, 배열에서 몇 번째에 해당하는 카메라인가)
	UPROPERTY(EditAnywhere)
	int32 CurrentCameraNumber;

private:
	// PlayerController는 구현부에서 계속 쓸 거라서 멤버로 해둠
    // 기존엔 구현부의 Tick()에서 계속 불러왔음
	APlayerController* OnPlayerController;
    
    // 다음 카메라로 전환할 시간(즉, 카메라 전환 쿨타임? 정도로 이해하면 될듯함)
	float TimeToNextCameraChange;

};

< 헤더(.h) 파일 >

// Fill out your copyright notice in the Description page of Project Settings.


#include "CameraDirector.h"
#include "Kismet/GameplayStatics.h"

// Sets default values
ACameraDirector::ACameraDirector()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CurrentCameraNumber = 0;
}

// Called when the game starts or when spawned
void ACameraDirector::BeginPlay()
{
	Super::BeginPlay();
	
	OnPlayerController = UGameplayStatics::GetPlayerController(this, 0);
	OnPlayerController->SetViewTarget(Cameras[CurrentCameraNumber]);
}

// Called every frame
void ACameraDirector::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (Cameras.Num() == 0)
		return;

	const float TimeBetweenaCameraChanges = 2.0f;
	const float SmoothBlendTime = 0.75f;
	TimeToNextCameraChange -= DeltaTime;

	if (TimeToNextCameraChange <= 0.0f)
	{
		TimeToNextCameraChange += TimeBetweenaCameraChanges;

		if (OnPlayerController)
		{
			int32 NextCameraNumber = (CurrentCameraNumber + 1) % Cameras.Num();
			if ((OnPlayerController->GetViewTarget() != Cameras[NextCameraNumber]) && (Cameras[NextCameraNumber] != nullptr))
			{
				OnPlayerController->SetViewTarget(Cameras[NextCameraNumber]);
				CurrentCameraNumber = NextCameraNumber;
			}
		}
	}
}

< 구현부(.cpp) 파일 >

오늘 하면서 알게된 점

TArray를 "Battery Collector"튜토리얼에서 봐서 배열은 TArray로 만드는 구나라고 알 수 있었다.
하지만 아직 Unreal Document를 보는게 미숙하다보니 TArray의 element가 몇 개인지를 가져올 수 있는 방법을 잘 몰랐다. 
그래서 기존에 하던 대로 .size()를 쳐보았더니 뜨길래 이걸 쓰면 되겠구나! 라고 생각했지만 이것이 아니어서 계속 에러가 났다.

처음 ) 이거겠지! 어..? 안되네?

그래서 구글에 검색을 하고  문서도 찾아본 끝에 Element 개수를 가지고 오는 것은 "배열이름.Num()"이라는 것을 알게 되었다.
(아래의 이미지를 클릭하면 해당 문서로 연결되니까 필요한 분은 보시길!)

이거였구나!!
(GIF인데 계속 첫 장면에서 재생이 안되서 제대로 재생이 되는 것을 보려면 한 번 이미지를 클릭해서 봐야함) 카메라를 2개에서 4개로 증가시켜보았다! 이제 Array이고 디테일 창에서 배열의 Element를 수정할 수 있으니까 몇개든 추가적인 컴파일 없이 더 추가할 수 있다! 야호!