게임 동작의 기본 뼈대 - 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로 설정했다.
▶로그는 로깅 수준에 따라서 색이 다르고, 로그 파일로 따로 출력되는지 여부도 다르다.
색깔과 출력 여부로 구분하고 싶다면 로깅 수준을 조절하자.
유니티는 엔진을 돌리는 상태에서도 VS에 BP를 찍어서 디버거를 돌리는게 가능했는데, 언리얼은 역시나 단계가 복잡하다.
▶즉, 언리얼은 기본적으로 엔진을 구동한 상태에서 디버깅을 할 수 없다고 보면 된다.
마음의 준비(?)를 할 것. 액터 이름 수정에서 느낀 것이 없는가?
-> 왜 항상 슬픈 예감은 틀린 적이 없는가. 그렇다. 엔진을 또 꺼야한다.
슬퍼하긴 이르다 - 엔진 코드의 특성 상 디버거를 돌리면 엔진이 다시 켜진다. 그래서 꺼야 한다는 것.
-> 이 작업을 통해서 처음으로 UE -> VS가 아니라 VS -> UE 방향으로 구동을 해본 것.
컨텐츠와 엔진이 일체화된 느낌을 받을 수 있을 것이다.
디버깅 돌리는데 저는 메모리 창이 안떠요!
-> 디버깅 실행한 상태에서 상단메뉴 디버그 > 창 > 메모리.
Alt + D > W > M > 엔터 눌러도 된다.
UE에서 VS를 호출하고 코드를 수정 후 빌드하면 소리가 나면서 UE에 반영 - '핫 리로드' 라고 한다. UE를 끄거나 하지 않아도 된다.
-> 이 방법을 쓸 경우 디버깅 하기는 좀 귀찮아진다. 일단 엔진을 끄고 디버깅용 엔진이 다시 켜지길 기다려야 하기 때문.
그래서 로그를 찍는 식으로 분석하는게 좋다.
VS에서 디버거를 돌려 UE를 호출하는 경우 디버깅 중지를 누르는 순간 엔진도 같이 꺼진다. 좀 불편할 것.
-> 다만 이 방법은 위의 방법보다 디버깅 하기는 수월한 편.
이 둘은 스타일의 차이이므로 프로젝트의 스타일에 따라 적절하게 사용할 것.
-> 디버그에 필요한 정보. 이 디버그 심볼이 들은걸 디버그 심볼 파일(프로그램 데이터베이스 파일, PDB 라고도 함) 이라고 한다.
저기요. 이게 뭔데요. 제가 뭐 글로벌 셰이더한테 잘못했나요...? (두통)
-> DebugGame이나 Development로 선택하고 디버깅하면 당연히 뜨는 것.
이건 실행파일만 만들어 준거지 아트 리소스(셰이더)는 따로 넣어줘야 하므로, 아트 리소스가 없으니 당연히 오류가 나는 것.
Editor가 안 붙은 것을 선택하고 디버거를 돌리면 exe 파일이 만들어지는데, Editor가 붙은 것을 선택하고 디버거를 돌리면 dll 파일이 만들어진다.
-> 이걸 선택하면 언리얼 에디터를 켠 다음에 dll만 교체해서 컨텐츠를 엔진에 올리는 식으로 동작을 하기 때문에, 아까처럼 글로벌 셰이더가 없다는 식의 징징거림 alert가 뜨지 않는다.
▶유니티가 그리운가? 킹치만 언리얼은 원래 이렇게 생겼는걸
-> C++이 원래 C#에 비해 빌드가 느리다. 언리얼의 빌드가 느린 데에는 이 이유가 가장 크다.
-> 그러나 빌드 속도 외에도 액터 이름 바꾸려면 엔진 끄고, 디버깅 하려면 엔진 끄고 하는 부수적인 작업들에서 걸리는 시간이 생각보다 상당하다.
그래서 언리얼로 게임을 만드는 경우는 상상만큼 멋지지 않고, 오히려 이 오래걸리고 짜증나는 현상이 정상이다.
▶결론적으로, 3차원을 표현하기 위해서는 수가 4개가 필요해서 나오게 된 개념이다. 수의 구성요소가 4개라서 사원수 라고 하는 것. 1개의 실수와 3개의 허수축으로 구성되어 있다.
3차원을 표현하려면 2차원에서 쓰던 실수와 허수축 두개로는 부족했기 때문에 또다른 허수단위 j를 도입해서 고려했다. 이런 수를 삼원수 라고 한다.
-> 근데 결론부터 말하면 삼원수라는건 존재하지 않는다. 숫자 세개로는 3차원을 표현할 수 없었다.
왜 표현할 수 없냐면 이 삼원수의 조건을 만족시키는 수가 존재하지 않았기 때문. 증명이 불가했음.
뭐, 아무튼.
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축에 박힌 채로 돌아가서, 의자가 등받이쪽으로 넘어가면서 더블락스핀처럼 회전한다.