하이러키 상에서 최상위 오브젝트인 Player와 _UI가 있다
Player는 _UI의 PromptText를 캐싱하고 싶은데 둘은 모두 최상위 게임오브젝트이며
이 둘보다 위에 있는건 현재 열려있는 씬 밖에 없다
결국 씬을 가져와서 씬으로부터 자식을 찾아야 프로그램 코드상으로 캐싱할 수 있다
1. 그렇다면 Player 기준으로 부모의 Transform을 저장해서, 그것으로부터 자식을 탐색하면 되지 않을까?
하지만 씬은 transform을 가지지 않으므로,
Transform sceneTransform = gameObject.transform.parent;
이런건 불가능하다
2. 그렇다면 GameObject로 받으면 되지 않을까?
하지만 이것도 불가능하다
GameObject sceneTransform = gameObject.transform.parent.gameObject;
씬에는 gameObject를 배치할 수 있지만 Scene 자체는 부모 오브젝트가 될 수 없기 때문이다
그러면 어떻게 해야 Scene을 가져올 수 있을까?
그건 SceneManager를 이용하는 것이다
다음 과정으로, 씬에 있는 최상위 오브젝트들을 가져올 수 있다
Scene currentScene = SceneManager.GetActiveScene();
GameObject[] rootObjects = currentScene.GetRootGameObjects();
검색함수는 따로 Helper클래스에 모아놓기로 정했다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 헬퍼 클래스(비 컴포넌트)
/// static 메서드로 만들어서 모든 곳에서 쓸 수 있도록 한다
/// </summary>
public class Helper
{
...
// 자식이 아닌 오브젝트를 검색한다
public static Transform FindObjectInScene(string findname)
{
// 최상위 루트오브젝트들을 찾는다
Scene currentScene = SceneManager.GetActiveScene();
GameObject[] rootObjects = currentScene.GetRootGameObjects();
// 루트 오브젝트를 검색하여 자식을 찾는다
if (rootObjects.Length != 0)
{
Transform foundTr;
for (int i = 0; i < rootObjects.Length; i++)
{
foundTr = FindChild(rootObjects[i].transform, findname);
if (foundTr)
return foundTr;
}
}
return null;
}
}
사용하는 곳에서는 이렇게 쓴다
재귀를 이용하므로, 매번 이렇게 검색하는건 심각한 성능의 낭비가 되기 때문에
Start에서 1번만 사용한다
캐싱한 이후에는 사용하지 않는다
promptText = Helper.FindObjectInScene("PromptText").GetComponent<TextMeshProUGUI>();
GameObject.Find와 같은 것처럼 보일 수 있지만
GameObject.Find는 비활성화된 오브젝트를 검색할 수 없다는 단점이 있다
또한 내가 만든 검색함수는 루트부터 차례로 검색하기 때문에(굳이 말하자면 DFS와 유사하다) 자식을 찾으면 조기종료가 가능하다
하지만 내가 만든 검색함수의 단점도 있다
재귀호출을 많이해서 stack overflow의 위험이 있다
따라서 다음 경우에 사용하면 좋다
① 비활성화된 오브젝트도 검색해야 할 때
② 루트 오브젝트의 수가 많지 않고, 특정 계층만 검색하고 싶을 때
'유니티 부트캠프 8기 > Ch05. Unity 게임 개발 숙련' 카테고리의 다른 글
벽 타기, 매달리기 (0) | 2025.03.11 |
---|---|
디버그 모드에서 자식오브젝트의 transform을 가져오는 방법 (0) | 2025.03.10 |
유니티 직렬화, Attribute, Serializable, SerializeField (0) | 2025.03.09 |
사운드 추가 (0) | 2025.03.05 |
몬스터 AI 만들기, 데미지 입었을 때 효과까지 (0) | 2025.03.05 |