Я работал над проектом, в котором я хотел получить все текстовые объекты в сцене и получить их иерархию из единой сцены.

Поэтому я решил получить иерархию сцен с помощью Editor Scripting. Если кто-то хочет получить его для разных сцен за один раз, вместо того, чтобы писать его как редактор сценария, пользователь может использовать тот же код, а затем прикрепить этот сценарий к префабу, а затем позволить экземпляру префаба оставаться во всех сценах и во всех сценах печатать путь.

Здесь я просто расскажу об идее создания сценария редактора.

  1. Создайте массив игровых объектов, в котором будут храниться все корневые объекты сцены.
private GameObject[] AllGo;

2. Определите константную строку с именем переменной, в которой хранится имя файла, в котором вы распечатываете всю иерархию игровых объектов, которые вам нужны.

const string clientList = "unity-scene.txt";

3. Напишите функцию, которая начнет выполняться при нажатии определенной метки в редакторе. Итак, чтобы сделать это, вы должны написать, как показано ниже

[MenuItem("Debug/GetAll")]
public static void GenerateLocReport()
{
    //some code 
}

* Если вы получаете сообщение об ошибке, проверьте, добавили ли вы пространство имен «using UnityEditor».

4. Теперь давайте напишем код внутри функции «GenerateLocReport ()».

а) Создайте массив игровых объектов, в котором будут храниться все корневые объекты сцены

List<GameObject> rootObjects = new List<GameObject>();

б) Затем с помощью сцены SceneManager.GetActiveScene () и GetRootGameObjects () мы получим корень всех игровых объектов, присутствующих в сцене.

Scene scene = SceneManager.GetActiveScene();
scene.GetRootGameObjects(rootObjects);

c) Затем определите переменную, которая хранит путь, в котором вы хотите сохранить файл, в котором вы хотите сохранить пути иерархии. Для этого мы используем Path.Combine () и Application.dataPath.

string filename = Path.Combine(Application.dataPath, clientList);

г) Затем переберите игровые объекты, получите всех их потомков и их собственный путь и запишите его в файл. Для записи в файл мы использовали StreamWriter

using (StreamWriter writer = new StreamWriter(filename, false))
{
  for (int i = 0; i < rootObjects.Count; ++i)
  {
   GameObject gameObject = rootObjects[i];
   //function to iterate over children
   DumpGameObject(gameObject, writer, "/", "");
  }
}

д) После перебора объектов мы будем использовать AssetDatabase.Refresh ().

AssetDatabase.Refresh();

5. Теперь давайте напишем функцию DumpGameObject (), которая выполняет итерацию по всем дочерним элементам определенного игрового объекта. Это рекурсивная функция, поэтому она может перебирать дочерние элементы переданного игрового объекта и печатать их пути.

private static void DumpGameObject(GameObject gameObject, StreamWriter writer, string indent, string parentName)
{
  if (gameObject.transform.childCount > 0)
  {
    if (parentName != "")
    {
       if (!parentName.EndsWith("/"))
       parentName = parentName + "/";
    }
    parentName = parentName + gameObject.name;
   }
   else
   {
     parentName = parentName + gameObject.name;
   }
   
   if (parentName.EndsWith("/"))
   {
     writer.WriteLine(parentName + gameObject.name);
   }
   else
   { 
     writer.WriteLine(parentName);
   }
   foreach (Transform child in gameObject.transform)
   {
     if (!parentName.EndsWith("/"))
     parentName = parentName + "/";
     DumpGameObject(child.gameObject, writer, indent, parentName);
   }
}

Сообщите мне, сработало ли это для вас (это действительно для меня!), И если у вас есть какие-либо отзывы.

Если вы хотите получить конкретный компонент и распечатать его путь, вы можете встроить приведенный ниже код в начало указанной выше функции (DumpGameObject ()).

foreach (Component component in gameObject.GetComponents<Component>())
{
  if (component == null)
  {
    Debug.Log("NULL");
  }
  else
  {
    if ((component.GetType().Name == "Text") ||  (component.GetType().Name == "Button"))
    {
       if ((component.GetType().Name == "Text"))
       {
         Text text = gameObject.GetComponent<Text>();
         writer.WriteLine(text.text + " = " + parentName + gameObject.name);
       }
       else if ((component.GetType().Name == "Button"))
       {
         writer.WriteLine(gameObject.name + " = " + parentName + gameObject.name);
       }
     }
   }
 }

То, что мы делаем выше, заключается в том, что мы перебираем игровой объект, и если компонент, который мы ищем, найден, мы печатаем путь к игровому объекту.

Чтобы увидеть подробный проект, вы можете клонировать или просмотреть код по ссылке ниже.