Unity

Unity : tag 확인 시 == 가 아니라 CompareTag 를 사용하라

Sorting 2020. 12. 14. 01:32
반응형

 

유니티 게임 오브젝트의 tag를 체크하여, tag에 따라 다른 동작을 해주려고 할 때

tag를 체크하는 코드를 다음과 같이 작성했더니 경고 메세지가 떴다.

 

// 1. equality operator 로 비교
if (gameObject.tag == "MyTag")
{
    // do something...
}

경고 메세지는 다음과 같았다.

info UNT0002: Comparing tags using == is inefficient.

equality operator 로 비교하는 것은 비효율적이라고 한다.

 

대안이 있을 것 같아서 조금 찾아보니,

다음과 같이 CompareTag() 로 비교하는 것이 조금 더 효율적이라고 한다.

// 2. CompareTag 메소드로 비교
if (gameObject.CompareTag("MyTag"))
{
    // do something...
}

둘의 차이가 무엇이길래 효율면에서 차이가 날까?

 

이 차이는 GameObject 의 tag 가, 멤버변수가 아닌 프로퍼티임으로부터 나오는 차이로 보인다.

tag 는 멤버변수가 아니라 프로퍼티다

위 프로퍼티의 getter 가 호출되는 순간, string 을 복사 생성한다고 한다.

이는 곧, 메모리 할당 및 복사로 인한 부하를 야기하고, GC 의 일거리를 하나 늘어나도록 만든다.

 

(추측컨데, GameObject의 tag 는 내부적으로는 별도의 integer/hash 값으로 저장되어 있고

사용자가 tag 프로퍼티를 통해 string 을 get 할 때에는

별도의 테이블로부터 string을 복원/복사해서 리턴하는 형태가 아닐까 싶다.)

 

CompareTag() 함수는 동적할당 없이 tag 비교가 가능하도록 구현된 메소드라 효율적이다.

"Unity 5 Game Optimization by Chris Dickinson" 에 의하면 27%의 성능 향상 효과를 볼 수 있다고 한다.

(전달받은 string 파라미터에서 hash 값을 생성하여 비교하는 형태일까?)

 

또, CompareTag() 와 == 사이에는 중요한 차이점이 하나 더 있는데,

CompareTag() 는 인자로 전달받은 string 이 실제로 존재하는 태그인지 확인하는 동작까지 포함한다.

존재하지 않는 태그를 CompareTag() 함수로 비교할 경우 다음과 같은 에러가 발생한다.

 

존재하지 않는 태그를 CompareTag()로 체크했을 때

 

오타, 혹은 리팩토링 간 삭제된 태그를 오용하는 경우까지 체크가 가능할 것으로 보인다.

 

성능 면에서도, 안정성 면에서도

CompareTag() 함수를 사용하지 않을 이유가 없는 것 같다.

 

Visual Studio refactor 기능은 Alt + Enter 를 통해

== / != 를 CompareTag() 로 자동변경해주는 기능을 제공하고 있으니 십분 활용하면 좋겠다.

 

 

참조 :

github.com/JetBrains/resharper-unity/wiki/Use-CompareTag-instead-of-explicit-string-comparison

answers.unity.com/questions/200820/is-comparetag-better-than-gameobjecttag-performanc.html

 

반응형