143 lines
4.6 KiB
C#
143 lines
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;
|
|||
|
|
}
|
|||
|
|
}
|