using UnityEngine; using UnityEngine.SceneManagement; // Сам ставит Safe Area на экранные Canvas при загрузке каждой сцены (город, карта мира). // Руками в сцене ничего делать не нужно, и пересборка HUD через Tools не сломает настройку. // // Правило: всё, что растянуто на весь экран (фоны и окна поверх игры: BuildMenuPanel, Panels), // остаётся на весь экран. Остальные элементы (верхняя и нижняя панели, кнопки по краям, чат, окна // по центру) переезжают в контейнер "SafeArea" и не залезают под вырез и скругления экрана. public static class SafeAreaInstaller { const string ContainerName = "SafeArea"; // Canvas, которые подгоняются под безопасную зону static readonly string[] CanvasNames = { "HUD_Canvas", "WorldMap_Canvas" }; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] static void Init() { InstallAll(); SceneManager.sceneLoaded += (scene, mode) => InstallAll(); } static void InstallAll() { foreach (var name in CanvasNames) { var go = GameObject.Find(name); if (go != null) Install(go.GetComponent()); } } public static void Install(RectTransform canvasRect) { if (canvasRect == null || canvasRect.Find(ContainerName) != null) return; var container = new GameObject(ContainerName, typeof(RectTransform)).GetComponent(); container.SetParent(canvasRect, false); container.anchorMin = Vector2.zero; container.anchorMax = Vector2.one; container.offsetMin = Vector2.zero; container.offsetMax = Vector2.zero; // Контейнер -- первым: окна на весь экран остаются поверх HUD container.SetSiblingIndex(0); // Пока контейнер совпадает с Canvas, перенос сохраняет раскладку один в один for (int i = canvasRect.childCount - 1; i >= 0; i--) { var child = canvasRect.GetChild(i) as RectTransform; if (child == null || child == container || IsFullScreen(child)) continue; child.SetParent(container, false); child.SetSiblingIndex(0); // обход с конца -- порядок отрисовки сохраняется } container.gameObject.AddComponent(); // а теперь сжимаем под безопасную зону } // Растянут на весь экран без отступов -- это фон или окно поверх игры static bool IsFullScreen(RectTransform rt) { return rt.anchorMin == Vector2.zero && rt.anchorMax == Vector2.one; } }