빠른 비교
csharp
gameObject.SetActive(false);
renderer.enabled = false;
bool self = gameObject.activeSelf;
bool active = gameObject.activeInHierarchy;갈리는 기준
SetActive(false)는 GameObject 전체를 비활성화합니다. 그 오브젝트와 자식 오브젝트의 컴포넌트 업데이트, 렌더링, 충돌 참여가 함께 멈추는 쪽에 가깝습니다.enabled = false는 특정Behaviour나Renderer같은 컴포넌트만 끄는 방식입니다. 오브젝트 자체는 살아 있고, 다른 컴포넌트는 계속 동작할 수 있습니다.activeSelf는 "이 오브젝트 자신이 켜져 있는가"를,activeInHierarchy는 "부모 포함 실제 계층 기준으로 지금 활성인가"를 보여 줍니다.- 그래서 부모가 꺼져 있으면 자식의
activeSelf는true여도activeInHierarchy는false일 수 있습니다. 이 차이를 모르고 디버깅하면 왜 안 보이고 왜 안 도는지 헷갈리기 쉽습니다. SetActive는OnEnable/OnDisable같은 라이프사이클에도 직접 영향을 주므로, 단순 렌더링 on/off와는 다른 강한 도구라고 생각하는 편이 좋습니다.
선택 기준
| 상황 | 적합한 선택 |
|---|---|
| 오브젝트 전체를 끄고 싶을 때 | gameObject.SetActive(false) |
| 렌더러·스크립트 하나만 끄고 싶을 때 | component.enabled = false |
| 자신의 활성 플래그만 확인 | activeSelf |
| 부모 포함 실제 활성 상태 확인 | activeInHierarchy |
| 화면에서 숨기되 Update는 유지 | renderer.enabled = false |
| 제어 대상 | 더 잘 맞는 선택 | 이유 |
|---|---|---|
| 게임오브젝트 전체 수명주기 | SetActive | 자식과 메시지 함수까지 같이 멈춤 |
| 특정 컴포넌트 기능만 일시 중단 | enabled = false | 나머지 로직은 유지 가능 |
| 디버깅 중 "내가 켰는가" 확인 | activeSelf | 자신의 플래그만 봄 |
| 디버깅 중 "실제로 동작 가능한가" 확인 | activeInHierarchy | 부모 영향까지 포함 |
주의할 점
renderer.enabled = false는 안 보이게만 할 뿐, Update와 충돌은 그대로 동작합니다.
csharp
// ❌ 렌더러만 끔 — Update·Collider·스크립트는 계속 실행됨
renderer.enabled = false;
// ✅ 오브젝트 전체를 멈추려면 SetActive
gameObject.SetActive(false); // OnDisable 호출, Update 중단, 충돌 비참여
// ✅ 렌더링만 숨기되 로직은 유지하려면 renderer
renderer.enabled = false; // Update는 유지, 화면에서만 사라짐부모가 꺼져 있는 자식 오브젝트를 activeSelf == true만 보고 활성이라고 판단하면 디버깅이 꼬입니다. 실제 동작 가능 여부는 activeInHierarchy로 확인하세요.
csharp
// 부모 비활성
parent.SetActive(false);
// 자식은 자기 플래그만 보면 true일 수 있음
child.activeSelf == true;
child.activeInHierarchy == false;
// 실제로는 Update도 렌더링도 돌지 않음참고 링크
4 sources