biography-of-lijie/Assets/GameMain/Scripts/UI/UGuiGroupHelper.cs

144 lines
4.9 KiB
C#

//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
using GeometryTD.CustomComponent;
namespace UI
{
/// <summary>
/// uGUI 界面组辅助器。
/// </summary>
[DefaultExecutionOrder(200)]
public class UGuiGroupHelper : UIGroupHelperBase
{
public const int DepthFactor = 10000;
private int m_Depth = 0;
private Canvas m_CachedCanvas = null;
private RectTransform m_RectTransform = null;
private int m_LastScreenWidth = -1;
private int m_LastScreenHeight = -1;
private Rect m_LastViewport = new Rect(float.MinValue, float.MinValue, float.MinValue, float.MinValue);
/// <summary>
/// 设置界面组深度。
/// </summary>
/// <param name="depth">界面组深度。</param>
public override void SetDepth(int depth)
{
m_Depth = depth;
m_CachedCanvas.overrideSorting = true;
m_CachedCanvas.sortingOrder = DepthFactor * depth;
}
private void Awake()
{
m_CachedCanvas = gameObject.GetOrAddComponent<Canvas>();
gameObject.GetOrAddComponent<GraphicRaycaster>();
m_RectTransform = GetComponent<RectTransform>();
}
private void Start()
{
m_CachedCanvas.overrideSorting = true;
m_CachedCanvas.sortingOrder = DepthFactor * m_Depth;
if (m_RectTransform == null)
{
return;
}
m_RectTransform.anchorMin = Vector2.zero;
m_RectTransform.anchorMax = Vector2.one;
m_RectTransform.pivot = new Vector2(0.5f, 0.5f);
m_RectTransform.anchoredPosition = Vector2.zero;
m_RectTransform.sizeDelta = Vector2.zero;
ApplyViewportClip(true);
}
private void LateUpdate()
{
ApplyViewportClip(false);
}
private void ApplyViewportClip(bool force)
{
if (m_RectTransform == null)
{
return;
}
int screenWidth = Screen.width;
int screenHeight = Screen.height;
Rect viewport = ResolveViewportRect();
if (!force
&& screenWidth == m_LastScreenWidth
&& screenHeight == m_LastScreenHeight
&& Mathf.Approximately(viewport.x, m_LastViewport.x)
&& Mathf.Approximately(viewport.y, m_LastViewport.y)
&& Mathf.Approximately(viewport.width, m_LastViewport.width)
&& Mathf.Approximately(viewport.height, m_LastViewport.height))
{
return;
}
m_LastScreenWidth = screenWidth;
m_LastScreenHeight = screenHeight;
m_LastViewport = viewport;
if (screenWidth <= 0 || screenHeight <= 0)
{
return;
}
float horizontalPadding = Mathf.Max(0f, (1f - viewport.width) * 0.5f * screenWidth);
float verticalPadding = Mathf.Max(0f, (1f - viewport.height) * 0.5f * screenHeight);
float canvasScale = ResolveCanvasScaleFactor();
float horizontalPaddingInCanvasUnit = horizontalPadding / canvasScale;
float verticalPaddingInCanvasUnit = verticalPadding / canvasScale;
m_RectTransform.offsetMin = new Vector2(horizontalPaddingInCanvasUnit, verticalPaddingInCanvasUnit);
m_RectTransform.offsetMax = new Vector2(-horizontalPaddingInCanvasUnit, -verticalPaddingInCanvasUnit);
}
private Rect ResolveViewportRect()
{
if (ResolutionAdapterComponent.TryGetTargetViewport(out Rect adapterViewport))
{
return adapterViewport;
}
Camera camera = m_CachedCanvas != null ? m_CachedCanvas.worldCamera : null;
if (camera == null && m_CachedCanvas != null && m_CachedCanvas.rootCanvas != null)
{
camera = m_CachedCanvas.rootCanvas.worldCamera;
}
if (camera == null && GameEntry.Scene != null)
{
camera = GameEntry.Scene.MainCamera;
}
if (camera == null)
{
camera = Camera.main;
}
return camera != null ? camera.rect : new Rect(0f, 0f, 1f, 1f);
}
private float ResolveCanvasScaleFactor()
{
Canvas rootCanvas = m_CachedCanvas != null ? m_CachedCanvas.rootCanvas : null;
float scale = rootCanvas != null ? rootCanvas.scaleFactor : (m_CachedCanvas != null ? m_CachedCanvas.scaleFactor : 1f);
return scale > 0.0001f ? scale : 1f;
}
}
}