게임엔진/Unity

Unity)Tag 사용 없이 오브젝트 찾기

LongRunnner 2024. 10. 3. 15:21

오브젝트 찾을 때 Tag를 많이 사용하곤 했다. 그러나 단점도 있다.

특정 게임 오브젝트를 찾을 때 나는 오브젝트들마다 다른 Tag를 생성 및 부착해서
FindObjectWithTag() 메서드를 통해 오브젝트들을 찾고 분류하기 했다.
물론 이 방법은 쉬운 방법이고 접근하기가 쉽다.

다만 인턴 기간동안 다른 팀과의 프로젝트 통합 과정에서 다른 프로젝트도 여러 Tag를 사용했고,
한 프로젝트로 통합하기 위해선 결국 Tag를 통일해야 했고,
자잘한 개인 Tag들을 삭제 해야 하는 고통을 겪었다.

거기서 가장 큰 고통은, Tag 분류들을 아이템의 종류별로 Tag를 나누었는데
통합 과정에서 아이템 모두를 'Item' 으로 통일할 수 밖에 없었고,
시스템으로 Tag를 분류해서 아이템을 구별했지만 결국은 시스템을 다시 구축해야 했다.

여기서 겪은 경험을 바탕으로 Tag 사용을 최소화 및 현명한 방법들을 정리하고자 한다.

 

1. Tag 분류는 최대한 적게, 사전에 다른 사람과 협의가 먼저

개인 프로젝트에서 Tag를 사용하는 것은 자유다. Tag 수가 많아도 개인이 기억하는것이나 분류하는 것도
결국 개인의 몫이고 어떻게 사용할지는 본인의 역량에 달려있다.

다만, 다른 팀원 및 다른 팀과 함께 프로젝트를 만들게 된다면 더 까다롭게 된다.

Tag 사용이 남발하고 무분별한 Tag들이 많아진다면, 프로젝트 통합 과정에서 Tag 이름 중복 때문에 
예기치 못한 버그나 오류가 나올 수 있다.

따라서, 내 경험상으론 Tag 사용은 최소화하되, 공통으로 사용될 Tag는 사전 협의를 통해 정해야 한다.

물론 초기 개발에서는 개발 진행 없어 Tag를 어떻게 협의해야 할지 감이 안잡힐 수 있다.
다만 프로젝트 통합 단계에선(다른 팀과의 프로젝트를 합쳐서 하나의 프로젝트로 만들시)
실질적으로 공통 Tag를 정해야 하는 어쩔 수 없는 과정을 거치기 때문에, 
아까 말했던 Tag 사용을 최소화 해야 한다는 조건이 바로 이것이다.

 

인턴 경험에서 Tag로 아이템을 분류한 적이 있었다. 통합 단계에서 Tag 정리를 위해

종류별로 나누었던 Tag를 한 개로 정해야 할 때, 과연 아이템 종류를 어떻게 나누어야 하는 방법에 대해

경험으로 배운 것을 알려주고자 한다.

2. 같은 종류의 스폰 오브젝트는 한 배열, 리스트 안에 정리

한 종류의 수많은 오브젝트들이 게임 씬 상에 스폰이 되어 있다면, 예를 들어 코인 프리팹이 스폰되어 있을때
이 코인들을 접근하기 위해서 Tag를 통해 FindObjectWithTag() 메서드를 사용했었다.

만일 Tag 접근 Find 메서드를 사용하지 못하는 순간이 올때, 이 스폰된 코인 프리팹들을 접근하기 위해선

나의 경우, 스폰된 프리팹들을 싱글톤화한 GameManager 오브젝트과 게임매니저 컴포넌트 스크립트 안에
리스트를 만들어서 그곳에 프리팹들을 추가 및 제거 했었다. 

  1. 싱글톤화한 GameManager는 다른 스크립트에서 접근이 쉽기 때문에, GameManager에 게임오브젝트 타입 리스트를
    만들고, 리스트에 오브젝트 추가 및 제거 메서드를 정의하였다.
  2. 프리팹이 스폰되어 생성될 때, 해당 프리팹의 Start() 메서드에 게임매니저의 리스트로 스폰된 자기 자신을 추가하는 메서드를 작성해, 리스트에 추가시킨다.
  3. 프리팹이 삭제, Destroy()가 된다면, 리스트에서도 제거를 해야 한다. 안하면 리스트 안에는 자기 자신이 파괴되어도 Missing으로 남게 되어서 무분별한 메모리를 낭비하게 된다. 따라서 GameManager에 정의한 제거 메서드를 통해,
    자기 프리팹의 OnDestroy() 메서드 안에 제거 메서드를 작성해서, 리스트의 완전한 삭제를 하면 된다.
  4. 스폰된 오브젝트들에 접근하고 싶다면, GameManager의 스폰된 프리팹 리스트를 통해 오브젝트들을 관리하면 된다

3.  오브젝트 안에 Enum 타입 변수를 정의해 분류하는 방법도 있다.

Tag 사용 중에서 onCollision이나 onTrigger 메서드를 통해 Tag 분류를 통해 오브젝트는 구별하는 쉬운 방법이 있다.

만일 Tag 사용이 제한된다면, 충돌한 오브젝트의 컴포넌트에 접근해서 사전에 정의한 Enum 타입에 접근해

구별시키는 방법이 있다.

EX) other.gameObject.GetComponent<'오브젝트 컴포넌트'>().ItemClass == ItemEnum.Coin