=======================
=======================
=======================
출처: https://codingmania.tistory.com/192
유니티에서 게임 오브젝트 찾는 법은 한두가지가 아니다.
이번에는 게임 오브젝트 내 게임 오브젝트 즉, 하위 게임오브젝트를 찾는 방법을 정리해보려 한다.
대표적으로 세 가지가 존재한다.
transform.FindChild(string str)
transform.GetChild(int index)
transform.childCount
자식이 무엇인가.
하이어라키(Hierarchy)에서 계층 구조를 이루고 있는 형태를 말한다.
상위에 GameObject가 부모이며 들여쓰기 된 하위 1~6까지의 6개의 GameObject가 자식이다.
이제, 자식을 찾는 방법을 알아보자.
1. 이름으로 자식 GameObject를 찾는 방법(자기 자신)
transform.FindChild("이름");
2. 번호 순으로 자식 GameObject를 찾는 방법(자기 자신)
transform.GetChild(번호);
여기서 자기 자신이란, 해당 스크립트가 컴포넌트가 된 상태를 말한다.
만약, 외부의 게임오브젝트를 찾는 것은 앞에 어떤 GameObject인지를 명시해줘야 한다.
3. 이름으로 다른 게임오브젝트의 자식 GameObject를 찾는 방법(외부 게임오브젝트)
otherGameobject.transform.FindChild("이름");
4. 번호 순으로 다른 게임오브젝트의 자식 GameObject를 찾는 방법(외부 게임오브젝트)
otherGameobject.transform.GetChild(번호);
물론 otherGameobject는 스크립트에서 어떤 게임오브젝트인지 선언해줘야 한다.
그 외에도 childCount 가 존재하는데, 이것은 자식 오브젝트의 개수를 알 수 있다.
Transform에 연결되어 있는 자식 트랜스폼들의 갯수입니다.
즉, transform.childCount 으로 자식의 개수를 불러 올 수 있다. ( 위 같은 경우 6 출력)
원래 기본적으로 자식의 Transform을 얻고 싶을 때 사용하는 것이다.
하지만 이를 통하여 GameObject나 Component 모두 얻을 수 있다.
출처: https://codingmania.tistory.com/192 [괴발개발 개발새발 하는 개발자의 개발 블로그]
=======================
=======================
=======================
출처: https://treeofimaginary.tistory.com/114
몇번 언급했지만 유니티는 게임오브젝트 찾는방법이 좀 까다롭다.
가~장 기본적으로 주어지는 메소드는 GameObject.Find(오브젝트이름).
문제는 이게 비활성화(Inactive) 상태의 오브젝트는 못찾아준다는거다.
비활성화 오브젝트를 찾는걸로 Transform.FindChild(오브젝트 이름)이 있지만 이건 해당 트랜스폼의 자식들에 대해서로 탐색범위가 한정되어있다. 심지어 자기 자식의 자식은 이걸로 찾아지지도 않는단다.
결국 내가 임시로 생각해둔 방법은
1) 게임내 탐색이 요구될법한 모든 오브젝트를 루트 오브젝트(GameManager)에 귀속시킨다.
2) GameManager 스크립트는 Awake시 자신의 자식들을 순회하면서 Dictionary에 추가하고, 만약 자식들한테 추가자식이 있을경우 함수를 재귀해 다시 탐색한다.
3)이후 필요할때마다 GameManager의 FindTransform(오브젝트 이름)을 호출해 원하는 객체를 가져온다.
...편하긴하다. GameManager는 무슨일이 있어도 비활성화되지 않도록 설정했고, 탐색도 this.transform.root로 바로 접근할수있다.
문제는...
this.transform.root.GetComponent<GameManager>().FindTransform("InventoryUI").GetComponent<InventoryUI>();
...무슨 의미인지 알겠는가? InventoryUI라는 객체에 담긴 InventoryUI클래스를 얻어오는 거다.
뭔가 쓸데없이 길어진다. 정말 답이 없게 길어진다.
내 경우 FindTransform을 쓰는 이유는 단 하나다, 해당 오브젝트 이름과 동일한 이름을 가진 스크립트 컴포넌트를 가져오기 위함이다.
그럼 왜 반환할때 컴포넌트를 직접 반환하지 않느냐?...
이게 InventoryUI를 반환할지 EventObject를 반환할지 확실하지않아서 반환 자료형을 확실히 정의할수가 없다.
그렇다고 부모 클래스인 MonoBehvaior로 주자니 쓸데없이 박싱하는작업이 길어진다.
애초에, 이런 용도면 매개변수가 그냥 class 타입 자체로 (InventoryUI면 그냥 InventoryUI라는 클래스명자체가 매개변수로 박힌다던가)보낼수있는게 가장 이상적일것같은데, 그건 뭔가 현실적으로 안되는것같고...
말이 장황한데, 내가 하고싶다는건 이거다. 상황은
"플레이어가 인벤토리UI 컴포넌트를 가져오고싶다"
플레이어 스크립트
InventoryUI ui = this.transform.root.GetComponent<GameManager>().FindComponent(InventoryUI);
이렇게 하면 뙇하고 클래스가 반환되는걸 원하는거.
사실 어쩌면 된다해도 이게 훨씬더 비효율적일수도 있다.
....제네릭 메소드가 답이 될것같기도 한데. 좀 더 알아봐야겠다.
---------------------------------------------------
21:54분 추가
역시 답은 제네릭 메소드에 존재했다.
Pad pad = this.transform.root.GetComponent<GameManager>().FindComponent<Pad>();
함수 내부는 이렇게 구성되어있다.
public T FindComponent<T>()
{
return ingameobjects[typeof(T).ToString()].GetComponent<T>();
}
내 경우 대부분의 클래스파일은 대게 해당 클래스의 이름과 동일한 이름을 가진 게임오브젝트에 삽입되므로 (EventObject같은 예외야 있겠지만 이건 매개변수를 하나 넣는식으로 해결가능) 쉽게 도달한것같다.
...그나저나, 이걸 기껏 발견하고났더니 이걸 또 어느세월에 다 수정하고있나...하하...
----------------------------------------------------------
22:10분 추가
줄일수 있는 방법은 더 존재한다. 다만...이건 좀 신경쓰이는 문제긴 하다.
public static GameManager getter;
private void Awake()
{
getter = this;
Find(this.transform);
}
GameManager 클래스 내부 내용이다. static으로 선언해놨기에 이런 사용법이 가능하다.
pad = GameManager.getter.FindComponent<Pad>();
이젠 getcomponent를 할 필요조차 없어진다는 의미.
다만 유니티에서 static을 쓰는건 꽤나 지양되는 분위기라 이게 베스트인지는 좀 조심스러워진다.
private void Start()
{
//루트 오브젝트를 찾아내고, 해당 오브젝트로부터 Pad 게임오브젝트를 받은뒤 Pad 컴포넌트를 가져온다.
//pad = this.transform.root.GetComponent<GameManager>().FindTransform("Pad").GetComponent<Pad>();
//pad = this.transform.root.GetComponent<GameManager>().FindComponent<Pad>(); //pad = GameManager.GetRoot().FindComponent<Pad>(); pad = GameManager.getter.FindComponent<Pad>();
}
오늘 하루동안 얻은걸 바탕으로 pad 컴포넌트를 얻어오는 4가지 방법 변천사. 2번째 아님 4번째가 모범답안 아닐까 싶다.
=======================
=======================
=======================
기타관련링크
- https://cru6548.tistory.com/5
- https://prosto.tistory.com/147
=======================
=======================
=======================
'게임엔진관련 > 유니티 엔진' 카테고리의 다른 글
[Unity] 유니티 애니매이션(스프라이트, 오브젝트) 관련 (1) | 2019.07.05 |
---|---|
[Unity] 유니티 InputField 컨텐츠 타입 패스워드 관련 (0) | 2019.07.04 |
[Unity] 유니티 특정 오브젝트 찾기 관련 (0) | 2019.07.01 |
[Unity] 유니티 날짜, 시간 가져오기 관련 (0) | 2019.06.27 |
[Unity] 유니티 빌드 에러 관련 (0) | 2019.06.19 |
댓글 영역