본문으로 건너뛰기

© 2026 Molayo

YouTube요약2026. 06. 15. 06:49

수천 개의 오브젝트? Unity 물리 성능을 해결하려면 이렇게 하세요

요약

Unity 엔진에서 수천 개의 물리 오브젝트를 사용할 때 발생하는 성능 저하 문제를 해결하는 최적화 방법을 다룹니다. 플레이어 주변의 오브젝트만 물리 시뮬레이션 대상에 포함하고 나머지는 정지시키는 전략을 제안합니다.

핵심 포인트

  • 많은 물리 오브젝트는 물리 엔진 시뮬레이션 틱에서 큰 오버헤드를 발생시킴
  • 플레이어 주변의 오브젝트만 활성화하여 불필요한 물리 계산을 방지해야 함
  • 리지드 바디를 정지(freeze)시키는 것만으로도 프레임 타임을 크게 개선 가능

비디오: 수천 개의 오브젝트? Unity 물리 성능을 해결하려면 이렇게 하세요
채널: Game Dev Guide
길이: 6분 41초
출처: 자막 (자동 생성, 영어)

스크립트:
만약 여러분도 저처럼 씬(scene)에서 많은 물리 오브젝트를 사용하고 있다면, 아주 빠른 최적화 팁을 하나 알려드리겠습니다. 이것은 제 게임 'Cabs of Chaos'의 레벨 맵입니다. 이것은 제 다운타운 맵입니다. 보시다시피, 리지드 바디 (Rigid Body)가 적용된 수많은 작은 프롭 (prop) 오브젝트들이 있으며, 플레이어는 언제든 이 오브젝트들에 돌진하거나 상호작용할 수 있습니다. 제가 목표로 하는 게임의 혼돈스러운 에너지를 높이기 위해, 플레이어가 부수고, 돌진하고, 들이받을 수 있는 많은 물리 오브젝트를 게임에 포함하는 것이 저에게는 중요합니다.

이렇게 많은 물리 [음악] 오브젝트를 보유하는 것은 무시할 수 없는 수준의 오버헤드 (overhead)를 발생시킵니다. 프로파일러 (Profiler)를 살펴보면, 성능의 상당 부분이 물리 엔진 (physics engine)의 시뮬레이션 틱 (simulation tick)에서 소모되고 있음을 확인할 수 있습니다. 이를 처리하는 데 약 5밀리초 (ms) 정도를 사용하고 있습니다. 이는 제가 일반적인 싱글 플레이어 환경에서 60 FPS를 달성하려고 노력 중이라는 점을 고려할 때 프레임 예산 (frame budget)의 큰 부분을 차지합니다. 또한 이것은 4인용 게임이므로, 4인 플레이 경험을 최대한 부드럽게 만들기 위해 가능한 최선의 성능을 확보하고 싶습니다.

그리고 이것은 현재 저에게 매우 중요한 문제입니다. 왜냐하면 이번 주말 밴쿠버에서 열리는 엑스포 (expo)에 제 노트북을 가져가기 때문입니다. 따라서 싱글 플레이어에서는 이상적으로 60 FPS 이상으로 실행되어야 하며, 그래야 4인 플레이 시에도 최소 30 FPS 이상을 유지하여 부드럽고 반응성이 좋게 느껴질 수 있습니다. 제 데스크톱 머신에서는 성능이 충분히 괜찮아서 이를 느끼지 못하고 준수한 프레임 타임 (frame time)을 얻고 있습니다. 하지만 제 노트북에서는 성능이 좋지 않았다고 말할 수밖에 없습니다.

따라서 여기 물리 프로파일 (physics profile)을 살펴보면, 어느 시점에서든 1,300개가 넘는 동적 바디 (dynamic bodies)가 스윕 (swept)되고 있는 것을 확인할 수 있습니다. 사실 현실적으로 플레이어 주변에는 특정 시점에 존재하는 물리 오브젝트의 양이 정해져 있기 때문에, 이는 전적으로 불필요한 작업입니다. 현재 씬 (scene)에 있는 모든 물리 오브젝트를 한꺼번에 시뮬레이션하고 있기 때문입니다. [music] 저는 현재 씬에 있는 모든 물리 리지드 바디 (rigid bodies)를 가져와서 언제든 캐시된 참조 (cached reference)를 가질 수 있도록 해주는 'my scene physics manager'라는 작은 도구를 가지고 있습니다.

여기 있는 모든 리지드 바디를 정지(freeze)시키면 어떤 일이 일어나는지 살펴보겠습니다. 보시다시피 프레임 타임 (frame time)이 상당히 떨어집니다. 이는 매우 엄청난 차이이며, 우리가 실제로 해야 할 일은 플레이어의 범위를 벗어난 모든 것이 궁극적으로 꺼지도록 하여 물리 시뮬레이션 (physics simulation) 대상에서 제외되게 하고, 오직 소수의 선택된 오브젝트 그룹만이 매 순간 물리 계산 대상이 되도록 만드는 것뿐임을 의미합니다. 플레이어 뒤에 있는 것들은 플레이어가 볼 수 없으므로 시뮬레이션할 이유가 없으며, 맵의 다른 구역 밖에 있는 것들도 마찬가지로 볼 수 없습니다.

최적화 (optimization) 목적 측면에서도 그런 것들을 시뮬레이션하는 것은 의미가 없습니다. [music] 이것이 멀티플레이어 게임이라 하더라도, 게임 내의 모든 플레이어 캐릭터에 대해 이 작업을 수행해야 한다는 뜻이지, 실제로 우리가 커버해야 할 거리 자체는 아마 상대적으로 작을 것입니다. 우리는 시뮬레이션 횟수를 약 1,300개에서 최대 몇 백 개 정도로 낮추게 될 것입니다. 이것은 매우 매우 간단한 스크립트입니다. 본질적으로, 우리는 씬의 루트 (root)에 위치할 정적 매니저 (static manager)를 가질 뿐입니다.

우리는 리지드 바디 (rigid bodies) 리스트를 가지고 있습니다. 나중에 이것을 해시 셋 (hash set)으로 바꿀 예정입니다. 지금 당장은 크게 걱정하지 않지만, 사실상 그리고 가시성을 위해, 이것은 그냥 리지드 바디 리스트입니다. 어, 그리고 최대 거리 (max distance) 값도 있습니다. 또한 우리는 인스턴스화 (instantiation) 시점에 스스로를 등록할 수 있는 타겟들의 해시 셋 (hash set)도 가지고 있습니다. 그러니까, 본질적으로 이것은 멀티플레이어 게임이기 때문에, 저는 물리 (physics)가 게임 내의 모든 플레이어 주변에서 작동하도록 보장하고 싶고, 그래서 그들이 이 계산에 포함되도록 확실히 하고 싶습니다.

하지만 여러분이 만약 싱글 플레이어 게임을 만든다면, 플레이어인 단 하나의 오브젝트만 있으면 됩니다. 하지만 이런 방식으로 구현하면 확장 가능한 (scalable) 방식으로 작동할 것입니다. 네, 우리는 오브젝트들이 스스로를 등록할 수 있게 허용하며, 이것은 제 차량 컨트롤러 (vehicle controller)에 구현되어 있습니다. 그래서 제 차량이 씬 (scene)에 스폰 (spawn)될 때, 물리 매니저 (physics manager)가 존재하는지 확인하고 스스로를 등록하며, 씬에서 비활성화될 때는 스스로를 등록 해제 (deregister)합니다. [music] 그래서 우리가 플레이 가능한 캐릭터, 즉 여기 있는 차량 컨트롤러 스크립트를 스폰할 때마다, 그 스크립트는 그 작업만 수행합니다.

네, 꽤 간단합니다. 에디터에서 몇 가지 단축키를 사용할 수 있게 해주는 작은 에디터 툴 버튼 같은 것이 있습니다. 여러분이 보신 버튼들이 바로 거기서 나온 것입니다. 관심 있으시다면 말씀드리는데, 그것은 본질적으로 에디터 내부에서 메서드 (methods)를 자동으로 실행할 수 있게 해줍니다. 그래서 에디트 타임 (edit time)에, 제가 신경 써야 하는 씬 안의 모든 바디 (bodies)들을 가져옵니다. 저는 이미 키네마틱 (kinematic)으로 설정되지 않은 것들에 집중합니다. 그것들은 곧 다이내믹 (dynamic) 오브젝트라는 뜻인데, 왜냐하면 별도로 처리되는 것들이 몇 가지 있기 때문입니다.

그래서 저는 이 모든 것들을 가져와서 제 씬 바디 (scene bodies)에 할당합니다. 그런 다음, Fixed Update (고정 업데이트)에서 eval distance (거리 평가) 메서드를 실행합니다. 기본적으로 우리는 최대값을 설정합니다. 모든 플레이어 캐릭터를 확인하며, 그들과의 리지드 바디 (rigid body) 거리를 비교합니다. 만약 우리가 설정한 최소 거리 이내에 있다면, 키네매틱 (kinematic) 상태를 비활성화하고 충돌 감지가 이루어지도록 합니다. 만약 거리 밖에 있다면, 리지드 바디를 비활성화하고 충돌 감지를 중단합니다. 보시는 것처럼, 저희 차량을 스크립트에 등록했습니다.

이제 물리 엔진의 오버헤드 (overhead)는 훨씬 낮아졌습니다. 현재는 단 하나의 다이내믹 (dynamic) 바디만을 실제로 시뮬레이션하고 있기 때문입니다. 정말 간단합니다. 보시다시피, [music] 물리 시뮬레이션 자체를 중단시키지는 않습니다. 왜냐하면 우리가 가까이 다가가면 그것들이 활성화되기 때문입니다. 실제로 멀리 떨어져 있는 오브젝트들은 비활성화되어 있습니다. 하지만 보시는 것처럼 우리가 그들에게 가까이 운전해 가면 다시 켜지게 됩니다. 여기서 후진을 해보면, 다시 토글 (toggle)되어 켜지는 것을 볼 수 있을 것입니다. 따라서 이 스크립트는 매우 단순하지만, 특히 물리 연산을 다루고 있다면 여러분에게 엄청난 최적화 오버헤드 (optimization overhead) 이득을 줄 수 있는 스크립트입니다.

여러분이 어떤 종류의 게임을 만들고 있든 상관없습니다. 작은 환경의 소규모 싱글 플레이어 게임이든, 거대한 대규모 오픈 월드(open-world) 형태든, >> [music] >> 이런 종류의 스크립트는 여러분의 게임에서 반드시 실행되도록 하고 싶을 것입니다. 이 스크립트 하나만으로도 빌드된 상태에서 초당 약 40프레임(FPS)으로 실행되던 싱글 플레이어 모드가 제 노트북에서 약 80~90프레임 정도로 올라갔으며, 이는 결과적으로 분할 화면(split screen)을 위해 여러 대의 카메라가 게임을 렌더링할 때의 성능을 크게 향상시킵니다.

이번 주말 이벤트를 위해 제 노트북에서 여유 성능(headroom)을 조금이라도 더 짜낼 수 있는지 최적화 작업을 다시 진행해 볼 예정입니다만, 여러분의 생각은 어떤지 아래 댓글로 알려주세요. 여러분이 공유하고 싶은 자신만의 물리 최적화 (physics optimizations) 방법이 있나요? 저는 매우 관심이 있으며, 시청 중인 다른 분들도 알고 싶어 할 것이라 확신합니다. 그리고 이 영상이 도움이 되었는지도 알려주세요. 영상이 즐거우셨다면 좋아요 버튼을 눌러주세요. 채널이 처음이시라면 구독도 고려해 주세요. 새로운 영상이 올라올 때 알림을 받으실 수 있습니다.

아니면 제 영상을 더 먼저 보고 싶으시다면, 지금 화면에 나오는 영상 중 하나를 확인해 보세요. 언제나 그렇듯, [music] 시청해 주셔서 정말 감사드리며 다음 시간에 다시 뵙겠습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 YouTube Game Dev Guide의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0