공부 이야기/대학교

[컴애니] 05 액터 클래스, 로그 출력, 스크린 메시지 출력

개구리밥 2021. 3. 15. 12:30
728x90

컴퓨터 애니메이션 2주차 3차시 실습. 액터 클래스, 로그 출력, 스크린 메시지 출력


05a 액터 클래스

액터 : 레벨에 배치할 수 있는 오브젝트 
docs.unrealengine.com/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Actors/index.html

얼리얼 엔진에서 액터 라고 하는 것은 게임에 등장해서 게임에 영향을 미칠 수 있는 모든 것을 말한다.
게임의 몬스터, npc, 떠다니는 물체 등등.

액터를 만든 방법은 여러 방법이 있을 수 있지만, 수업에서 알려준 방법은 콘텐츠 브라우저 안에 있는 C++클래스 폴더를 선택한 후 추가/임포트에서 New C++ Class, Actor 선택. 이름 변경 가능.

C++로 만든다
액터 선택

액터와 같이 생성된 C++ 코드에는 생성자, BeginPlay, Tick 이 있다.

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


#include "MyActor.h"

// Sets default values
AMyActor::AMyActor()
{
 	// 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;

}

// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
	Super::BeginPlay();
	
}

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

}

BeginePlay 함수는 게임을 시작했을 때, 또는 액터가 나타났을 때 최초 한번 호출되는 함수이다.
초기화에 필요한 것들을 정의하는 장소로 쓴다.

Tick 함수는 매 프레임마다 호출되는 함수로, 지속적으로 변경되는 것들을 작성하는 장소이다.
Tick의 DeltaTime은 프레임이 변경된 이후의 시간에 대한 정보이다.
Tick이 반복적으로 호출될 때, 직전의 Tick함수가 호출된 시간을 측정하고 있다가 그 다음에 Tick 함수가 호출될 때 그 사이에 흘러간 시간을 파라미터로 넘겨준다.
30프레임짜리 게임이면 1/30초.


엑터는 드래그 드랍으로 게임 화면에 추가할 수 있다..
아직 형태가 없어서 보이는 형태는 없지만 우측의 월드 아웃라이너에서 목록으로 확인할 수 있음.


아웃라이너에 있는 플레이어 스타트는 게임을 시작했을 때 플레이어의 시작 위치를 정하는 것이다.

 


게임 실행 후 빠르게 빠져나오는 키는 ESC


05b 로그 출력

화면에 무언가를 출력해보자. 특히 디버그용으로 출력하기 위해서 정보 출력이 필요함.
표준 입출력이 없다. 전용 함수를 사용해서 출력.
UE4 Wiki에 상세한 내용이 적혀 있다.

https://www.ue4community.wiki/logging-lgpidy6i

 

Logging | UE4 Community Wiki

Logging Logging means keeping an ordered record of events, function calls, variable values at a certain time during runtime, etc. This is usually saved in the form of text in a log file. Here is an example of a simple log message: UE_LOG(LogTemp, Warning,

www.ue4community.wiki

 

먼저 택스트를 로그창에 출력해보자. 

void AMyActor::BeginPlay()
{
	Super::BeginPlay();
	
	UE_LOG(LogTemp, Warning, TEXT("Hello"));
}

 

작성한 후 UE4로 가서 컴파일을 클릭하고, 실행하면 출력 로그에서 작성한 텍스트를 확인할 수 있다.


출력 로그는 창 -> 개발자툴 -> 출력로그에서 추가할 수 있다.

 

이번엔 숫자를 출력해보자.

void AMyActor::BeginPlay()
{
	Super::BeginPlay();
	
	UE_LOG(LogTemp, Warning, TEXT("Hello"));
	UE_LOG(LogTemp, Warning, TEXT("abcd %d"), 10);
}

C 형식의 언어들처럼 작성하면 된다.

동일하게 컴파일 후 실행을 눌러보면 확인할 수 있다.

출력이 중복으로 두번 나왔다. 그 이유는 엑터를 하나 더 추가했기 때문이다.
동일한 코드를 사용하는 엑터를 더 추가했기 때문에 동일한 작업이 일어난 것이다.

MyActor로 AAA, BBB 엑터를 생성.

이번엔 틱에서 한번 확인해보자. 그전에 인스턴스는 하나만 남겨두고 진행한다.

void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	UE_LOG(LogTemp, Warning, TEXT("DeltaTime %f"), DeltaTime);
}

컴파일 이후 실행해보면 이번에는 출력이 계속 반복된다.

이전 프레임에서 시작해서 현재 프레임이 다시 시작되는 시간이 뜨는 것이다.
이건 프레임타임이 0.008초정도라는 것이다.

너무 속도가 필요 이상으로 빠른 상태이니 이것을 조정하는 방법

(초당 프레임을 변경하는 방법)

 

이번에 찍히는 델타 타임이 0.03333... 이 찍히고 있다. 이는 프레임 0.033...초 라는 뜻이다. 1/30초. 프레임이 한번 시작되고 다음 프레임이 찍힐떄까지의 시간. 이는 1초에 30장 그림이 업데이트 된다는 뜻.

처음 상태로 돌려두자. (플레이 중에도 설정을 바꿀 수 있다. 프레임 설정은 실시간 설정.)


05c 게임 화면에 디버그 출력을 해보자

 

다음 링크로 가면 스크린 출력 예제가 있다. Printing Messages to Screen

 

Logging | UE4 Community Wiki

Logging Logging means keeping an ordered record of events, function calls, variable values at a certain time during runtime, etc. This is usually saved in the form of text in a log file. Here is an example of a simple log message: UE_LOG(LogTemp, Warning,

www.ue4community.wiki

이 함수는 아마도 Tick에서만 작동한다고 한다. 

첫 파라미터는 int형의 키 값이다. 메시지의 ID에 해당하는 숫자. 없으면 -1,
두번째 파라미터는 float형의 화면에 출력하고있는 시간을 정한다.  3.0f면 3초.
세번째 파라미터는 색을 정할 수 있다. 언리얼 에서는 FColor 클래스를 사용하여 미리 정의되어있는 색을 사용.

FColor에 이미 정해져있는 색깔들

그다음 파라미터는 출력할 문자를 넣는 자리이다.
TEXT는 안에 쓰는 문자열을 언리얼에서 사용하는 문자열인 FString으로 바꿔주는 매크로이다.

void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Blue, TEXT("Hello"));
}

작성한 뒤, 컴파일한 다음 실행해보자.

계속 반복되며 틱마다 출력이 하나 나온다. 이미 있으면 그 아레에 출력되어서 저렇게 쌓이게 된다.

 

코드를 변경하여 프레임 타임을 출력해보자. 출력 형식을 변경해야 해서 아래의 코드로 작성했다.

void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FString str;
	str = FString::Printf(TEXT("Frame Time: %f"), DeltaTime);

	GEngine->AddOnScreenDebugMessage(-1, 0.2f, FColor::Blue, str);
}

출력 유지 시간도 줄여서 더 짧은 양만 화면에 표시된다.


fps를 표시하기 위해 코드를 변경해보자. 

void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FString frame_time;
	frame_time = FString::Printf(TEXT("Frame Time: %f"), DeltaTime);

	FString fps;
	fps = FString::Printf(TEXT("fps: %f"), 1.0f / DeltaTime);

	GEngine->AddOnScreenDebugMessage(-1, 0.2f, FColor::Blue, frame_time);
	GEngine->AddOnScreenDebugMessage(-1, 0.2f, FColor::Green, fps);
}

1초를 DeltaTime 으로 나눈 값이 fps(frame fer second)이다.


너무 아래로 주르르륵 뜨는 것이 보기 싫으니 이걸 줄이는 방법 생각해보자.


한가지 방법은 출력하는 시간을 줄이는 것이다.
3.0f 보다 0.2f일때가 화면에 더 적게 보인다.

다른 방법은 DeltaTime 만큼만 출력을 해주는 것이다.

void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FString frame_time;
	frame_time = FString::Printf(TEXT("Frame Time: %f"), DeltaTime);

	FString fps;
	fps = FString::Printf(TEXT("fps: %f"), 1.0f / DeltaTime);

	GEngine->AddOnScreenDebugMessage(-1, DeltaTime, FColor::Blue, frame_time);
	GEngine->AddOnScreenDebugMessage(-1, DeltaTime, FColor::Green, fps);
}

 

Deltatime 만큼 출력

첫번째 파라미터인 키 값을 사용하는 방법도 있다.
출력할 때마다 키 값을 확인해서 같은 숫자의 키에 해당하는 메시자가 화면에 있으면 그 부분을 대체한다.

void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FString frame_time;
	frame_time = FString::Printf(TEXT("Frame Time: %f"), DeltaTime);

	FString fps;
	fps = FString::Printf(TEXT("fps: %f"), 1.0f / DeltaTime);

	GEngine->AddOnScreenDebugMessage(1, 1.0f, FColor::Blue, frame_time);
	GEngine->AddOnScreenDebugMessage(2, 1.0f, FColor::Green, fps);
}

키 값 사용

더 안전하고 더 좋은 방법이다.
델타타임은 작은 오차가 있으면 글자가 사라지고 없어지는것이 보일 수 있고 아래에 뜰 수도 있기 떄문이다.


중요한 부분. 델타타임을 이용하여 fps 측정하기.
키 값을 이용하여 안전한 출력 하기

320x100