143 lines
No EOL
4.6 KiB
C#
143 lines
No EOL
4.6 KiB
C#
using UnityEditor;
|
||
using UnityEngine;
|
||
using UnityEditor.SceneManagement;
|
||
using UnityEngine.SceneManagement;
|
||
using System.Collections.Generic;
|
||
|
||
public class MapHierarchyTool : EditorWindow
|
||
{
|
||
[MenuItem("Tools/Map Hierarchy Tool")]
|
||
public static void ShowWindow()
|
||
{
|
||
GetWindow<MapHierarchyTool>("Map Tool");
|
||
}
|
||
|
||
private void OnGUI()
|
||
{
|
||
GUILayout.Label("Управление объектами сцен", EditorStyles.boldLabel);
|
||
|
||
if (GUILayout.Button("1. Вытащить из 'map'", GUILayout.Height(30)))
|
||
{
|
||
ProcessScenes(false);
|
||
}
|
||
|
||
if (GUILayout.Button("2. Загнать обратно в 'map' (кроме Main Camera)", GUILayout.Height(30)))
|
||
{
|
||
ProcessScenes(true);
|
||
}
|
||
|
||
GUILayout.Space(10);
|
||
EditorGUILayout.HelpBox("Выделите папку со сценами или сами сцены в окне Project, затем нажмите нужную кнопку.", MessageType.Info);
|
||
}
|
||
|
||
private void ProcessScenes(bool packIntoMap)
|
||
{
|
||
// Находим все сцены среди выделенных объектов/папок
|
||
List<string> scenePaths = new List<string>();
|
||
foreach (string guid in Selection.assetGUIDs)
|
||
{
|
||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||
if (AssetDatabase.IsValidFolder(path))
|
||
{
|
||
string[] folderScenes = AssetDatabase.FindAssets("t:Scene", new string[] { path });
|
||
foreach (string fGuid in folderScenes)
|
||
{
|
||
scenePaths.Add(AssetDatabase.GUIDToAssetPath(fGuid));
|
||
}
|
||
}
|
||
else if (path.EndsWith(".unity"))
|
||
{
|
||
scenePaths.Add(path);
|
||
}
|
||
}
|
||
|
||
if (scenePaths.Count == 0)
|
||
{
|
||
Debug.LogWarning("Сцены не выбраны! Выделите папку или файлы сцен в окне Project.");
|
||
return;
|
||
}
|
||
|
||
// Спрашиваем сохранение текущей открытой сцены
|
||
if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) return;
|
||
|
||
string originalScenePath = SceneManager.GetActiveScene().path;
|
||
|
||
// Перебираем найденные сцены
|
||
foreach (string scenePath in scenePaths)
|
||
{
|
||
Scene scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
|
||
|
||
if (packIntoMap)
|
||
Pack(scene);
|
||
else
|
||
Unpack(scene);
|
||
|
||
EditorSceneManager.SaveScene(scene);
|
||
}
|
||
|
||
// Возвращаем обратно исходную сцену, которая была открыта
|
||
if (!string.IsNullOrEmpty(originalScenePath))
|
||
{
|
||
EditorSceneManager.OpenScene(originalScenePath, OpenSceneMode.Single);
|
||
}
|
||
|
||
Debug.Log($"Успешно обработано сцен: {scenePaths.Count}");
|
||
}
|
||
|
||
private void Unpack(Scene scene)
|
||
{
|
||
GameObject mapObj = FindMapObject(scene);
|
||
if (mapObj == null) return;
|
||
|
||
Transform mapTransform = mapObj.transform;
|
||
List<Transform> children = new List<Transform>();
|
||
|
||
// Собираем прямых потомков map
|
||
foreach (Transform child in mapTransform)
|
||
{
|
||
children.Add(child);
|
||
}
|
||
|
||
// Переносим их в корень сцены
|
||
foreach (Transform child in children)
|
||
{
|
||
child.SetParent(null);
|
||
}
|
||
|
||
EditorSceneManager.MarkSceneDirty(scene);
|
||
}
|
||
|
||
private void Pack(Scene scene)
|
||
{
|
||
GameObject mapObj = FindMapObject(scene);
|
||
|
||
// Если объекта map почему-то нет, создаем его
|
||
if (mapObj == null)
|
||
{
|
||
mapObj = new GameObject("map");
|
||
}
|
||
|
||
Transform mapTransform = mapObj.transform;
|
||
GameObject[] rootObjects = scene.GetRootGameObjects();
|
||
|
||
foreach (GameObject rootObj in rootObjects)
|
||
{
|
||
// Игнорируем сам map и Main Camera
|
||
if (rootObj != mapObj && rootObj.name != "Main Camera")
|
||
{
|
||
rootObj.transform.SetParent(mapTransform);
|
||
}
|
||
}
|
||
|
||
EditorSceneManager.MarkSceneDirty(scene);
|
||
}
|
||
|
||
private GameObject FindMapObject(Scene scene)
|
||
{
|
||
foreach (GameObject rootObj in scene.GetRootGameObjects())
|
||
{
|
||
if (rootObj.name == "map") return rootObj;
|
||
}
|
||
return null;
|
||
}
|
||
} |