65 lines
3.0 KiB
C#
65 lines
3.0 KiB
C#
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<RectTransform>());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void Install(RectTransform canvasRect)
|
||
|
|
{
|
||
|
|
if (canvasRect == null || canvasRect.Find(ContainerName) != null) return;
|
||
|
|
|
||
|
|
var container = new GameObject(ContainerName, typeof(RectTransform)).GetComponent<RectTransform>();
|
||
|
|
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<SafeArea>(); // а теперь сжимаем под безопасную зону
|
||
|
|
}
|
||
|
|
|
||
|
|
// Растянут на весь экран без отступов -- это фон или окно поверх игры
|
||
|
|
static bool IsFullScreen(RectTransform rt)
|
||
|
|
{
|
||
|
|
return rt.anchorMin == Vector2.zero && rt.anchorMax == Vector2.one;
|
||
|
|
}
|
||
|
|
}
|