기본 패턴
csharp
GameObject player = gameObject;
Transform tr = player.transform;
Rigidbody body = player.GetComponent<Rigidbody>();설명
GameObject는 씬 안의 "존재 자체"이고,Component는 그 존재에 붙는 기능 단위입니다. 그리고Transform은 모든 GameObject가 기본으로 가지는 위치/회전/스케일 컴포넌트입니다.- 그래서 Unity를 읽을 때는 "GameObject가 무엇을 갖고 있는가"보다 "이 GameObject에 어떤 Component가 붙어 있는가"로 생각하는 편이 자연스럽습니다.
Transform은 특별합니다. 일반 컴포넌트처럼 보이지만 계층 구조와 공간 좌표의 중심이라서 사실상 모든 시스템의 출발점 역할을 합니다.Rigidbody,Collider,AudioSource,Button, 사용자 스크립트는 모두 같은 컴포넌트 계열이지만, 붙는 대상과 책임이 다릅니다. Unity 설계는 이 조합으로 만들어진다고 보면 됩니다.- 이 기본 mental model이 잡히면
GetComponent,[SerializeField], 프리팹, 인스펙터 연결, 활성화 상태 같은 카드가 훨씬 덜 따로 노는 느낌으로 읽힙니다.
어떻게 읽어야 하는가
GameObject는 컨테이너이자 계층 노드입니다. 이름, 활성 상태, 태그, 레이어, 그리고 붙어 있는 컴포넌트들의 묶음이라고 보면 됩니다.Component는 기능 단위입니다. 같은 GameObject에 물리, 오디오, 렌더링, 사용자 로직이 함께 붙을 수 있는 이유도 이 컴포넌트 모델 덕분입니다.Transform은 단순히 위치 값 하나가 아니라 parent-child 관계까지 포함합니다. 그래서 좌표계 문제를 볼 때는 "월드 좌표인가, 로컬 좌표인가, 어떤 부모 아래에 있는가"를 같이 봐야 합니다.MonoBehaviour는 결국 사용자 스크립트도 컴포넌트라는 사실을 드러냅니다.this는 오브젝트 전체가 아니라 "현재 붙어 있는 컴포넌트"를 가리킨다는 감각이 중요합니다.- Unity 코드를 읽을 때는 항상 "이 메서드는 GameObject를 대상으로 하는가, 특정 Component를 대상으로 하는가, 아니면 Transform 공간을 다루는가"를 먼저 구분하면 혼란이 크게 줄어듭니다.
짧은 예제
csharp
public class PlayerMover : MonoBehaviour
{
private Rigidbody body;
private void Awake()
{
body = GetComponent<Rigidbody>();
}
}빠른 정리
| 개념 | 역할 |
|---|---|
GameObject | 씬 안의 존재, 컨테이너 |
Component | 기능 단위 |
Transform | 위치, 회전, 스케일, 계층 구조 |
| 사용자 스크립트 | 직접 만든 컴포넌트 |
| 읽는 기준 | "이 오브젝트에 어떤 컴포넌트가 붙어 있는가?" |
자주 하는 실수
| 코드 | 실제 의미 |
|---|---|
Destroy(this) | 현재 컴포넌트만 제거 |
Destroy(gameObject) | 오브젝트 전체 제거 |
enabled = false | 현재 Behaviour 컴포넌트만 비활성화 |
gameObject.SetActive(false) | 오브젝트와 자식 전체 활성 흐름 중단 |
transform.position | 월드 좌표 |
transform.localPosition | 부모 기준 로컬 좌표 |
주의할 점
Unity 입문자 버그 상당수는 GameObject와 Component를 같은 것으로 생각하면서 생깁니다.
Destroy(this)는 현재 컴포넌트만 지우고, Destroy(gameObject)는 오브젝트 전체를 지운다는 차이부터 먼저 익혀 두면 실수가 크게 줄어듭니다.
참고 링크
3 sources