C++ 기반 UE4 입문 - 로그를 찍어보자

LIHA·2023년 3월 12일
0

Unreal Engine

목록 보기
4/5
post-thumbnail

우리는 로그를 찍을 것이다 - UE_LOG() 메소드를 사용하자

게임 동작의 기본 뼈대 - BeginPlay와 Tick.
시작할때 한번만 로드되는 것과 실시간으로 업데이트 하는 두 메소드. 여기에 한번 로그를 찍어보자.
-> 카테고리, 로깅 수준, 형식, 인자 순서로 입력하고 빌드시키면 엔진의 출력 로그 창에서 확인할 수 있다.

void AMyActor::BeginPlay()
{
	Super::BeginPlay();

	// 시작
	//카테고리, 로깅수준, 형식, 나머지 인자들
	UE_LOG(LogTemp, Warning, TEXT("BeginPlay %d"), 3);
    
    //BeginPlay쪽은 가볍게 Warning 으로 설정하고 출력형식을 %d로 설정했다.
	
}

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

	UE_LOG(LogTemp, Error, TEXT("Tick %f"), DeltaTime);
}
//Tick쪽은 Error로 설정하고 출력형식을 %f로 설정했다.
  • 위와 같이 로그 설정을 할 경우 이렇게 찍힌다.
    -> BeginPlay쪽은 '노란색'으로 BeginPlay 3 이라고 찍히고, 한번 찍힌다.
    -> Tick쪽은 '빨간색'으로 Tick (DeltaTime) 으로 찍히고, 멈출때까지 계속 찍힌다.

▶로그는 로깅 수준에 따라서 색이 다르고, 로그 파일로 따로 출력되는지 여부도 다르다.
색깔과 출력 여부로 구분하고 싶다면 로깅 수준을 조절하자.

  • 형식중에 Verbose가 있는데 이게 뭐에요?
    -> 사전적 정의는 '말수가 많은' 이라는 뜻의 형용사. 상세 로깅을 출력할지 말지 조정하는 파라미터.

언리얼은 디버깅도 쉽지 않아요 - 엔진구동과 디버깅을 동시에 할 수 없다

유니티는 엔진을 돌리는 상태에서도 VS에 BP를 찍어서 디버거를 돌리는게 가능했는데, 언리얼은 역시나 단계가 복잡하다.

▶즉, 언리얼은 기본적으로 엔진을 구동한 상태에서 디버깅을 할 수 없다고 보면 된다.
마음의 준비(?)를 할 것. 액터 이름 수정에서 느낀 것이 없는가?
-> 왜 항상 슬픈 예감은 틀린 적이 없는가. 그렇다. 엔진을 또 꺼야한다.

  • 슬퍼하긴 이르다 - 엔진 코드의 특성 상 디버거를 돌리면 엔진이 다시 켜진다. 그래서 꺼야 한다는 것.
    -> 이 작업을 통해서 처음으로 UE -> VS가 아니라 VS -> UE 방향으로 구동을 해본 것.
    컨텐츠와 엔진이 일체화된 느낌을 받을 수 있을 것이다.

  • 디버깅 돌리는데 저는 메모리 창이 안떠요!
    -> 디버깅 실행한 상태에서 상단메뉴 디버그 > 창 > 메모리.
    Alt + D > W > M > 엔터 눌러도 된다.

VS에서 디버깅으로 엔진을 켜면 디버깅 종료시 엔진도 꺼진다

  • UE에서 VS를 호출하고 코드를 수정 후 빌드하면 소리가 나면서 UE에 반영 - '핫 리로드' 라고 한다. UE를 끄거나 하지 않아도 된다.
    -> 이 방법을 쓸 경우 디버깅 하기는 좀 귀찮아진다. 일단 엔진을 끄고 디버깅용 엔진이 다시 켜지길 기다려야 하기 때문.
    그래서 로그를 찍는 식으로 분석하는게 좋다.

  • VS에서 디버거를 돌려 UE를 호출하는 경우 디버깅 중지를 누르는 순간 엔진도 같이 꺼진다. 좀 불편할 것.
    -> 다만 이 방법은 위의 방법보다 디버깅 하기는 수월한 편.
    이 둘은 스타일의 차이이므로 프로젝트의 스타일에 따라 적절하게 사용할 것.


Debug, Dev, Shipping? 디버그 심볼과 최적화 정도의 차이

  • VS를 보면 디버그 모드가 이렇게 다섯 가지나 된다. 추려도 세 갠데, 뭐가 다른거지?
    -> Debug와 Development의 차이는 Debug와 Release의 차이라고 보면 된다. 즉, 최적화 정도가 다르다.
    Debug는 Develop에 비해서 디버그 심볼이 많이 남아있기 때문에 디버그 하긴 편하다.
    -> 보통 Shipping 쪽으로 갈 수록 가장 최적화가 잘 되어 있다. 누르고 눌러 최적화 해줌.

디버그 심볼이 뭔데요? 😵😵

-> 디버그에 필요한 정보. 이 디버그 심볼이 들은걸 디버그 심볼 파일(프로그램 데이터베이스 파일, PDB 라고도 함) 이라고 한다.

  • 디버그 심볼은 '정보' 이기 때문에, 빌드 종류에 따라 달라지는 최적화 정도에 따라서 일부 혹은 전부가 '손실'된다.
    왜냐면 최적화 과정에서 컴파일러가 얘를 갖다 버리기 때문.
    -> 그렇기 때문에 개발단계라면 가능하면 디버그 모드로 돌리는게 좋다.
    BAT 정도 할거 아니면 어지간하면 Shipping으로 빌드 뽑지 말것. 아니, BAT 할거여도 Shipping으로는 뽑지 말것.

DebugGame이나 Development로 디버깅했는데 글로벌 셰이더 오류가 난다면 - 의외로 정상

저기요. 이게 뭔데요. 제가 뭐 글로벌 셰이더한테 잘못했나요...? (두통)
-> DebugGame이나 Development로 선택하고 디버깅하면 당연히 뜨는 것.
이건 실행파일만 만들어 준거지 아트 리소스(셰이더)는 따로 넣어줘야 하므로, 아트 리소스가 없으니 당연히 오류가 나는 것.

그럼 DebugGame Editor는 뭔데요? - dll 파일 생성용!

Editor가 안 붙은 것을 선택하고 디버거를 돌리면 exe 파일이 만들어지는데, Editor가 붙은 것을 선택하고 디버거를 돌리면 dll 파일이 만들어진다.
-> 이걸 선택하면 언리얼 에디터를 켠 다음에 dll만 교체해서 컨텐츠를 엔진에 올리는 식으로 동작을 하기 때문에, 아까처럼 글로벌 셰이더가 없다는 식의 징징거림 alert가 뜨지 않는다.

DebugGame인지 DebugGame Editor인지 창이 작아서 안보여요😫 - 너비를 바꾸자

  • 그 DebugGame 콤보박스 근처 아무데나 우클릭 > 도구 모음 > 명령 > 표준 > 솔루션 구성 선택하고 우측의 '선택 사항 수정' 클릭 > 너비 수정 (보통 150 ~ 200 정도 권장)

▶유니티가 그리운가? 킹치만 언리얼은 원래 이렇게 생겼는걸
-> C++이 원래 C#에 비해 빌드가 느리다. 언리얼의 빌드가 느린 데에는 이 이유가 가장 크다.
-> 그러나 빌드 속도 외에도 액터 이름 바꾸려면 엔진 끄고, 디버깅 하려면 엔진 끄고 하는 부수적인 작업들에서 걸리는 시간이 생각보다 상당하다.
그래서 언리얼로 게임을 만드는 경우는 상상만큼 멋지지 않고, 오히려 이 오래걸리고 짜증나는 현상이 정상이다.


의자를 회전시켜보자 - FRotator와 Quaternion중에 뭘 쓸까?

▶결론적으로, 3차원을 표현하기 위해서는 수가 4개가 필요해서 나오게 된 개념이다. 수의 구성요소가 4개라서 사원수 라고 하는 것. 1개의 실수와 3개의 허수축으로 구성되어 있다.

  • 아니 축이 세갠데 어떻게 요소가 4개에요? 뭐가 어디에 쓰이는건데요?
    -> 실수 성분은 회전각도, 나머지 허수 성분은 각 축의 좌표이자 벡터로 간주한다.
    -> 우리가 보통 알고있는 xyz 좌표계는 오일러 좌표계인데, 여기에 한계가 있기 때문에 쿼터니언 개념이 나오게 된 것!
    그 한계를 '짐벌락' 이라고 한다. 시간나면 검색해보자.

3차원을 표현하려면 2차원에서 쓰던 실수와 허수축 두개로는 부족했기 때문에 또다른 허수단위 j를 도입해서 고려했다. 이런 수를 삼원수 라고 한다.
-> 근데 결론부터 말하면 삼원수라는건 존재하지 않는다. 숫자 세개로는 3차원을 표현할 수 없었다.
왜 표현할 수 없냐면 이 삼원수의 조건을 만족시키는 수가 존재하지 않았기 때문. 증명이 불가했음.
뭐, 아무튼.

그래서 FRotator의 인자값으로 뭘 넣을까? UE Docs를 참고하자

Docs는 이쪽
-> Docs에 따르면 Pitch, Yaw, Roll 순으로 넣는다. y, z, x 축 순이다.

	AddActorLocalRotation(FRotator(0.f, RotateSpeed * DeltaTime, 0.f));

↑코드는 이렇게 작성되었다.
이건 z축을 회전축으로 써서 (회전스피드 * DeltaTime) 을 설정해서 돌릴것이라서, 나머지는 0.f로 그냥 두고 가운데만 이렇게 쓴 것이다.
-> 이렇게 쓰면 z축에 박힌채로 돌아가므로 디스코팡팡처럼 회전한다.
-> 그러니 회전축을 다른걸로 설정하고 싶으면 0.f와 (회전스피드 * DeltaTime) 의 위치만 바꿔주면 된다. y축을 중심으로 돌려볼까나?

  • DeltaTime은 왜 곱하는거에요? 속도 * 시간 하면 거리 아닌가요? 🤔
    -> 유저마다 컴퓨터의 사양이 다르기 때문에, 초당 연산 가능한 프레임 수도 다르다.
    때문에 리터럴 값으로 박아버리면 저사양 컴퓨터는 굉음을 내며 클라이언트가 다운될 것.
    그래서 각자 PC 사양에 맞는 연산으로 돌아가도록 DeltaTime을 곱해주는 것이다.
    -> 어떻게 보면 거리가 맞다. 고사양 PC에선 더 많이 돌아갈테니 회전 거리 값이 클것이고, 저사양 컴퓨터에선 작을 것.

  • 어 제 의자 안돌아가는데요?
    -> 핫 리로드 안해서 그럼. 엔진 에디터에서 컴파일 누르고 실행시키면 돌아갈것.

	AddActorLocalRotation(FRotator(RotateSpeed * DeltaTime, 0.f, 0.f));

↑이렇게 축을 다르게 설정해주면 y축에 박힌 채로 돌아가서, 의자가 등받이쪽으로 넘어가면서 더블락스핀처럼 회전한다.

다음 강의부터 세팅 - Development, 핫 리로드를 기본으로 할것!

profile
갑자기 왜 춤춰?

0개의 댓글