[Unity] 특정 Component 삭제법.

2022. 7. 18. 13:02[Unity] 게임 개발

반응형

Object Pooling을 고도화 하던 중 Type에 따라 Collider의 종류가 다르게 들어가야 하는 경우를 마주 하였다.

 

이때 이전에 들고 있던 Collider를 삭제 해주고 새로운 Collider를 넣어주기 위해서 Destroy문을 사용 중 특이점을 발견하였다.

 

Destroy Component 코드.

 if (this.GetComponent<Collider2D>() != null)
 {
    preCollider = this.GetComponent<Collider2D>();
    Destroy(preCollider);
 }

해당 Destroy문으로 특정 Component를 검색하여 삭제시켜주는 것이 일반적인 방법이다.

하지만 불규칙이 존재하였다. AddComponent 구문과 함께 사용할때 문제가 생겨났다.

 

문제 발생 코드.

        if (this.GetComponent<Collider2D>() != null)
        {
            preCollider = this.GetComponent<Collider2D>();
            Destroy(preCollider);
            
            gameObject.AddComponent<PolygonCollider2D>(); // => 불규칙 조건 발생.
        }

정확한 원인은 모르겠지만 Destroy문이 동작 할때 Add가 되면서 밑단의 GC에서 불규칙 조건이 생겨나는 것 같다.

 

해결방법 1.

        if (this.GetComponent<Collider2D>() != null)
        {
            preCollider = this.GetComponent<Collider2D>();
            DestroyImmediate(preCollider);

            gameObject.AddComponent<PolygonCollider2D>();
        }

해결 방법으로 첫번째는 Destroy문 대신 DestroyImmediate문을 사용해주는 방법이다.

DestroyImmediate 문은 해당 게임 개체에 대한 모든 참조를 즉시 null로 설정하고 Destroy() 함수처럼 프레임이 끝날때 까지 기다는 것이 아니라 즉시 삭제를 진행한다. 때문에 사용에 매우 주의하여야 한다.

 

해결방법 2.

        if (this.GetComponent<Collider2D>() != null)
        {
            
            preCollider = this.GetComponent<Collider2D>();
            preColliderName = preCollider.GetType().ToString();
            Destroy(GetComponent(nameof(preColliderName)));

            gameObject.AddComponent<PolygonCollider2D>();
        }

  해결 방법 두번째로는 string으로 compnent에 접근 후 삭제하는 것이다. 정확한 차이는 필자도 잘 모르겠다. 불규칙 없이 잘 동작한다.

 

 

결론 : Unity 개발자라면 Pooling 과정에서 비슷한 고민이 생길 것이다. 필자는 결론적으로 Pooling을 고도화 하면서 Destroy문을 사용하는 것이 마음에 들지 않아서 Prefab을 쪼개서 Pooling하는 것으로 노선을 변경하였다. 하지만 그 과정에서 공부한 내용을 정리해 놓겠다.

반응형