프로그래밍/Unity

유니티에서 특정 오브젝트 찾기 #03 : 성능 최적화

selinatsu 2024. 10. 19. 15:10
반응형

FindObjectsOfType<GameObject>()를 사용하면, 이미 씬에 존재하는 모든 게임 오브젝트를 한 번에 다 가져오는 것이기 때문에, 결국 성능 최적화 측면에서 비효율적입니다.

즉, 모든 오브젝트를 메모리에 로드한 후에 다시 필터링을 하는 방식이므로, 성능 최적화는 이미 깨진 상태라고 할 수 있습니다.

 

문제점

FindObjectsOfType<GameObject>()는 씬에 있는 모든 게임 오브젝트를 메모리로 로드하고 나서, 그 중에서 조건을 확인하는 방식이기 때문에, 불필요한 오브젝트들도 로드됩니다.

이런 방식은 특히 씬에 오브젝트가 많을 때 성능에 큰 영향을 미칠 수 있습니다.

 

최적화가 깨지지 않는 대안

레이어를 기준으로 성능을 최적화하려면, 모든 오브젝트를 일일이 로드하지 않고, 처음부터 필터링된 오브젝트들만 검색하는 방식으로 전환해야 합니다.

Unity는 기본적으로 레이어 기반으로만 오브젝트를 검색하는 함수는 제공하지 않기 때문에, 대안적인 방법을 사용해야 합니다.

 

더 나은 대안 1

태그를 이용한 최적화

가장 간단한 방법은 태그를 사용하는 것입니다. 태그를 이용하면 Unity가 내부적으로 성능 최적화된 검색을 수행하므로, 특정 태그에 해당하는 오브젝트들만 검색됩니다.

 

GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");

 

이 방식은 이미 성능이 최적화되어 있으며, 씬에 있는 모든 오브젝트를 탐색하지 않고, "Enemy" 태그가 지정된 오브젝트들만 바로 가져옵니다. 태그를 사용할 수 있는 상황이라면, 이 방법이 최선입니다.

 

더 나은 대안 2

물리적 검사에서 레이어 마스크 활용

레이어를 기준으로 특정 오브젝트를 찾고자 할 때는, 레이어 마스크를 사용하는 물리적 검사가 성능 최적화에 매우 효과적입니다. 레이캐스트나 충돌 검사에서 처음부터 특정 레이어에 속한 오브젝트들만 검사하도록 할 수 있습니다.

 

// "Enemy" 레이어에 속한 오브젝트만 검색

int layerMask = LayerMask.GetMask("Enemy");  
RaycastHit[] hits = Physics.RaycastAll(ray, maxDistance, layerMask);

foreach (var hit in hits)
{
    Debug.Log("Enemy 레이어 오브젝트 발견: " + hit.collider.gameObject.name);
}

 

 

이 방식은 처음부터 "Enemy" 레이어에 속한 오브젝트만 검사하므로, 불필요한 오브젝트는 아예 고려되지 않아 성능이 크게 향상됩니다. 레이캐스트나 충돌 검사 같은 물리 연산에서 레이어 마스크를 활용하면 성능 최적화에 매우 유리합니다.

 

 

요약

FindObjectsOfType<GameObject>()는 씬의 모든 오브젝트를 가져오므로, 성능 최적화에 부정적입니다.

 

최적화된 방식으로는 태그를 사용하는 GameObject.FindGameObjectsWithTag()나, 레이어 마스크를 사용하는 물리적 검사 (예: Raycast) 를 활용하는 것이 좋습니다.

 

처음부터 필터링된 오브젝트만 검색하는 것이 성능에 더 유리하며, 모든 오브젝트를 한 번에 로드하는 방식은 피하는 것이 좋습니다.

 

결론적으로, FindObjectsOfType<GameObject>() 방식은 성능 최적화에 적합하지 않으므로, 태그나 레이어 마스크를 사용하는 방법이 더 효율적입니다.

 

 

 

반응형