지금까지 했던 모든 삽질의 원흉은.. 언리얼 엔진의 appSleep은, 밀리초 단위가 아닌, 그냥 '초' 단위였다는 것이란 걸 어제 발견했다. (털썩)
2차 CBT까지 한 R모 게임을 플레이하면서 "30분 기다렸는데 캐릭터가 안나와요" 하신 분들, 죄송합니다. (꾸벅) "30분동안 해도 그림자만 보여요" 하신 분들, 역시 죄송합니다. (꾸벅) "캐릭터 머리가 계속 뻥 뚫려보여요" 하신 분들께도, 역시 죄송합니다 (꾸벅)
이제 단위가 밀리초단위가 아니라 그냥 '초'단위란 걸 알았으니, 아마 캐릭터가 나타나기까지 걸리는 시간이 1/1000로 단축될 겁니다.. (아마도) 다음부턴 잘 될 겁니다 ( __)
모든 게임의 가장 상위에는 대개 다음과 같은 루프가 있기 마련이다.
while ( quit == false )
{
process_userinput();
update_everything( time_elapsed );
draw_everything();
Sleep( 1 );
}
보통 게임에서는 루프를 돌다가 다른 쓰레드나 프로세스에 약간의 기회를 양보하기 위해서 윈도우 API의 Sleep을 호출한다. Sleep을
호출한 쓰레드는 지정된 시간동안 (단위는 밀리초) '잠이 들고', 윈도우는 다른 쓰레드를 깨워서 일을 시킬 여력이 생기게 된다.
내가 이 회사와서 맡은 일 중의 하나가, 캐릭터의 로딩을 쓰레드로 띠어내는 일인데, 쓰레드가 무한정 CPU자원을 먹어서는 안되므로, 쓰레드
역시 다음과 같은 루프로 구성된다.
while ( quit == false )
{
wait_for_request();
load_requested();
Sleep( 1 );
}
문제는 여기서 Sleep이 윈도우API함수라는 데 있다. Sleep을 호출하는 부분이, 쓰레드 본체에 있는게 아니라, 다른 DLL에
있는데, 이 DLL이 윈도우 API를 호출하기 곤란한 구조라는 점이 문제. 그래서 언리얼 엔진에서 제공하는 appSleep이란 함수가 동일한
일을 해주는 것을 발견하고 다음과 같이 넣었다.
while ( quit == false )
{
wait_for_request();
load_requested();
appSleep( 1 );
}
그런데, 물론, 아까도 말했듯이, appSleep의 단위는 Sleep과는 다르게 '초'인 것이다. -_- 캐릭터가 여러 부분으로
구성된다면, 한 부분 로딩할 때마다 appSleep(1)이 먹고, 결국, 로딩하는데 수초 정도를 '잠자는데' 보내고서야 로딩이 끝나는 것.
OTL 플레이어가 100명정도 등장하면, 수백초를 '잠자는데' 보내고서야 로딩이 끝난다.... 당연히 30분이 지나도 플레이어가 안나오는 유저가
생기지...... (아놔)