Unity의 GameObject 클래스는 씬에 존재할 수 있는 모든 것을 나타냅니다. 게임 오브젝트는 Unity에서 씬의 구성 요소이며, 게임 오브젝트의 모양과 기능을 결정하는 기능적 컴포넌트의 컨테이너 역할을 합니다.
GameObject 클래스는 코드에서 게임 오브젝트로 작업할 수 있는 메서드 컬렉션을 제공합니다. 여기에는 게임 오브젝트 간의 검색, 연결, 메시지 전송, 게임 오브젝트에 연결된 컴포넌트 추가 또는 제거, 씬 내 상태와 관련된 값 설정 등의 메서드가 포함됩니다.
GameObject 클래스의 모든 멤버에 대한 전체 레퍼런스는 게임 오브젝트 스크립트 레퍼런스를 참조하십시오.
Unity 에디터의 씬 및 계층 구조에서 게임 오브젝트 사용에 대한 자세한 내용은 게임 오브젝트 소개를 참조하십시오.
모든 게임 오브젝트는 씬 내 게임 오브젝트 상태와 관련하여 인스펙터 상단의 컨트롤 세트를 공유하며, 게임 오브젝트의 스크립팅 API를 통해 제어할 수 있습니다.
게임 오브젝트는 기본적으로 활성화되지만, 비활성화하여 게임 오브젝트에 연결된 모든 컴포넌트를 끌 수 있습니다. 이렇게 하면 일반적으로 보이지 않게 되며, Update 또는 FixedUpdate 같은 일반적인 콜백이나 이벤트를 수신하지 않습니다.
게임 오브젝트의 활성 상태는 게임 오브젝트의 이름 왼쪽에 있는 체크박스로 표시됩니다. GameObject.SetActive를 사용하여 제어할 수 있습니다.
GameObject.activeSelf를 사용하여 게임 오브젝트의 현재 활성 상태를 읽을 수도 있습니다. 게임 오브젝트가 씬에서 실제로 활성 상태인지 확인하려면 GameObject.activeInHierarchy를 사용합니다. 게임 오브젝트가 실제로 활성 상태인지 여부는 게임 오브젝트의 자체 활성 상태와 모든 부모의 활성 상태에 따라 결정되기 때문에 GameObject.activeInHierarchy가 필요합니다. 부모 중 하나가 활성화되어 있지 않으면 게임 오브젝트가 활성화된 설정에도 불구하고 활성화되지 않습니다.
전역 조명, 오클루전, 배칭, 내비게이션, 반사 프로브 같은 Unity의 일부 시스템은 게임 오브젝트의 정적 상태에 의존합니다. GameObjectUtility.SetStaticEditorFlags를 사용하여 Unity의 시스템에서 게임 오브젝트를 정적으로 간주하도록 제어할 수 있습니다. 자세한 내용은 정적 게임 오브젝트를 참조하십시오.
태그는 씬에서 게임 오브젝트 유형을 표시 및 식별하는 방식을 제공하고, 레이어는 렌더링 또는 물리 충돌 같은 특정 빌트인 동작에 게임 오브젝트 그룹을 포함하거나 제외하는 유사하면서도 차별화된 방식을 제공합니다.
에디터에서 태그와 레이어를 사용하는 방법에 대한 자세한 내용은 메인 사용자 매뉴얼 페이지의 태그와 레이어를 참조하십시오.
GameObject.tag 및 GameObject.layer 프로퍼티를 사용하여 스크립트를 통해 태그 및 레이어 값을 수정할 수 있습니다. 또한 CompareTag 메서드를 사용하여 게임 오브젝트의 태그를 효율적으로 확인할 수 있습니다. 여기에는 태그 존재 여부 확인이 포함되며 메모리 할당이 발생하지 않습니다.
런타임 시 컴포넌트를 추가하거나 제거할 수 있습니다. 이는 절차적으로 게임 오브젝트를 생성하거나 게임 오브젝트의 동작 방식을 수정하는 데 유용할 수 있습니다. 스크립트 컴포넌트와 일부 빌트인 컴포넌트 유형을 제거하지 않고도 스크립트를 통해 enable 또는 disable에 사용할 수 있습니다.
런타임 시 컴포넌트를 추가하는 가장 좋은 방법은 AddComponent<Type>를 사용하여 꺾쇠 괄호 안에 컴포넌트 유형을 지정하는 것입니다. 컴포넌트를 제거하려면 컴포넌트 자체에 Object.Destroy 메서드를 사용해야 합니다.
가장 간단한 경우는 게임 오브젝트의 스크립트가 동일한 게임 오브젝트에 연결된 다른 컴포넌트에 액세스해야 하는 경우입니다(게임 오브젝트에 연결된 다른 스크립트도 컴포넌트 자체임). 이렇게 하기 위한 첫 번째 단계는 작업하려는 컴포넌트 인스턴스에 대한 레퍼런스를 가져오는 것입니다. 이 작업은 GetComponent 메서드로 수행됩니다. 일반적으로 컴포넌트 오브젝트를 변수에 할당하는데 이 작업은 다음 코드를 사용하여 수행됩니다. 이 예시에서 스크립트는 동일한 게임 오브젝트의 Rigidbody 컴포넌트에 대한 레퍼런스를 가져옵니다.
void Start ()
{
Rigidbody rb = GetComponent<Rigidbody>();
}
컴포넌트 인스턴스에 대한 레퍼런스가 있으면 인스펙터에서와 마찬가지로 프로퍼티 값을 설정할 수 있습니다.
void Start ()
{
Rigidbody rb = GetComponent<Rigidbody>();
// Change the mass of the object's Rigidbody.
rb.mass = 10f;
}
다음과 같이 컴포넌트 레퍼런스에 대한 메서드를 호출할 수도 있습니다.
void Start ()
{
Rigidbody rb = GetComponent<Rigidbody>();
// Add a force to the Rigidbody.
rb.AddForce(Vector3.up * 10f);
}
참고: 동일한 게임 오브젝트에 여러 커스텀 스크립트를 연결할 수 있습니다. 한 스크립트에서 다른 스크립트에 액세스해야 할 때는 평소와 마찬가지로 GetComponent를 사용하고 스크립트 클래스의 이름(또는 파일 이름)을 사용하여 원하는 컴포넌트 유형을 지정할 수 있습니다.
게임 오브젝트에 추가되지 않은 컴포넌트 유형을 검색해서 가져오려고 하면 GetComponent는 null을 반환합니다. null 오브젝트의 값을 변경하려고 하면 런타임 시점에 null 레퍼런스 오류가 발생합니다.
스크립트는 때때로 단독으로 작동하지만, 일반적으로 다른 게임 오브젝트 또는 다른 게임 오브젝트의 컴포넌트를 추적합니다. 예를 들어 요리 게임에서 요리사가 스토브의 위치를 알아야 할 수 있습니다. Unity는 특정 상황에 적합한 다른 오브젝트를 검색해서 가져오는 다양한 방법을 제공합니다.
관련된 게임 오브젝트를 찾는 가장 간단한 방법은 public GameObject 변수를 스크립트에 추가하는 것입니다.
public class Chef : MonoBehaviour
{
public GameObject stove;
// Other variables and functions...
}
이 변수는 인스펙터에서 GameObject 필드로 표시됩니다.
씬 또는 계층 구조 패널에서 오브젝트를 이 변수로 드래그하여 할당할 수 있습니다.
GetComponent 함수와 컴포넌트 액세스 변수는 다른 요소와 마찬가지로 이 오브젝트에 이용할 수 있습니다. 따라서 다음과 같은 코드를 사용할 수 있습니다.
public class Chef : MonoBehaviour {
public GameObject stove;
void Start() {
// Start the chef 2 units in front of the stove.
transform.position = stove.transform.position + Vector3.forward * 2f;
}
}
또한 스크립트에서 컴포넌트 유형의 public 변수를 선언하면 해당 컴포넌트가 연결된 게임 오브젝트를 드래그할 수 있습니다. 이렇게 하면 게임 오브젝트 자체가 아닌 컴포넌트에 직접 액세스합니다.
public Transform playerTransform;
오브젝트와 변수를 연결하는 것은 영구적으로 연결된 개별 오브젝트를 다루는 경우에 가장 유용합니다. array 변수를 사용하여 동일한 유형의 여러 오브젝트를 연결할 수 있지만 런타임이 아닐 때 Unity 에디터에서 연결해야 합니다. 런타임 시 오브젝트를 쉽게 찾을 수 있는 경우가 많으며, Unity는 아래 설명대로 두 가지 방법을 제공합니다.
게임 씬은 수집품, 웨이포인트, 장애물 같은 유형의 여러 게임 오브젝트를 사용하는 경우가 있습니다. 이를 감독하거나 이에 반응하는 특정 스크립트로 추적해야 할 수 있습니다. 예를 들어 모든 웨이포인트는 경로 탐색 스크립트에서 사용할 수 있어야 할 수 있습니다. 변수를 사용하여 이러한 게임 오브젝트를 연결할 수도 있지만, 각 새로운 웨이포인트를 스크립트의 변수로 드래그해야 하는 경우 설계 프로세스가 지루해집니다. 마찬가지로 웨이포인트가 삭제되면 누락된 게임 오브젝트에 대한 변수 레퍼런스를 제거해야 하는 번거로움이 있습니다. 이러한 경우에는 모든 게임 오브젝트를 하나의 부모 게임 오브젝트의 자식으로 만들어 게임 오브젝트 세트를 관리하는 것이 좋습니다. 자식 게임 오브젝트는 부모의 Transform 컴포넌트를 사용하여 가져올 수 있습니다(모든 게임 오브젝트에는 암시적으로 트랜스폼이 있기 때문).
using UnityEngine;
public class WaypointManager : MonoBehaviour {
public Transform[] waypoints;
void Start()
{
waypoints = new Transform[transform.childCount];
int i = 0;
foreach (Transform t in transform)
{
waypoints[i++] = t;
}
}
}
또한 Transform.Find 메서드를 사용하여 이름별로 특정 자식 오브젝트를 찾을 수도 있습니다.
transform.Find("Frying Pan");
이는 게임 오브젝트에 게임플레이 중에 추가하거나 제거할 수 있는 자식 게임 오브젝트가 있을 때 유용할 수 있습니다. 게임플레이 중에 집어 들거나 내려놓을 수 있는 툴이나 장비가 좋은 예입니다.
프로젝트를 편집하는 동안 인스펙터에서 게임 오브젝트 간에 레퍼런스를 설정할 수 있습니다. 하지만 게임에서 캐릭터와 가장 가까운 아이템을 찾거나 씬이 로드된 후 인스턴스화된 게임 오브젝트를 참조하는 등 사전에 설정할 수 없는 경우도 있습니다. 이 경우 런타임 시 레퍼런스를 찾아 게임 오브젝트 간에 메시지를 보낼 수 있습니다.
BroadcastMessage를 사용하면 해당 메서드가 어디에 구현되어야 하는지 명시하지 않고도 지정한 이름의 메서드에 호출을 보낼 수 있습니다. 이를 사용하여 특정 게임 오브젝트 또는 해당 자식의 모든 MonoBehaviour에서 지정한 이름의 메서드를 호출할 수 있습니다. 필요에 따라 하나 이상의 수신자가 있도록 강제로 설정할 수 있습니다(그렇지 않으면 오류 발생).
SendMessage는 조금 더 구체적이며, 게임 오브젝트 자체(자식 제외)에 지정된 이름의 메서드만 호출합니다.
SendMessageUpwards는 유사하지만 게임 오브젝트와 모든 해당 _부모_에 지정된 이름의 메서드를 호출합니다.
게임 오브젝트를 식별할 수 있는 일부 정보가 있는 한, 씬 계층 구조에서 언제든지 게임 오브젝트를 찾을 수 있습니다. 개별 오브젝트는 GameObject.Find 함수를 사용하여 이름으로 검색할 수 있습니다.
GameObject player;
void Start()
{
player = GameObject.Find("MainHeroCharacter");
}
또한 GameObject.FindWithTag 및 GameObject.FindGameObjectsWithTag 메서드를 사용하여 태그로 오브젝트 또는 오브젝트 컬렉션을 찾을 수 있습니다.
다음은 한 명의 요리사 캐릭터가 등장하는 요리 게임에서 주방에 여러 개의 스토브(각각 ‘Stove’ 태그 지정)가 있는 경우입니다.
GameObject chef;
GameObject[] stoves;
void Start()
{
chef = GameObject.FindWithTag("Chef");
stoves = GameObject.FindGameObjectsWithTag("Stove");
}
프로젝트가 실행되는 동안 게임 오브젝트를 생성하거나 파괴할 수 있습니다. Unity에서는 기존 오브젝트의 새 복사본을 만드는 Instantiate 메서드를 사용하여 게임 오브젝트를 생성할 수 있습니다.
게임 오브젝트를 인스턴스화하는 방법에 대한 전체 설명과 예시는 런타임 시 프리팹 인스턴스화를 참조하십시오.
Destroy 메서드는 프레임 업데이트가 완료된 후 또는 선택적으로 짧은 시간 지연 후 오브젝트를 삭제합니다.
void OnCollisionEnter(Collision otherObj) {
if (otherObj.gameObject.tag == "Garbage can") {
Destroy(gameObject, 0.5f);
}
}
Destroy 함수는 개별 컴포넌트를 파괴할 수 있으며 게임 오브젝트 자체에는 영향을 미치지 않습니다. this를 작성하여 스크립트가 연결된 게임 오브젝트를 파괴한다고 가정하는 실수가 흔히 발생합니다.
Destroy(this);
this는 게임 오브젝트가 아니라 스크립트를 나타냅니다. 실제로는 이를 호출하는 스크립트 컴포넌트를 파괴하고 게임 오브젝트는 그대로 유지하지만 스크립트 컴포넌트는 제거됩니다.
GameObject 클래스는 Unity 게임 오브젝트 메뉴에서 제공되는 옵션에 대한 스크립트 기반 대안을 제공하며, 이를 통해 기본 오브젝트를 만들 수 있습니다.
Unity의 빌트인 기본 인스턴스를 생성하려면 지정한 유형의 기본형을 인스턴스화하는 GameObject.CreatePrimitive를 사용합니다. 사용 가능한 기본 유형은 구체, 캡슐, 실린더, 큐브, 평면, 사각형입니다.