• 티스토리 홈
  • 프로필사진
    SiJun-Park
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
SiJun-Park
  • 프로필사진
    SiJun-Park
    • 분류 전체보기 (190)
      • Unity (148)
        • 출시 해보기 (Slime Company) (3)
        • 뱀서류 Project (34)
        • Defense Project (20)
        • FPS Project (30)
        • RPG Project (39)
        • 기타 - 개발 (22)
      • 개발 (35)
        • 임베디드 소프트웨어 (7)
        • 컴파일러 (6)
        • 기계학습 (8)
        • 보안 (8)
        • 그래픽스 (2)
        • 그 외 (4)
      • 코딩문제 (6)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • GetComponent 공부 기록
        2025년 12월 30일
        • SiJun-Park
        • 작성자
        • 2025.12.30.:35

        " GetComponent는 기본 아니냐? " 이 생각을 저도 하였었고, 그냥 무심코 GetCompnent를 사용하고 있었습니다.

         

        그러다 공부를 계속 하다가 그게 아니라는 것을 알았습니다.

        왜?

        Component의 저장 구조는 배열로 관리를 하고 있습니다.

        *인터페이스는 Component가 아닙니다.

         

        그래서 내부적으로 어떻게 동작을 하는지 보면

         

        foreach (component in components)
        {
            if (component.GetType() == Monster)
                return component;
        }

         

        위 처럼 타입 비교가 아주 단순합니다. 

        상대적으로 빠르구요

         

        그런데 문제는 GetComponent<IDamageable>()을 하였을 경우 입니다.

        foreach (component in components)
        {
            if (component is IDamageable)
                return (IDamageable)component;
        }

        이렇게 됩니다.

         

        위에서 언급을 하였듯이 인터페이스는 엔진 레벨 타입이 아닙니다.

        그래서 유니티 Native 쪽엔 Idamageble이 존재하지 않기 때문에

        전부 C# 리플렉션 + is 검사를 하게 됩니다.

         

        매 컴포넌트마다 인터페이스 테이블을 탐색하게 되고, 캐스팅을 하게 됩니다.

        그래서 컴포넌트가 많을수록 비용이 증가하게 됩니다.

         

        즉 인터페이스 기반 조회는 내부적으로 타입 체크/캐스팅 비용이 더 들 수 있어, 빈번한 호출(Update 등)에서는 캐싱/이벤트 구조가 유리합니다.

        그래서 해결 방법은?

        TryGetComponent을 사용해서 해결을 할 수 있습니다.

        if (other.TryGetComponent(out IDamageable d))
        {
            d.TakeDamage(10);
        }

        이렇게 한다면, GC alloc가 생길 가능성이 제거가 됩니다.

         

        GetComponent<T>는 실패 시 null이 되고 내부적으로 비용이 큰 경로를 타는 문제가 있었으나

        TryGetComponent<T>는 처음부터 성공/실패 분기며 예외/후처리가 없습니다.

         

        또한 Native -> Managed 왕복을 최소화 합니다.

        GetComponent는 Native -> Managed 변환 , 타입 캐스팅, null 체크 

        TryGetComponent는 분기 포함 API, 실패 시 바로 return false, 불필요한 변환 최소화를 합니다.

         

        그러면 인터페이스를 쓰지 말라는 거냐?

        절대 아닙니다. 쓰는 위치가 중요합니다.

         

        void Update()
        {
            var d = other.GetComponent<IDamageable>();
            if (d != null)d.TakeDamage(1);
        }

         

        예로들어서 위 처럼 한다면 아까 위에 말했던 리플렉션 + is 검사를 수시로 하게 됩니다.

        void OnTriggerEnter(Collider other)
        {
            if (other.TryGetComponent(out IDamageable d))
            {
                d.TakeDamage(10);
            }
        }

        그래서 위 처럼 이벤트 기반에는 TryGetComponent가 좋습니다.

         

        즉 자주 호출되느냐가 관건입니다.

         

         

        'Unity > 기타 - 개발' 카테고리의 다른 글

        foreach / Animator 최적화 공부 기록  (0) 2026.01.01
        Transform 그리고 StopAllCoroutines 공부 기록  (1) 2026.01.01
        Coroutine 공부 기록  (0) 2025.12.30
        Heap과 Stack에 대해 공부  (0) 2025.12.21
        Text와 TextMeshPro 공부  (0) 2025.12.20
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바