📌
숙련 주차 강의의 늪에서 벗어나 환기를 위해 특강 정리를 하고자 한다!
학습 내용
1. 오브젝트와 스크립트의 관계
2. 다른 오브젝트를 참조하는 방법
3. 관련한 유용한 지식
# 기초
1. 오브젝트와 스크립트의 관계
게임 오브젝트에는 한 개 이상의 컴포넌트가 존재한다. 컴포넌트는 게임 오브젝트와 동작에 관한 기본 구성 요소로 모든 게임 오브젝트의 작동과 관련된 부품이다.
만약 게임 오브젝트에 스크립트를 추가했다면, 그 스크립트 역시 해당 오브젝트의 컴포넌트가 된다. 이때의 스크립트는 현재 오브젝트 자체를 참조하고 있기 때문에 기본 속성 데이터를 바로 접근할 수 있다.
Class A
void Start()
{
Debug.Log(gameObject.name); // 현재 오브젝트의 이름을 출력한다
Debug.Log(gameObject.tag); // 현재 오브젝트의 태그를 출력한다
}
하지만 이름, 태그 등과 달리 Rigidbody, Collider, AudioSource 같은 다른 컴포넌트는 직접 접근할 수 없기 때문에 GetComponent로 불러와야 한다. 단, Transform은 특별히 모든 GameObject에 기본적으로 포함된 컴포넌트이기 때문에, GetComponent<Transform>()를 쓰지 않고도 바로 접근할 수 있다.
2. 다른 오브젝트를 참조하는 방법
그렇다면 스크립트에서 현재 오브젝트가 아닌 다른 오브젝트와 상호작용하는 방법은 무엇이 있을까?
✅ Find 메서드
오브젝트 A에 붙어있는 A 스크립트에서 오브젝트 B를 참조하려고 한다고 가정해보자.
class A
{
public GameObject B;
void Start()
{
cube = GameObject.Find("B");
Debug.Log(cube.name);
}
현재 씬에서 특정 이름을 가진 오브젝트를 찾을 때 사용되는 Find 메서드를 활용하면 쉽게 B 오브젝트를 찾을 수 있다.
cube = GameObject.FindTag("//B 오브젝트의 태그");
// 태그가 달린 오브젝트를 리스트로 불러온다.
GameObject[] cube = GameObject.FindGameObjectWithTag("//B 오브젝트의 태그");
상황에 따라 다양한 Find 메서드를 사용할 수도 있다. 그러나 Find 메서드는 씬에 있는 모든 오브젝트를 검색하기 때문에 성능에 영향을 미칠 수 있어 최대한 사용을 피하는 게 좋다.
✅ 직렬화를 통한 인스펙터에서의 참조
필드에 맴버 변수를 만들고 인스펙터에 오브젝트를 드롭 앤 드롭으로 연결해서 참조 관계를 형성할 수 있다.
// 필드
public gameObject B
[SerializeField] private GameObject B;
여기서 B 오브젝트의 컴포넌트를 가져오려면 어떻게 해야할까?
✅ Getcomponent<T>
위에서 잠깐 언급했듯이 오브젝트의 컴포넌트를 가져올 때 사용하는 메서드이다. Getcomponent<T>에서 <>안에는 가져올 컴포넌트의 타입을 찾는다. 만약 Collider 컴포넌트를 쓰려면 Getcomponent<Collider>로 사용할 수 있다.
gameObject.GetComponent<Collider>
그러나 이 경우 스크립트가 있는 현재 오브젝트의 콜라이더 컴포넌트를 가져오게 된다. 따라서 B 오브젝트의 컴포넌트를 가져오려면 B.GetComponet를 사용해야 한다.
// 필드에서 변수 선언
Collider b
// 컴포넌트 가져오기
b = B.GetComponent<Collider>();
만약 B 오브젝트의 스크립트를 가져오고 싶을 때도 방법은 동일하다.
// 필드에서 변수 선언
B 클래스 = b 클래스
// 컴포넌트 가져오기
b 클래스 = B.GetComponent<Collider>();
찾으려는 컴포넌트가 없다면 null을 반환하기 때문에 예외 처리를 해주는 게 좋다.
✅ Getcomponent<T>의 종류
GetComponents<T>() : 현재 게임 오브젝트에서 타입 T의 모든 컴포넌트를 배열로 반환한다.
GetComponentInChildren<T> (bool includeInactive = false) : 현재 게임 오브젝트의 자식들 중에서 타입 T의 컴포넌트를 찾는다. IncludeInactive가 false(기본값)인 경우, 활성화된 오브젝트에서만 컴포넌트를 찾고, true로 설정하면 비활성화된 오브젝트와 자식 오브젝트에서도 컴포넌트를 검색한다.
GetComponentsInChildren<T> (bool includeInactive = false) : 현재 게임 오브젝트의 자식들 중에서 타입 T의 컴포넌트를 찾아 배열로 반환한다. 매개변수는 위와 같은 역할이다.
GetComponentInParent<T>() : 현재 게임 오브젝트와 그 부모들 중에서 타입 T의 컴포넌트를 찾는다.
GetComponentsInParent<T> (bool includeInactive = false) : 현재 게임 오브젝트와 그 부모들 중에서 타입 T의 컴포넌트를 배열로 반환한다.
✅ Getcomponent<T> 사용 시 유의할 점
최적화를 위해 GetComponent 메서드는 awake나 start에 한번만 초기화를 해두고, 변수로 사용하는 게 좋다. 또한 GetComponentInChildren 메서드는 계층 구조의 깊이에 따라 검색 시간이 더 많이 소요되기 때문에 찾고자 하는 컴포넌트를 계층 구조 상위에 배치하여 검색 시간을 줄이는 게 좋다.
3. 관련된 유용한 지식
✅ 오브젝트가 비활성화된 상태로 플레이 모드를 시작하면, 그 오브젝트에 연결된 스크립트가 실행되지 않는다. 또한, GameObject.Find를 사용해도 비활성화된 오브젝트는 찾을 수 없다.
✅ MonoBehavior
Unity에서 제공하는 모든 스크립트가 상속되어 있는 클래스이다. Awake, Start, Update 등 대표적인 메서드들은 MonoBehavior가 있어야 사용이 가능하다. 스크립트는 비주얼 스튜디오에서 제공해주는 시스템이기 때문에 스크립트 파일 자체로는 사용이 불가능하고, GameObject의 Component로 등록을 해야 사용을 할 수 있다. 이와 마찬가지로 MonoBehavior을 상속받지 않는 클래스라면 Component로 등록이 불가능하다.
델리게이트 특강을 이어서 보면 될 것 같다.
'[내배캠] 본 캠프 개발 학습 > 매일매일 쓰는 TIL' 카테고리의 다른 글
11월 15일 금요일 본 캠프 개발 일지 | 유니티 외부 데이터 파싱하기 (CSV) (0) | 2024.11.15 |
---|---|
11월 14일 목요일 본 캠프 개발 일지 (0) | 2024.11.14 |
11월 12일 화요일 본 캠프 개발 일지 (4) | 2024.11.12 |
11월 11일 월요일 본 캠프 개발 일지 (3) | 2024.11.11 |
11월 9일 토요일 본 캠프 개발 일지 | 베이지반 특강 1회차 (3) | 2024.11.09 |