Post | Sanctuary
top of page
  • Join our Discord!
  • Join our Kickstarter!

최적화와 애니메이션

안녕, 저는 Antypodish고 이건 제 첫 개발자 로그에요.


시작하기 전에 간단히 제 소개를 하도록 하겠습니다; 저는 원래 전기 공학, 철강업 자동화, 원자력 로봇공학과 물 산업 같은 분야에서 배우거나 일한 경험이 있지만, 게임 개발은 제 취미였기에 이보다 훨씬 더 일찍 시작했습니다. 제가 처음 유니티를 접한 건 2014년, 제가 “프롬 더 뎁스”라는 게임의 커뮤니티에서, 당시에는 몇 없던 게임 모더들 중 하나로, 남는 시간에 소소하게 모드를 만드는 정도로 활동하던 시기였습니다. 몇 년쯤 지나고 나니 저만의 것을 만들어보고 싶단 생각이 들었고, 그 때 이후로는 여러 유니티 프로젝트를 만들며 Unity forum에서 자주 활동하게 되었죠.


제가 처음 유니티를 가지고 놀기 시작했을 때부터, 주로 관심을 둔 것은 최적화와 어떻게 하면 극단적으로 큰 스케일을 구현할 수 있는가였습니다. 저는 실험하는 것을 좋아했고, 제 프로젝트에 DOTS, 머신러닝, 절차적 생성같은 강력한 기법들을 끼워넣고는 했죠. 종종 제 Youtube 채널에 영상을 올리기도 하니까, 관련 분야에 관심이 있으시다면 그곳에서 흥미로운 것들을 찾으실 수 있을지도 모릅니다. 얼마든지 저한테 연락하는 걸 주저하지 마세요. 공식 Discord에서도 저와 이야기를 주고받을 수 있고요.😉

프롬 더 뎁스같은 게임 말고도, 저는 제로-K, 팩토리오, 마인크래프트, 문명과 심시티같은 게임들을 자주 플레이했습니다. 꼭 이런 게임들만을 하는 것은 아니고, 시간이 나면 얼마든지 다른 게임들을 탐험해보기도 했죠. 위에서 소개한 건 제가 가장 좋아하는 목록들 중 일부입니다.

삶의 변화에 따라서, 저는 게임 개발업계에 뛰어들게 되었고, 마침내 생츄어리의 두 창업자들에 의해 발견되었습니다. DOTS 프로그래머를 찾고 있더군요. 그렇게 지금, 생츄어리 팀의 행복한 일원으로서 이 자리에 있게 되었죠.😊


 

제가 초기에 하게 된 작업들 중 하나는 애니메이션이었습니다. 아직 작업 중이긴 하지만, 현재의 애니메이션은 골격과 리깅 메쉬를 사용합니다. 우리 모델들에 달린 포탑과 총을 움직이고 사용할 수 있게 해주죠. 초기 버전은 모델 하나에도 여러 메쉬를 사용했지만, 제가 통일된 스킨 메쉬를 사용하게 변경한 이후로는 성능이 증가했습니다. 특히 이 게임의 특성 상 동시에 수천 개의 유닛이 전장에서 활동한다는 걸 감안하면 말이죠. 저는 또한 나중에 사용될 디테일들을 위한 지원도 추가했고, 이것은 우리의 게임이 다양한 줌 레벨에서도 더 유연하게 작동할 수 있도록 도와주었지만, 스킨 메쉬에 있어서는 다소 많이 복잡했습니다: 모든 가능성을 일일이 복사했다간 너무 많은 메모리가 소모되었을 테니까요. 게다가 우리는 DOTS 프레임워크를 사용하는 중이고, 이는 우리의 코드가 여러 스레드와 함께 작동하도록 디자인 되었음을 의미합니다. 하지만 이 모든 문제들은 약간 노력하기만 하면 충분히 해결이 가능한 것들입니다. 제가 생츄어리의 게임 논리와 애니메이션에 한 실험 중 하나는 다포탑 유닛들이 서로 다른 범위를 가지고 조준할 수 있는지 알아보는 것이었습니다. 예를 들어서, 전차의 우측에 있는 포탑이 왼쪽에 있는 포탑보다 사거리가 더 길거나 하는 식이죠. 이런 방식은 두 포탑의 포각이 서로 다르게 조정되어야 한다는 것을 의미했습니다. 기술적으로는 충분히 적용이 가능하지만, 모든 유닛에 적용되지는 않을 요소입니다. 물론 우리가 다포탑 유닛들을 지원하고 싶었던 만큼 저는 미리 적용해두었지만요. 다포탑 하면 해군 유닛들이 가장 먼저 떠오르지만, 공중 유닛들의 하부 포탑에도 적용될 가능성이 있습니다.

제가 주로 애니메이션과 골격에 대해서 이야기했지만, 저는 또한 걸어다니는 유닛들을 위해, 후진동작(inverse kinematics, FABRIC & CCD)을 사용한 애니메이션 해결법 또한 찾아보았습니다. 여기선 절차적 애니메이션을 사용할까 고려하는 중입니다. 한편으로는 복잡하지만, 한편으로는 우리 모델링 팀을 위해서 여러 문제들을 해결해주죠. 더 이상 걸어다니는 유닛들을 위한 스톡 애니메이션을 만들지 않아도 되니까요. DOTS와 연계해서 작동할 수 있게 하도록 하려면 쉬운 일은 아니지만, 그럴만한 가치가 있는 작업입니다. 여러 개의 다리가 달린 유닛들이 불균형한 지형을 걸어다닐 때도 매우 현실적으로 보이고, 다리가 공중에 뜨거나 클리핑되는 일이 없을 테니까요! 하지만, 다리가 한 쌍 달린 유닛과 여러 쌍 달린 유닛은 또 다르기 때문에, 지금 시점에서는 어떤 해결책을 최종적으로 쓰게 될지 알 수 없는 상황입니다. 그래도, 이런 도전들이 제게는 원동력으로 작용하더라구요.



지금쯤이면 다들 아시겠지만, 생츄어리 RTS는 CPU에서 최대한 많은 성능을 뽑아내는 것을 목표로 하고 있습니다. 하지만, 우리는 단순히 최적화에만 집중하는 것이 아니라, LUA 지원을 통해 게임이 폭 넓게 모딩이 가능하도록 하고 싶었습니다. 이건 그렇게 쉬운 도전이 아닙니다. 우리는 10000개가 넘는 유닛들이 동시에 전장에서 공격, 건설, 길찾기, 자원 수집같은 여러 종류의 활동을 수행하는 것을 목표로 했으니까요. 그에 더해, 우리는 이 모든 것들이 멀티플레이어 네트워크에서도 지원되는 것으로 목표를 잡았습니다.

많은 게임들은 하나나 2개 정도의 CPU 스레드를 사용하고, 대부분의 시각 효과는 GPU에게 할애합니다. 그러면 왜 우리도 이렇게 할 수는 없냐고요? 멋진 시각적 효과는 GPU에게 남겨두고 CPU가 시뮬레이션을 하게 할 수는 없을까요? 다른 게임에서도 잘 작동하는 방식이라면 생츄어리에서도 먹히지 않을까요? 하지만, 우리가 만든 게임의 스케일은 워낙 큰 탓에 CPU와 GPU 간에 지나치게 많은 데이터가 오가는 것은 최대한 피해야 합니다.


가장 최근의 시험에서는 8코어의 I7 프로세서를 가진 중간 정도 사양의 PC에서 1만개의 유닛을 시뮬레이션했을 때 안정적으로 60fps를 출력할 수 있었습니다. 이런 게 가능했던 이유는 오직 우리가 DOTS를 통해 최대한 다중 코어의 성능을 끌어올릴 수 있도록 게임을 기초부터 디자인했기 때문이었죠.


 

멀티스레딩도 중요하지만, 최적화 면에서 동등하게 중요한 부분은 여럿 존재합니다. 코드가 더 이상 사용하지 않는 메모리를 치우는 방식인 가비지 컬렉션을 예로 들어보겠습니다. 최적화 과정에서, 저는 주된 쓰레기 수집 발생 상황과 병목 현상을 추적하고, 이것을 어떻게 완화하고, 이것들이 왜 게임플레이 중에 발생하는지 조사하게 되었습니다. 게임이 버벅거리거나 랙 현상이 발생하는 것을 최소화하기 위해서는 이것을 고려하는 것이 중요했으니까요. 이런 부분은 제 작업에서 절대로 끝나지 않는 부분이기도 합니다. 언제나 더 최적화할 부분이 남게 되더군요.


제가 최적화를 위해 사용한 방법 중 하나는 우리가 모든 스크립트를 모든 프레임에서 실행해야 하는지 검토해보는 것이었습니다. 0.1초의 시간에서, 게임이 60fps로 돌아간다고 가정하면, 프레임당 16ms는 되어야 편안한 게임플레이 경험이 가능합니다. 그래도 전략 게임은 이러한 요구 사항이 비교적 덜한 편입니다. FPS같은 경우에는 20fps나 40fps 정도의 지연만으로도 헤드샷을 당하느냐 아니냐를 결정할 수도 있으니까요. 멀티플레이어에서 랙이 일어나는 현상을 목격하신 분이라면 아마 이걸 확연히 느낄 수 있을 겁니다.


하지만, RTS에서는 즉각적인 효과보다는 플레이어가 넣은 입력에 대한 반응성이 더욱 중요합니다. 그렇기에 어떤 작업들이 중요하고, 어떤 작업들은 덜 중요한지 분간하는 것이 가능해졌죠. 적당한 기한 안이라면 조준이나 길찾기에 대한 계산 빈도를 다소 지연시킬 수도 있는 것입니다. 제가 맡은 작업 중 하나는 이런 프레임이 작동하는 방식을 조직화하고 스케줄을 짜는 것이었습니다.


저는 한 시뮬레이션 프레임에서 어떤 작업들이 일어나는지, 제가 설계한 6프레임 모델을 바탕으로 결정해야 했습니다. 물론 멀티스레딩 호환성을 염두에 두고요. 더 곤란한 압박은, 플레이어가 게임 호스트일 경우였습니다: 그런 상황에서는 호스트와 다른 플레이어들의 코드를 동시에 시뮬레이션해야 하기 때문입니다. 프레임의 절반을 호스트에게, 나머지 절반을 다른 플레이어에게 분배하는 것은 한 프레임에 지나친 부담이 가해지는 것을 줄일 수 있습니다. 그렇기에 더 편안한 게임플레이 경험을 제공하고 CPU 활용률을 높일 수 있게 되죠. 제가 작업하면서 가장 재미있다고 느낀 도전들 중 하나였습니다! 😊


당장은, 이쯤해서 제 첫 개발자 로그를 멈추는 게 좋다고 느끼네요. 읽으면서 재밌으셨기를 바랍니다.


다음에 다시 만날 때까지,

Anty


5 views0 comments
bottom of page