using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
using UnityEngine.UI;
|
using System;
|
namespace vnxbqy.UI
|
{
|
[ExecuteAlways]
|
public class AdaptiveLayout : MonoBehaviour
|
{
|
[SerializeField] HorizonOrVertical m_HorizonOrVerticle;
|
[SerializeField] CanvasGroup m_CanvasGroup;
|
[SerializeField] List<AdaptiveElement> m_AdapElements;
|
[SerializeField] bool m_AutoIncludeChild=false;
|
[SerializeField] float m_LeastHeight = 0f;
|
[SerializeField] float m_LeastWidth = 0f;
|
[SerializeField] float m_MaxHeight = 0f;
|
[SerializeField] float m_MaxWidth = 0f;
|
[NonSerialized] RectTransform m_Rect;
|
public RectTransform rectTransform
|
{
|
get
|
{
|
if (m_Rect == null)
|
{
|
m_Rect = GetComponent<RectTransform>();
|
}
|
return m_Rect;
|
}
|
}
|
public float Size
|
{
|
get
|
{
|
return m_HorizonOrVerticle == HorizonOrVertical.Horizon ? rectTransform.sizeDelta.x : rectTransform.sizeDelta.y;
|
}
|
}
|
|
public event Action adaptiveUpdateEvent;
|
|
private void OnEnable()
|
{
|
if (m_AdapElements == null)
|
{
|
enabled = false;
|
return;
|
}
|
if (m_CanvasGroup != null)
|
{
|
m_CanvasGroup.alpha = 0;
|
m_CanvasGroup.interactable = true;
|
StartCoroutine(Co_DelayShow());
|
}
|
}
|
|
private void TrackerRect(RectTransform _rect)
|
{
|
var _pivot = _rect.pivot;
|
var _anchorMax = _rect.anchorMax;
|
var _anchorMin = _rect.anchorMin;
|
if (m_HorizonOrVerticle == HorizonOrVertical.Horizon)
|
{
|
_pivot.x = 0; _pivot.y = 0.5f;
|
_anchorMax.x = 0; _anchorMax.y = 0.5f;
|
_anchorMin.x = 0; _anchorMin.y = 0.5f;
|
}
|
else
|
{
|
_pivot.x = 0.5f; _pivot.y = 1f;
|
_anchorMax.x = 0.5f; _anchorMax.y = 1;
|
_anchorMin.x = 0.5f; _anchorMin.y = 1;
|
}
|
if (_rect.pivot != _pivot || _rect.anchorMax != _anchorMax || _rect.anchorMin != _anchorMin)
|
{
|
_rect.pivot = _pivot;
|
_rect.anchorMax = _anchorMax;
|
_rect.anchorMin = _anchorMin;
|
}
|
}
|
|
private void CalculateLayout()
|
{
|
var _offset = 0.0f;
|
var _horizon = m_HorizonOrVerticle == HorizonOrVertical.Horizon;
|
for (int i = 0; i < m_AdapElements.Count; i++)
|
{
|
if (m_AdapElements[i].rect == null || !m_AdapElements[i].rect.gameObject.activeInHierarchy)
|
{
|
continue;
|
}
|
_offset += _horizon ? m_AdapElements[i].padding.left : m_AdapElements[i].padding.top;
|
var _pos = m_AdapElements[i].rect.localPosition;
|
if (_horizon)
|
{
|
_pos.x = _offset;
|
}
|
else
|
{
|
_pos.y = -_offset;
|
}
|
if (m_AdapElements[i].rect.localPosition != _pos)
|
{
|
m_AdapElements[i].rect.localPosition = _pos;
|
}
|
_offset += _horizon ? m_AdapElements[i].rect.sizeDelta.x : m_AdapElements[i].rect.sizeDelta.y;
|
_offset += _horizon ? m_AdapElements[i].padding.right : m_AdapElements[i].padding.bottom;
|
}
|
var _sizeDelta = rectTransform.sizeDelta;
|
if (_horizon)
|
{
|
if (m_LeastWidth > 1f)
|
{
|
_offset = Mathf.Max(_offset, m_LeastWidth);
|
}
|
if (m_MaxWidth > 1f)
|
{
|
_offset = Mathf.Min(_offset, m_MaxWidth);
|
}
|
_sizeDelta.x = _offset;
|
}
|
else
|
{
|
if (m_LeastHeight > 1f)
|
{
|
_offset = Mathf.Max(_offset, m_LeastHeight);
|
}
|
if (m_MaxHeight > 1f)
|
{
|
_offset = Mathf.Min(_offset, m_MaxHeight);
|
}
|
_sizeDelta.y = _offset;
|
}
|
if (rectTransform.sizeDelta != _sizeDelta)
|
{
|
rectTransform.sizeDelta = _sizeDelta;
|
if (adaptiveUpdateEvent != null)
|
{
|
adaptiveUpdateEvent();
|
}
|
}
|
}
|
|
private void LateUpdate()
|
{
|
if (m_AdapElements == null)
|
{
|
return;
|
}
|
TrackerRect(rectTransform);
|
for (int i = 0; i < m_AdapElements.Count; i++)
|
{
|
if (m_AdapElements[i].rect == null)
|
{
|
continue;
|
}
|
TrackerRect(m_AdapElements[i].rect);
|
}
|
CalculateLayout();
|
}
|
|
private void OnTransformChildrenChanged()
|
{
|
if (m_AutoIncludeChild)
|
{
|
AutoIncludeChild();
|
}
|
}
|
|
private void AutoIncludeChild()
|
{
|
var _index = 0;
|
foreach (Transform _child in transform)
|
{
|
if (m_AdapElements == null)
|
{
|
m_AdapElements = new List<AdaptiveElement>();
|
}
|
var _rect = m_AdapElements.Find((x) =>
|
{
|
return x.rect == _child;
|
});
|
var _rectOffset= _child.GetComponent<AdaptiveRectOffset>();
|
if (_rect == null)
|
{
|
m_AdapElements.Insert(_index, new AdaptiveElement(_child as RectTransform, _rectOffset));
|
}
|
_index++;
|
}
|
if (m_AdapElements != null)
|
{
|
m_AdapElements.RemoveAll((x) =>
|
{
|
return x.rect == null;
|
});
|
}
|
LateUpdate();
|
}
|
|
IEnumerator Co_DelayShow()
|
{
|
yield return WaitingForSecondConst.WaitMS100;
|
if (m_CanvasGroup != null)
|
{
|
m_CanvasGroup.alpha = 1;
|
}
|
}
|
|
public enum HorizonOrVertical
|
{
|
Horizon,
|
Vertical,
|
}
|
[Serializable]
|
public class AdaptiveElement
|
{
|
[SerializeField] RectTransform m_Rect;
|
public RectTransform rect
|
{
|
get
|
{
|
return m_Rect;
|
}
|
}
|
[SerializeField] RectOffset m_Padding;
|
public RectOffset padding
|
{
|
get
|
{
|
return m_Padding;
|
}
|
}
|
|
public AdaptiveElement(RectTransform _rect, AdaptiveRectOffset _offset)
|
{
|
m_Rect = _rect;
|
m_Padding = _offset == null ? new RectOffset() : _offset.rectOffset;
|
}
|
}
|
|
}
|
}
|