summaryrefslogtreecommitdiff
path: root/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout')
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs145
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs241
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs103
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs207
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs30
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs179
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs50
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs78
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs237
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs233
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs112
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs.meta13
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs30
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs.meta13
24 files changed, 1801 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs
new file mode 100644
index 0000000..96ee135
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs
@@ -0,0 +1,145 @@
+using UnityEngine.EventSystems;
+
+namespace UnityEngine.UI
+{
+ [AddComponentMenu("Layout/Aspect Ratio Fitter", 142)]
+ [ExecuteInEditMode]
+ [RequireComponent(typeof(RectTransform))]
+ [DisallowMultipleComponent]
+ public class AspectRatioFitter : UIBehaviour, ILayoutSelfController
+ {
+ public enum AspectMode { None, WidthControlsHeight, HeightControlsWidth, FitInParent, EnvelopeParent }
+
+ [SerializeField] private AspectMode m_AspectMode = AspectMode.None;
+ public AspectMode aspectMode { get { return m_AspectMode; } set { if (SetPropertyUtility.SetStruct(ref m_AspectMode, value)) SetDirty(); } }
+
+ [SerializeField] private float m_AspectRatio = 1;
+ public float aspectRatio { get { return m_AspectRatio; } set { if (SetPropertyUtility.SetStruct(ref m_AspectRatio, value)) SetDirty(); } }
+
+ [System.NonSerialized]
+ private RectTransform m_Rect;
+
+ private RectTransform rectTransform
+ {
+ get
+ {
+ if (m_Rect == null)
+ m_Rect = GetComponent<RectTransform>();
+ return m_Rect;
+ }
+ }
+
+ private DrivenRectTransformTracker m_Tracker;
+
+ protected AspectRatioFitter() {}
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ SetDirty();
+ }
+
+ protected override void OnDisable()
+ {
+ m_Tracker.Clear();
+ LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
+ base.OnDisable();
+ }
+
+ protected override void OnRectTransformDimensionsChange()
+ {
+ UpdateRect();
+ }
+
+ private void UpdateRect()
+ {
+ if (!IsActive())
+ return;
+
+ m_Tracker.Clear();
+
+ switch (m_AspectMode)
+ {
+#if UNITY_EDITOR
+ case AspectMode.None:
+ {
+ if (!Application.isPlaying)
+ m_AspectRatio = Mathf.Clamp(rectTransform.rect.width / rectTransform.rect.height, 0.001f, 1000f);
+
+ break;
+ }
+#endif
+ case AspectMode.HeightControlsWidth:
+ {
+ m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaX);
+ rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, rectTransform.rect.height * m_AspectRatio);
+ break;
+ }
+ case AspectMode.WidthControlsHeight:
+ {
+ m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaY);
+ rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, rectTransform.rect.width / m_AspectRatio);
+ break;
+ }
+ case AspectMode.FitInParent:
+ case AspectMode.EnvelopeParent:
+ {
+ m_Tracker.Add(this, rectTransform,
+ DrivenTransformProperties.Anchors |
+ DrivenTransformProperties.AnchoredPosition |
+ DrivenTransformProperties.SizeDeltaX |
+ DrivenTransformProperties.SizeDeltaY);
+
+ rectTransform.anchorMin = Vector2.zero;
+ rectTransform.anchorMax = Vector2.one;
+ rectTransform.anchoredPosition = Vector2.zero;
+
+ Vector2 sizeDelta = Vector2.zero;
+ Vector2 parentSize = GetParentSize();
+ if ((parentSize.y * aspectRatio < parentSize.x) ^ (m_AspectMode == AspectMode.FitInParent))
+ {
+ sizeDelta.y = GetSizeDeltaToProduceSize(parentSize.x / aspectRatio, 1);
+ }
+ else
+ {
+ sizeDelta.x = GetSizeDeltaToProduceSize(parentSize.y * aspectRatio, 0);
+ }
+ rectTransform.sizeDelta = sizeDelta;
+
+ break;
+ }
+ }
+ }
+
+ private float GetSizeDeltaToProduceSize(float size, int axis)
+ {
+ return size - GetParentSize()[axis] * (rectTransform.anchorMax[axis] - rectTransform.anchorMin[axis]);
+ }
+
+ private Vector2 GetParentSize()
+ {
+ RectTransform parent = rectTransform.parent as RectTransform;
+ if (!parent)
+ return Vector2.zero;
+ return parent.rect.size;
+ }
+
+ public virtual void SetLayoutHorizontal() {}
+
+ public virtual void SetLayoutVertical() {}
+
+ protected void SetDirty()
+ {
+ UpdateRect();
+ }
+
+ #if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ m_AspectRatio = Mathf.Clamp(m_AspectRatio, 0.001f, 1000f);
+ SetDirty();
+ }
+
+ #endif
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs.meta
new file mode 100644
index 0000000..e89adeb
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 49604c30279a7aa44b531ad6ffea458c
+timeCreated: 1602119378
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs
new file mode 100644
index 0000000..6504ac2
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs
@@ -0,0 +1,241 @@
+using UnityEngine.EventSystems;
+
+namespace UnityEngine.UI
+{
+ [RequireComponent(typeof(Canvas))]
+ [ExecuteInEditMode]
+ [AddComponentMenu("Layout/Canvas Scaler", 101)]
+ public class CanvasScaler : UIBehaviour
+ {
+ public enum ScaleMode { ConstantPixelSize, ScaleWithScreenSize, ConstantPhysicalSize }
+
+ [Tooltip("Determines how UI elements in the Canvas are scaled.")]
+ [SerializeField] private ScaleMode m_UiScaleMode = ScaleMode.ConstantPixelSize;
+ public ScaleMode uiScaleMode { get { return m_UiScaleMode; } set { m_UiScaleMode = value; } }
+
+ [Tooltip("If a sprite has this 'Pixels Per Unit' setting, then one pixel in the sprite will cover one unit in the UI.")]
+ [SerializeField] protected float m_ReferencePixelsPerUnit = 100;
+ public float referencePixelsPerUnit { get { return m_ReferencePixelsPerUnit; } set { m_ReferencePixelsPerUnit = value; } }
+
+
+ // Constant Pixel Size settings
+
+ [Tooltip("Scales all UI elements in the Canvas by this factor.")]
+ [SerializeField] protected float m_ScaleFactor = 1;
+ public float scaleFactor { get { return m_ScaleFactor; } set { m_ScaleFactor = Mathf.Max(0.01f, value); } }
+
+
+ // Scale With Screen Size settings
+
+ public enum ScreenMatchMode { MatchWidthOrHeight = 0, Expand = 1, Shrink = 2 }
+
+ [Tooltip("The resolution the UI layout is designed for. If the screen resolution is larger, the UI will be scaled up, and if it's smaller, the UI will be scaled down. This is done in accordance with the Screen Match Mode.")]
+ [SerializeField] protected Vector2 m_ReferenceResolution = new Vector2(800, 600);
+ public Vector2 referenceResolution
+ {
+ get
+ {
+ return m_ReferenceResolution;
+ }
+ set
+ {
+ m_ReferenceResolution = value;
+
+ const float k_MinimumResolution = 0.00001f;
+
+ if (m_ReferenceResolution.x > -k_MinimumResolution && m_ReferenceResolution.x < k_MinimumResolution) m_ReferenceResolution.x = k_MinimumResolution * Mathf.Sign(m_ReferenceResolution.x);
+ if (m_ReferenceResolution.y > -k_MinimumResolution && m_ReferenceResolution.y < k_MinimumResolution) m_ReferenceResolution.y = k_MinimumResolution * Mathf.Sign(m_ReferenceResolution.y);
+ }
+ }
+
+ [Tooltip("A mode used to scale the canvas area if the aspect ratio of the current resolution doesn't fit the reference resolution.")]
+ [SerializeField] protected ScreenMatchMode m_ScreenMatchMode = ScreenMatchMode.MatchWidthOrHeight;
+ public ScreenMatchMode screenMatchMode { get { return m_ScreenMatchMode; } set { m_ScreenMatchMode = value; } }
+
+ [Tooltip("Determines if the scaling is using the width or height as reference, or a mix in between.")]
+ [Range(0, 1)]
+ [SerializeField] protected float m_MatchWidthOrHeight = 0;
+ public float matchWidthOrHeight { get { return m_MatchWidthOrHeight; } set { m_MatchWidthOrHeight = value; } }
+
+ // The log base doesn't have any influence on the results whatsoever, as long as the same base is used everywhere.
+ private const float kLogBase = 2;
+
+
+ // Constant Physical Size settings
+
+ public enum Unit { Centimeters, Millimeters, Inches, Points, Picas }
+
+ [Tooltip("The physical unit to specify positions and sizes in.")]
+ [SerializeField] protected Unit m_PhysicalUnit = Unit.Points;
+ public Unit physicalUnit { get { return m_PhysicalUnit; } set { m_PhysicalUnit = value; } }
+
+ [Tooltip("The DPI to assume if the screen DPI is not known.")]
+ [SerializeField] protected float m_FallbackScreenDPI = 96;
+ public float fallbackScreenDPI { get { return m_FallbackScreenDPI; } set { m_FallbackScreenDPI = value; } }
+
+ [Tooltip("The pixels per inch to use for sprites that have a 'Pixels Per Unit' setting that matches the 'Reference Pixels Per Unit' setting.")]
+ [SerializeField] protected float m_DefaultSpriteDPI = 96;
+ public float defaultSpriteDPI { get { return m_DefaultSpriteDPI; } set { m_DefaultSpriteDPI = Mathf.Max(1, value); } }
+
+
+ // World Canvas settings
+
+ [Tooltip("The amount of pixels per unit to use for dynamically created bitmaps in the UI, such as Text.")]
+ [SerializeField] protected float m_DynamicPixelsPerUnit = 1;
+ public float dynamicPixelsPerUnit { get { return m_DynamicPixelsPerUnit; } set { m_DynamicPixelsPerUnit = value; } }
+
+
+ // General variables
+
+ private Canvas m_Canvas;
+ [System.NonSerialized]
+ private float m_PrevScaleFactor = 1;
+ [System.NonSerialized]
+ private float m_PrevReferencePixelsPerUnit = 100;
+
+
+ protected CanvasScaler() {}
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ m_Canvas = GetComponent<Canvas>();
+ Handle();
+ }
+
+ protected override void OnDisable()
+ {
+ SetScaleFactor(1);
+ SetReferencePixelsPerUnit(100);
+ base.OnDisable();
+ }
+
+ protected virtual void Update()
+ {
+ Handle();
+ }
+
+ protected virtual void Handle()
+ {
+ if (m_Canvas == null || !m_Canvas.isRootCanvas)
+ return;
+
+ if (m_Canvas.renderMode == RenderMode.WorldSpace)
+ {
+ HandleWorldCanvas();
+ return;
+ }
+
+ switch (m_UiScaleMode)
+ {
+ case ScaleMode.ConstantPixelSize: HandleConstantPixelSize(); break;
+ case ScaleMode.ScaleWithScreenSize: HandleScaleWithScreenSize(); break;
+ case ScaleMode.ConstantPhysicalSize: HandleConstantPhysicalSize(); break;
+ }
+ }
+
+ protected virtual void HandleWorldCanvas()
+ {
+ SetScaleFactor(m_DynamicPixelsPerUnit);
+ SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit);
+ }
+
+ protected virtual void HandleConstantPixelSize()
+ {
+ SetScaleFactor(m_ScaleFactor);
+ SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit);
+ }
+
+ protected virtual void HandleScaleWithScreenSize()
+ {
+ Vector2 screenSize = new Vector2(Screen.width, Screen.height);
+
+ // Multiple display support only when not the main display. For display 0 the reported
+ // resolution is always the desktops resolution since its part of the display API,
+ // so we use the standard none multiple display method. (case 741751)
+ int displayIndex = m_Canvas.targetDisplay;
+ if (displayIndex > 0 && displayIndex < Display.displays.Length)
+ {
+ Display disp = Display.displays[displayIndex];
+ screenSize = new Vector2(disp.renderingWidth, disp.renderingHeight);
+ }
+
+ float scaleFactor = 0;
+ switch (m_ScreenMatchMode)
+ {
+ case ScreenMatchMode.MatchWidthOrHeight:
+ {
+ // We take the log of the relative width and height before taking the average.
+ // Then we transform it back in the original space.
+ // the reason to transform in and out of logarithmic space is to have better behavior.
+ // If one axis has twice resolution and the other has half, it should even out if widthOrHeight value is at 0.5.
+ // In normal space the average would be (0.5 + 2) / 2 = 1.25
+ // In logarithmic space the average is (-1 + 1) / 2 = 0
+ float logWidth = Mathf.Log(screenSize.x / m_ReferenceResolution.x, kLogBase);
+ float logHeight = Mathf.Log(screenSize.y / m_ReferenceResolution.y, kLogBase);
+ float logWeightedAverage = Mathf.Lerp(logWidth, logHeight, m_MatchWidthOrHeight);
+ scaleFactor = Mathf.Pow(kLogBase, logWeightedAverage);
+ break;
+ }
+ case ScreenMatchMode.Expand:
+ {
+ scaleFactor = Mathf.Min(screenSize.x / m_ReferenceResolution.x, screenSize.y / m_ReferenceResolution.y);
+ break;
+ }
+ case ScreenMatchMode.Shrink:
+ {
+ scaleFactor = Mathf.Max(screenSize.x / m_ReferenceResolution.x, screenSize.y / m_ReferenceResolution.y);
+ break;
+ }
+ }
+
+ SetScaleFactor(scaleFactor);
+ SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit);
+ }
+
+ protected virtual void HandleConstantPhysicalSize()
+ {
+ float currentDpi = Screen.dpi;
+ float dpi = (currentDpi == 0 ? m_FallbackScreenDPI : currentDpi);
+ float targetDPI = 1;
+ switch (m_PhysicalUnit)
+ {
+ case Unit.Centimeters: targetDPI = 2.54f; break;
+ case Unit.Millimeters: targetDPI = 25.4f; break;
+ case Unit.Inches: targetDPI = 1; break;
+ case Unit.Points: targetDPI = 72; break;
+ case Unit.Picas: targetDPI = 6; break;
+ }
+
+ SetScaleFactor(dpi / targetDPI);
+ SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit * targetDPI / m_DefaultSpriteDPI);
+ }
+
+ protected void SetScaleFactor(float scaleFactor)
+ {
+ if (scaleFactor == m_PrevScaleFactor)
+ return;
+
+ m_Canvas.scaleFactor = scaleFactor;
+ m_PrevScaleFactor = scaleFactor;
+ }
+
+ protected void SetReferencePixelsPerUnit(float referencePixelsPerUnit)
+ {
+ if (referencePixelsPerUnit == m_PrevReferencePixelsPerUnit)
+ return;
+
+ m_Canvas.referencePixelsPerUnit = referencePixelsPerUnit;
+ m_PrevReferencePixelsPerUnit = referencePixelsPerUnit;
+ }
+
+#if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ m_ScaleFactor = Mathf.Max(0.01f, m_ScaleFactor);
+ m_DefaultSpriteDPI = Mathf.Max(1, m_DefaultSpriteDPI);
+ }
+
+#endif
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs.meta
new file mode 100644
index 0000000..4d67413
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: debcf26b89013e446a6de5574715c5af
+timeCreated: 1602119380
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs
new file mode 100644
index 0000000..a31d14c
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs
@@ -0,0 +1,103 @@
+using UnityEngine.EventSystems;
+
+namespace UnityEngine.UI
+{
+ [AddComponentMenu("Layout/Content Size Fitter", 141)]
+ [ExecuteInEditMode]
+ [RequireComponent(typeof(RectTransform))]
+ public class ContentSizeFitter : UIBehaviour, ILayoutSelfController
+ {
+ public enum FitMode
+ {
+ Unconstrained,
+ MinSize,
+ PreferredSize
+ }
+
+ [SerializeField] protected FitMode m_HorizontalFit = FitMode.Unconstrained;
+ public FitMode horizontalFit { get { return m_HorizontalFit; } set { if (SetPropertyUtility.SetStruct(ref m_HorizontalFit, value)) SetDirty(); } }
+
+ [SerializeField] protected FitMode m_VerticalFit = FitMode.Unconstrained;
+ public FitMode verticalFit { get { return m_VerticalFit; } set { if (SetPropertyUtility.SetStruct(ref m_VerticalFit, value)) SetDirty(); } }
+
+ [System.NonSerialized] private RectTransform m_Rect;
+ private RectTransform rectTransform
+ {
+ get
+ {
+ if (m_Rect == null)
+ m_Rect = GetComponent<RectTransform>();
+ return m_Rect;
+ }
+ }
+
+ private DrivenRectTransformTracker m_Tracker;
+
+ protected ContentSizeFitter()
+ {}
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ SetDirty();
+ }
+
+ protected override void OnDisable()
+ {
+ m_Tracker.Clear();
+ LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
+ base.OnDisable();
+ }
+
+ protected override void OnRectTransformDimensionsChange()
+ {
+ SetDirty();
+ }
+
+ private void HandleSelfFittingAlongAxis(int axis)
+ {
+ FitMode fitting = (axis == 0 ? horizontalFit : verticalFit);
+ if (fitting == FitMode.Unconstrained)
+ {
+ // Keep a reference to the tracked transform, but don't control its properties:
+ m_Tracker.Add(this, rectTransform, DrivenTransformProperties.None);
+ return;
+ }
+
+ m_Tracker.Add(this, rectTransform, (axis == 0 ? DrivenTransformProperties.SizeDeltaX : DrivenTransformProperties.SizeDeltaY));
+
+ // Set size to min or preferred size
+ if (fitting == FitMode.MinSize)
+ rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, LayoutUtility.GetMinSize(m_Rect, axis));
+ else
+ rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, LayoutUtility.GetPreferredSize(m_Rect, axis));
+ }
+
+ public virtual void SetLayoutHorizontal()
+ {
+ m_Tracker.Clear();
+ HandleSelfFittingAlongAxis(0);
+ }
+
+ public virtual void SetLayoutVertical()
+ {
+ HandleSelfFittingAlongAxis(1);
+ }
+
+ protected void SetDirty()
+ {
+ if (!IsActive())
+ return;
+
+ LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
+ }
+
+ #if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ SetDirty();
+ }
+
+ #endif
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs.meta
new file mode 100644
index 0000000..9f31a6d
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 742ec49dc902c1f4db49d19ada047c0e
+timeCreated: 1602119379
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs
new file mode 100644
index 0000000..170e410
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs
@@ -0,0 +1,207 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+namespace UnityEngine.UI
+{
+ [AddComponentMenu("Layout/Grid Layout Group", 152)]
+ public class GridLayoutGroup : LayoutGroup
+ {
+ public enum Corner { UpperLeft = 0, UpperRight = 1, LowerLeft = 2, LowerRight = 3 }
+ public enum Axis { Horizontal = 0, Vertical = 1 }
+ public enum Constraint { Flexible = 0, FixedColumnCount = 1, FixedRowCount = 2 }
+
+ [SerializeField] protected Corner m_StartCorner = Corner.UpperLeft;
+ public Corner startCorner { get { return m_StartCorner; } set { SetProperty(ref m_StartCorner, value); } }
+
+ [SerializeField] protected Axis m_StartAxis = Axis.Horizontal;
+ public Axis startAxis { get { return m_StartAxis; } set { SetProperty(ref m_StartAxis, value); } }
+
+ [SerializeField] protected Vector2 m_CellSize = new Vector2(100, 100);
+ public Vector2 cellSize { get { return m_CellSize; } set { SetProperty(ref m_CellSize, value); } }
+
+ [SerializeField] protected Vector2 m_Spacing = Vector2.zero;
+ public Vector2 spacing { get { return m_Spacing; } set { SetProperty(ref m_Spacing, value); } }
+
+ [SerializeField] protected Constraint m_Constraint = Constraint.Flexible;
+ public Constraint constraint { get { return m_Constraint; } set { SetProperty(ref m_Constraint, value); } }
+
+ [SerializeField] protected int m_ConstraintCount = 2;
+ public int constraintCount { get { return m_ConstraintCount; } set { SetProperty(ref m_ConstraintCount, Mathf.Max(1, value)); } }
+
+ protected GridLayoutGroup()
+ {}
+
+ #if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ base.OnValidate();
+ constraintCount = constraintCount;
+ }
+
+ #endif
+
+ public override void CalculateLayoutInputHorizontal()
+ {
+ base.CalculateLayoutInputHorizontal();
+
+ int minColumns = 0;
+ int preferredColumns = 0;
+ if (m_Constraint == Constraint.FixedColumnCount)
+ {
+ minColumns = preferredColumns = m_ConstraintCount;
+ }
+ else if (m_Constraint == Constraint.FixedRowCount)
+ {
+ minColumns = preferredColumns = Mathf.CeilToInt(rectChildren.Count / (float)m_ConstraintCount - 0.001f);
+ }
+ else
+ {
+ minColumns = 1;
+ preferredColumns = Mathf.CeilToInt(Mathf.Sqrt(rectChildren.Count));
+ }
+
+ SetLayoutInputForAxis(
+ padding.horizontal + (cellSize.x + spacing.x) * minColumns - spacing.x,
+ padding.horizontal + (cellSize.x + spacing.x) * preferredColumns - spacing.x,
+ -1, 0);
+ }
+
+ public override void CalculateLayoutInputVertical()
+ {
+ int minRows = 0;
+ if (m_Constraint == Constraint.FixedColumnCount)
+ {
+ minRows = Mathf.CeilToInt(rectChildren.Count / (float)m_ConstraintCount - 0.001f);
+ }
+ else if (m_Constraint == Constraint.FixedRowCount)
+ {
+ minRows = m_ConstraintCount;
+ }
+ else
+ {
+ float width = rectTransform.rect.size.x;
+ int cellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x)));
+ minRows = Mathf.CeilToInt(rectChildren.Count / (float)cellCountX);
+ }
+
+ float minSpace = padding.vertical + (cellSize.y + spacing.y) * minRows - spacing.y;
+ SetLayoutInputForAxis(minSpace, minSpace, -1, 1);
+ }
+
+ public override void SetLayoutHorizontal()
+ {
+ SetCellsAlongAxis(0);
+ }
+
+ public override void SetLayoutVertical()
+ {
+ SetCellsAlongAxis(1);
+ }
+
+ private void SetCellsAlongAxis(int axis)
+ {
+ // Normally a Layout Controller should only set horizontal values when invoked for the horizontal axis
+ // and only vertical values when invoked for the vertical axis.
+ // However, in this case we set both the horizontal and vertical position when invoked for the vertical axis.
+ // Since we only set the horizontal position and not the size, it shouldn't affect children's layout,
+ // and thus shouldn't break the rule that all horizontal layout must be calculated before all vertical layout.
+
+ if (axis == 0)
+ {
+ // Only set the sizes when invoked for horizontal axis, not the positions.
+ for (int i = 0; i < rectChildren.Count; i++)
+ {
+ RectTransform rect = rectChildren[i];
+
+ m_Tracker.Add(this, rect,
+ DrivenTransformProperties.Anchors |
+ DrivenTransformProperties.AnchoredPosition |
+ DrivenTransformProperties.SizeDelta);
+
+ rect.anchorMin = Vector2.up;
+ rect.anchorMax = Vector2.up;
+ rect.sizeDelta = cellSize;
+ }
+ return;
+ }
+
+ float width = rectTransform.rect.size.x;
+ float height = rectTransform.rect.size.y;
+
+ int cellCountX = 1;
+ int cellCountY = 1;
+ if (m_Constraint == Constraint.FixedColumnCount)
+ {
+ cellCountX = m_ConstraintCount;
+ cellCountY = Mathf.CeilToInt(rectChildren.Count / (float)cellCountX - 0.001f);
+ }
+ else if (m_Constraint == Constraint.FixedRowCount)
+ {
+ cellCountY = m_ConstraintCount;
+ cellCountX = Mathf.CeilToInt(rectChildren.Count / (float)cellCountY - 0.001f);
+ }
+ else
+ {
+ if (cellSize.x + spacing.x <= 0)
+ cellCountX = int.MaxValue;
+ else
+ cellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x)));
+
+ if (cellSize.y + spacing.y <= 0)
+ cellCountY = int.MaxValue;
+ else
+ cellCountY = Mathf.Max(1, Mathf.FloorToInt((height - padding.vertical + spacing.y + 0.001f) / (cellSize.y + spacing.y)));
+ }
+
+ int cornerX = (int)startCorner % 2;
+ int cornerY = (int)startCorner / 2;
+
+ int cellsPerMainAxis, actualCellCountX, actualCellCountY;
+ if (startAxis == Axis.Horizontal)
+ {
+ cellsPerMainAxis = cellCountX;
+ actualCellCountX = Mathf.Clamp(cellCountX, 1, rectChildren.Count);
+ actualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));
+ }
+ else
+ {
+ cellsPerMainAxis = cellCountY;
+ actualCellCountY = Mathf.Clamp(cellCountY, 1, rectChildren.Count);
+ actualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));
+ }
+
+ Vector2 requiredSpace = new Vector2(
+ actualCellCountX * cellSize.x + (actualCellCountX - 1) * spacing.x,
+ actualCellCountY * cellSize.y + (actualCellCountY - 1) * spacing.y
+ );
+ Vector2 startOffset = new Vector2(
+ GetStartOffset(0, requiredSpace.x),
+ GetStartOffset(1, requiredSpace.y)
+ );
+
+ for (int i = 0; i < rectChildren.Count; i++)
+ {
+ int positionX;
+ int positionY;
+ if (startAxis == Axis.Horizontal)
+ {
+ positionX = i % cellsPerMainAxis;
+ positionY = i / cellsPerMainAxis;
+ }
+ else
+ {
+ positionX = i / cellsPerMainAxis;
+ positionY = i % cellsPerMainAxis;
+ }
+
+ if (cornerX == 1)
+ positionX = actualCellCountX - 1 - positionX;
+ if (cornerY == 1)
+ positionY = actualCellCountY - 1 - positionY;
+
+ SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);
+ SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);
+ }
+ }
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs.meta
new file mode 100644
index 0000000..0ca5454
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 295d2cd868a0c204f850fde4917c4551
+timeCreated: 1602119378
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs
new file mode 100644
index 0000000..efe8d8e
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs
@@ -0,0 +1,30 @@
+namespace UnityEngine.UI
+{
+ [AddComponentMenu("Layout/Horizontal Layout Group", 150)]
+ public class HorizontalLayoutGroup : HorizontalOrVerticalLayoutGroup
+ {
+ protected HorizontalLayoutGroup()
+ {}
+
+ public override void CalculateLayoutInputHorizontal()
+ {
+ base.CalculateLayoutInputHorizontal();
+ CalcAlongAxis(0, false);
+ }
+
+ public override void CalculateLayoutInputVertical()
+ {
+ CalcAlongAxis(1, false);
+ }
+
+ public override void SetLayoutHorizontal()
+ {
+ SetChildrenAlongAxis(0, false);
+ }
+
+ public override void SetLayoutVertical()
+ {
+ SetChildrenAlongAxis(1, false);
+ }
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs.meta
new file mode 100644
index 0000000..0b116be
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 2e0c30f216d393d4b93475ba573aea85
+timeCreated: 1602119378
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs
new file mode 100644
index 0000000..3e1c923
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs
@@ -0,0 +1,179 @@
+namespace UnityEngine.UI
+{
+ // 布局算法的核心都在这个基类里面
+ public abstract class HorizontalOrVerticalLayoutGroup : LayoutGroup
+ {
+ [SerializeField] protected float m_Spacing = 0;
+ public float spacing { get { return m_Spacing; } set { SetProperty(ref m_Spacing, value); } }
+
+ [SerializeField] protected bool m_ChildForceExpandWidth = true;
+ public bool childForceExpandWidth { get { return m_ChildForceExpandWidth; } set { SetProperty(ref m_ChildForceExpandWidth, value); } }
+
+ [SerializeField] protected bool m_ChildForceExpandHeight = true;
+ public bool childForceExpandHeight { get { return m_ChildForceExpandHeight; } set { SetProperty(ref m_ChildForceExpandHeight, value); } }
+
+ [SerializeField] protected bool m_ChildControlWidth = true;
+ public bool childControlWidth { get { return m_ChildControlWidth; } set { SetProperty(ref m_ChildControlWidth, value); } }
+
+ [SerializeField] protected bool m_ChildControlHeight = true;
+ public bool childControlHeight { get { return m_ChildControlHeight; } set { SetProperty(ref m_ChildControlHeight, value); } }
+
+ // 根据子节点计算得到自身的min, preferred, flexible
+ protected void CalcAlongAxis(int axis, bool isVertical)
+ {
+ float combinedPadding = (axis == 0 ? padding.horizontal : padding.vertical); // padding是left+right, top+bottom
+ bool controlSize = (axis == 0 ? m_ChildControlWidth : m_ChildControlHeight);
+ bool childForceExpandSize = (axis == 0 ? childForceExpandWidth : childForceExpandHeight);
+
+ float totalMin = combinedPadding; // 所有子节点的min之和
+ float totalPreferred = combinedPadding; // 所有子节点的preferred之和
+ float totalFlexible = 0; // 是一个无单位数值,等于所有子节点的flexible值相加
+
+ bool alongOtherAxis = (isVertical ^ (axis == 1));
+ for (int i = 0; i < rectChildren.Count; i++)
+ {
+ RectTransform child = rectChildren[i];
+ float min, preferred, flexible; // 子节点的三个属性值
+ GetChildSizes(child, axis, controlSize, childForceExpandSize, out min, out preferred, out flexible);
+
+ if (alongOtherAxis)
+ {
+ totalMin = Mathf.Max(min + combinedPadding, totalMin);
+ totalPreferred = Mathf.Max(preferred + combinedPadding, totalPreferred);
+ totalFlexible = Mathf.Max(flexible, totalFlexible);
+ }
+ else
+ {
+ totalMin += min + spacing;
+ totalPreferred += preferred + spacing;
+
+ // Increment flexible size with element's flexible size.
+ totalFlexible += flexible;
+ }
+ }
+
+ // 减去最后一个子节点多加的spacing
+ if (!alongOtherAxis && rectChildren.Count > 0)
+ {
+ totalMin -= spacing;
+ totalPreferred -= spacing;
+ }
+
+ totalPreferred = Mathf.Max(totalMin, totalPreferred);
+ // 保存到m_TotalMinSize, m_TotalPreferredSize, m_TotalFlexibleSize
+ SetLayoutInputForAxis(totalMin, totalPreferred, totalFlexible, axis);
+ }
+
+ protected void SetChildrenAlongAxis(int axis, bool isVertical)
+ {
+ float size = rectTransform.rect.size[axis]; // RectTransform大小
+ bool controlSize = (axis == 0 ? m_ChildControlWidth : m_ChildControlHeight);
+ bool childForceExpandSize = (axis == 0 ? childForceExpandWidth : childForceExpandHeight);
+ float alignmentOnAxis = GetAlignmentOnAxis(axis);
+
+ bool alongOtherAxis = (isVertical ^ (axis == 1));
+ if (alongOtherAxis)
+ {
+ float innerSize = size - (axis == 0 ? padding.horizontal : padding.vertical); // 容纳子节点的空间
+ for (int i = 0; i < rectChildren.Count; i++)
+ {
+ RectTransform child = rectChildren[i];
+ float min, preferred, flexible;
+ GetChildSizes(child, axis, controlSize, childForceExpandSize, out min, out preferred, out flexible);
+
+ float requiredSpace = Mathf.Clamp(innerSize, min, flexible > 0 ? size : preferred);
+ float startOffset = GetStartOffset(axis, requiredSpace);
+ if (controlSize)
+ {
+ SetChildAlongAxis(child, axis, startOffset, requiredSpace);
+ }
+ else
+ {
+ float offsetInCell = (requiredSpace - child.sizeDelta[axis]) * alignmentOnAxis;
+ SetChildAlongAxis(child, axis, startOffset + offsetInCell);
+ }
+ }
+ }
+ else
+ {
+ float pos = (axis == 0 ? padding.left : padding.top);
+ if (GetTotalFlexibleSize(axis) == 0 && GetTotalPreferredSize(axis) < size)
+ pos = GetStartOffset(axis, GetTotalPreferredSize(axis) - (axis == 0 ? padding.horizontal : padding.vertical));
+
+ float minMaxLerp = 0; // 塞进min之后的剩余空间/preferred-min的空间,是子节点从min向preferred扩大的依据
+ if (GetTotalMinSize(axis) != GetTotalPreferredSize(axis))
+ minMaxLerp = Mathf.Clamp01((size - GetTotalMinSize(axis)) / (GetTotalPreferredSize(axis) - GetTotalMinSize(axis)));
+
+ float itemFlexibleMultiplier = 0; // 塞进preferred之后,进一步塞满剩余空间的依据,即flexible
+ if (size > GetTotalPreferredSize(axis))
+ {
+ if (GetTotalFlexibleSize(axis) > 0)
+ itemFlexibleMultiplier = (size - GetTotalPreferredSize(axis)) / GetTotalFlexibleSize(axis);
+ }
+
+ for (int i = 0; i < rectChildren.Count; i++)
+ {
+ RectTransform child = rectChildren[i];
+ float min, preferred, flexible;
+ GetChildSizes(child, axis, controlSize, childForceExpandSize, out min, out preferred, out flexible);
+
+ float childSize = Mathf.Lerp(min, preferred, minMaxLerp);
+ childSize += flexible * itemFlexibleMultiplier;
+ if (controlSize)
+ {
+ // 设置子节点的transform
+ SetChildAlongAxis(child, axis, pos, childSize);
+ }
+ else
+ {
+ float offsetInCell = (childSize - child.sizeDelta[axis]) * alignmentOnAxis;
+ SetChildAlongAxis(child, axis, pos + offsetInCell);
+ }
+ pos += childSize + spacing;
+ }
+ }
+ }
+
+ // 返回节点的min, prefered, flexible大小
+ // axis 0是x轴,1是y轴
+ // controlSize 是否勾选ChildControlSize
+ // childForceExpand 是否勾选ChildForceExpand
+ private void GetChildSizes(RectTransform child, int axis, bool controlSize, bool childForceExpand,
+ out float min, out float preferred, out float flexible)
+ {
+ if (!controlSize) // 如果没勾ChildControlSize,那么会忽略
+ {
+ min = child.sizeDelta[axis];//sizeDelta这里等价于size,因为动态布局系统里面anchor都是一起的
+ preferred = min;
+ flexible = 0;
+ }
+ else
+ {
+ min = LayoutUtility.GetMinSize(child, axis);
+ preferred = LayoutUtility.GetPreferredSize(child, axis);
+ flexible = LayoutUtility.GetFlexibleSize(child, axis);
+ }
+
+ if (childForceExpand)
+ flexible = Mathf.Max(flexible, 1);
+ }
+
+#if UNITY_EDITOR
+ protected override void Reset()
+ {
+ base.Reset();
+
+ // For new added components we want these to be set to false,
+ // so that the user's sizes won't be overwritten before they
+ // have a chance to turn these settings off.
+ // However, for existing components that were added before this
+ // feature was introduced, we want it to be on be default for
+ // backwardds compatibility.
+ // Hence their default value is on, but we set to off in reset.
+ m_ChildControlWidth = false;
+ m_ChildControlHeight = false;
+ }
+
+#endif
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs.meta
new file mode 100644
index 0000000..4eaf7af
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: e33d83c2ebb040d459eaafaae66cc5e9
+timeCreated: 1602119380
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs
new file mode 100644
index 0000000..d0e1510
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs
@@ -0,0 +1,50 @@
+using UnityEngine;
+using System.Collections;
+
+namespace UnityEngine.UI
+{
+ public interface ILayoutElement
+ {
+#region LayoutGroup的派生类才会实现,其他ILayoutElement比如Image,Text不会实现
+ // After this method is invoked, layout horizontal input properties should return up-to-date values.
+ // Children will already have up-to-date layout horizontal inputs when this methods is called.
+ void CalculateLayoutInputHorizontal();
+ // After this method is invoked, layout vertical input properties should return up-to-date values.
+ // Children will already have up-to-date layout vertical inputs when this methods is called.
+ void CalculateLayoutInputVertical();
+#endregion
+
+ // Layout horizontal inputs
+ float minWidth { get; }
+ float preferredWidth { get; }
+ float flexibleWidth { get; }
+ // Layout vertical inputs
+ float minHeight { get; }
+ float preferredHeight { get; }
+ float flexibleHeight { get; }
+
+ int layoutPriority { get; }
+ }
+
+ public interface ILayoutController
+ {
+ void SetLayoutHorizontal();
+ void SetLayoutVertical();
+ }
+
+ // An ILayoutGroup component should drive the RectTransforms of its children.
+ public interface ILayoutGroup : ILayoutController
+ {
+ }
+
+ // An ILayoutSelfController component should drive its own RectTransform.
+ public interface ILayoutSelfController : ILayoutController
+ {
+ }
+
+ // An ILayoutIgnorer component is ignored by the auto-layout system.
+ public interface ILayoutIgnorer
+ {
+ bool ignoreLayout { get; }
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs.meta
new file mode 100644
index 0000000..f115b8f
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 9437925aea643a84f8ab4da3d03c183d
+timeCreated: 1602119379
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs
new file mode 100644
index 0000000..cdee245
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs
@@ -0,0 +1,78 @@
+using UnityEngine.EventSystems;
+
+namespace UnityEngine.UI
+{
+ [AddComponentMenu("Layout/Layout Element", 140)]
+ [RequireComponent(typeof(RectTransform))]
+ [ExecuteInEditMode]
+ public class LayoutElement : UIBehaviour, ILayoutElement, ILayoutIgnorer
+ {
+ [SerializeField] private bool m_IgnoreLayout = false;
+ [SerializeField] private float m_MinWidth = -1;
+ [SerializeField] private float m_MinHeight = -1;
+ [SerializeField] private float m_PreferredWidth = -1;
+ [SerializeField] private float m_PreferredHeight = -1;
+ [SerializeField] private float m_FlexibleWidth = -1;
+ [SerializeField] private float m_FlexibleHeight = -1;
+ [SerializeField] private int m_LayoutPriority = 1;
+
+
+ public virtual bool ignoreLayout { get { return m_IgnoreLayout; } set { if (SetPropertyUtility.SetStruct(ref m_IgnoreLayout, value)) SetDirty(); } }
+
+ public virtual void CalculateLayoutInputHorizontal() {}
+ public virtual void CalculateLayoutInputVertical() {}
+ public virtual float minWidth { get { return m_MinWidth; } set { if (SetPropertyUtility.SetStruct(ref m_MinWidth, value)) SetDirty(); } }
+ public virtual float minHeight { get { return m_MinHeight; } set { if (SetPropertyUtility.SetStruct(ref m_MinHeight, value)) SetDirty(); } }
+ public virtual float preferredWidth { get { return m_PreferredWidth; } set { if (SetPropertyUtility.SetStruct(ref m_PreferredWidth, value)) SetDirty(); } }
+ public virtual float preferredHeight { get { return m_PreferredHeight; } set { if (SetPropertyUtility.SetStruct(ref m_PreferredHeight, value)) SetDirty(); } }
+ public virtual float flexibleWidth { get { return m_FlexibleWidth; } set { if (SetPropertyUtility.SetStruct(ref m_FlexibleWidth, value)) SetDirty(); } }
+ public virtual float flexibleHeight { get { return m_FlexibleHeight; } set { if (SetPropertyUtility.SetStruct(ref m_FlexibleHeight, value)) SetDirty(); } }
+ public virtual int layoutPriority { get { return m_LayoutPriority; } set { if (SetPropertyUtility.SetStruct(ref m_LayoutPriority, value)) SetDirty(); } }
+
+
+ protected LayoutElement()
+ {}
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ SetDirty();
+ }
+
+ protected override void OnTransformParentChanged()
+ {
+ SetDirty();
+ }
+
+ protected override void OnDisable()
+ {
+ SetDirty();
+ base.OnDisable();
+ }
+
+ protected override void OnDidApplyAnimationProperties()
+ {
+ SetDirty();
+ }
+
+ protected override void OnBeforeTransformParentChanged()
+ {
+ SetDirty();
+ }
+
+ protected void SetDirty()
+ {
+ if (!IsActive())
+ return;
+ LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);
+ }
+
+ #if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ SetDirty();
+ }
+
+ #endif
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs.meta
new file mode 100644
index 0000000..40cc6f9
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 1ae73daeb8941804886a5ec8aa41dc2a
+timeCreated: 1602119377
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs
new file mode 100644
index 0000000..6a17e00
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs
@@ -0,0 +1,237 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine.EventSystems;
+using UnityEngine.Serialization;
+
+namespace UnityEngine.UI
+{
+ [DisallowMultipleComponent]
+ [ExecuteInEditMode]
+ [RequireComponent(typeof(RectTransform))]
+ public abstract class LayoutGroup : UIBehaviour, ILayoutElement, ILayoutGroup
+ {
+ [SerializeField] protected RectOffset m_Padding = new RectOffset();
+ public RectOffset padding { get { return m_Padding; } set { SetProperty(ref m_Padding, value); } }
+
+ [FormerlySerializedAs("m_Alignment")]
+ [SerializeField] protected TextAnchor m_ChildAlignment = TextAnchor.UpperLeft;
+ public TextAnchor childAlignment { get { return m_ChildAlignment; } set { SetProperty(ref m_ChildAlignment, value); } }
+
+ [System.NonSerialized] private RectTransform m_Rect;
+ protected RectTransform rectTransform
+ {
+ get
+ {
+ if (m_Rect == null)
+ m_Rect = GetComponent<RectTransform>();
+ return m_Rect;
+ }
+ }
+
+ protected DrivenRectTransformTracker m_Tracker;
+ private Vector2 m_TotalMinSize = Vector2.zero;
+ private Vector2 m_TotalPreferredSize = Vector2.zero;
+ private Vector2 m_TotalFlexibleSize = Vector2.zero;
+
+ [System.NonSerialized] private List<RectTransform> m_RectChildren = new List<RectTransform>();
+ protected List<RectTransform> rectChildren { get { return m_RectChildren; } }
+
+
+ // ILayoutElement Interface
+ // 收集子节点中参与布局的节点
+ public virtual void CalculateLayoutInputHorizontal()
+ {
+ m_RectChildren.Clear();
+ var toIgnoreList = ListPool<Component>.Get();
+ for (int i = 0; i < rectTransform.childCount; i++)
+ {
+ var rect = rectTransform.GetChild(i) as RectTransform;
+ if (rect == null || !rect.gameObject.activeInHierarchy)
+ continue;
+
+ rect.GetComponents(typeof(ILayoutIgnorer), toIgnoreList);
+
+ if (toIgnoreList.Count == 0)
+ {
+ m_RectChildren.Add(rect);
+ continue;
+ }
+
+ for (int j = 0; j < toIgnoreList.Count; j++)
+ {
+ var ignorer = (ILayoutIgnorer)toIgnoreList[j];
+ if (!ignorer.ignoreLayout)
+ {
+ m_RectChildren.Add(rect);
+ break;
+ }
+ }
+ }
+ ListPool<Component>.Release(toIgnoreList);
+ m_Tracker.Clear();
+ }
+
+ // 这个方法不收集是因为在CalculateLayoutInputHorizontal收集了,在LayoutRebuilder的Rebuild()方法中有注释
+ public abstract void CalculateLayoutInputVertical();
+ public virtual float minWidth { get { return GetTotalMinSize(0); } }
+ public virtual float preferredWidth { get { return GetTotalPreferredSize(0); } }
+ public virtual float flexibleWidth { get { return GetTotalFlexibleSize(0); } }
+ public virtual float minHeight { get { return GetTotalMinSize(1); } }
+ public virtual float preferredHeight { get { return GetTotalPreferredSize(1); } }
+ public virtual float flexibleHeight { get { return GetTotalFlexibleSize(1); } }
+ public virtual int layoutPriority { get { return 0; } }
+
+ // ILayoutController Interface
+
+ public abstract void SetLayoutHorizontal();
+ public abstract void SetLayoutVertical();
+
+ // Implementation
+
+ protected LayoutGroup()
+ {
+ if (m_Padding == null)
+ m_Padding = new RectOffset();
+ }
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ SetDirty();
+ }
+
+ protected override void OnDisable()
+ {
+ m_Tracker.Clear();
+ LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
+ base.OnDisable();
+ }
+
+ protected override void OnDidApplyAnimationProperties()
+ {
+ SetDirty();
+ }
+
+ protected float GetTotalMinSize(int axis)
+ {
+ return m_TotalMinSize[axis];
+ }
+
+ protected float GetTotalPreferredSize(int axis)
+ {
+ return m_TotalPreferredSize[axis];
+ }
+
+ protected float GetTotalFlexibleSize(int axis)
+ {
+ return m_TotalFlexibleSize[axis];
+ }
+
+ protected float GetStartOffset(int axis, float requiredSpaceWithoutPadding)
+ {
+ float requiredSpace = requiredSpaceWithoutPadding + (axis == 0 ? padding.horizontal : padding.vertical); // 算上padding后的大小
+ float availableSpace = rectTransform.rect.size[axis]; // RectTransform大小
+ float surplusSpace = availableSpace - requiredSpace; // 剩余空间
+ float alignmentOnAxis = GetAlignmentOnAxis(axis); // 0\0.5\1
+ return (axis == 0 ? padding.left : padding.top) + surplusSpace * alignmentOnAxis;
+ }
+
+ protected float GetAlignmentOnAxis(int axis)
+ {
+ if (axis == 0)
+ return ((int)childAlignment % 3) * 0.5f; // 0, 0.5, 1
+ else
+ return ((int)childAlignment / 3) * 0.5f; // 0, 0.5, 1
+ }
+
+ protected void SetLayoutInputForAxis(float totalMin, float totalPreferred, float totalFlexible, int axis)
+ {
+ m_TotalMinSize[axis] = totalMin;
+ m_TotalPreferredSize[axis] = totalPreferred;
+ m_TotalFlexibleSize[axis] = totalFlexible;
+ }
+
+ protected void SetChildAlongAxis(RectTransform rect, int axis, float pos)
+ {
+ if (rect == null)
+ return;
+
+ m_Tracker.Add(this, rect,
+ DrivenTransformProperties.Anchors |
+ (axis == 0 ? DrivenTransformProperties.AnchoredPositionX : DrivenTransformProperties.AnchoredPositionY));
+
+ rect.SetInsetAndSizeFromParentEdge(axis == 0 ? RectTransform.Edge.Left : RectTransform.Edge.Top, pos, rect.sizeDelta[axis]);
+ }
+
+ protected void SetChildAlongAxis(RectTransform rect, int axis, float pos, float size)
+ {
+ if (rect == null)
+ return;
+
+ m_Tracker.Add(this, rect,
+ DrivenTransformProperties.Anchors |
+ (axis == 0 ?
+ (DrivenTransformProperties.AnchoredPositionX | DrivenTransformProperties.SizeDeltaX) :
+ (DrivenTransformProperties.AnchoredPositionY | DrivenTransformProperties.SizeDeltaY)
+ ));
+
+ rect.SetInsetAndSizeFromParentEdge(axis == 0 ? RectTransform.Edge.Left : RectTransform.Edge.Top, pos, size);
+ }
+
+ private bool isRootLayoutGroup
+ {
+ get
+ {
+ Transform parent = transform.parent;
+ if (parent == null)
+ return true;
+ return transform.parent.GetComponent(typeof(ILayoutGroup)) == null;
+ }
+ }
+
+ protected override void OnRectTransformDimensionsChange()
+ {
+ base.OnRectTransformDimensionsChange();
+ if (isRootLayoutGroup)
+ SetDirty();
+ }
+
+ protected virtual void OnTransformChildrenChanged()
+ {
+ SetDirty();
+ }
+
+ protected void SetProperty<T>(ref T currentValue, T newValue)
+ {
+ if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
+ return;
+ currentValue = newValue;
+ SetDirty();
+ }
+
+ protected void SetDirty()
+ {
+ if (!IsActive())
+ return;
+
+ if (!CanvasUpdateRegistry.IsRebuildingLayout())
+ LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
+ else
+ StartCoroutine(DelayedSetDirty(rectTransform));
+ }
+
+ IEnumerator DelayedSetDirty(RectTransform rectTransform)
+ {
+ yield return null;
+ LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
+ }
+
+ #if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ SetDirty();
+ }
+
+ #endif
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs.meta
new file mode 100644
index 0000000..2c5525c
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 5094cec73437de8479168e16d201c2c6
+timeCreated: 1602119378
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs
new file mode 100644
index 0000000..5fba1cc
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs
@@ -0,0 +1,233 @@
+using System.Collections.Generic;
+using UnityEngine.Events;
+
+namespace UnityEngine.UI
+{
+ public class LayoutRebuilder : ICanvasElement
+ {
+ // m_ToRebuild是一个ILayoutGroup
+ private RectTransform m_ToRebuild;
+ //There are a few of reasons we need to cache the Hash from the transform:
+ // - This is a ValueType (struct) and .Net calculates Hash from the Value Type fields.
+ // - The key of a Dictionary should have a constant Hash value.
+ // - It's possible for the Transform to get nulled from the Native side.
+ // We use this struct with the IndexedSet container, which uses a dictionary as part of it's implementation
+ // So this struct gets used as a key to a dictionary, so we need to guarantee a constant Hash value.
+ private int m_CachedHashFromTransform;
+
+ // 一个rebuilder结构的池子
+ static ObjectPool<LayoutRebuilder> s_Rebuilders = new ObjectPool<LayoutRebuilder>(null, x => x.Clear());
+
+ private void Initialize(RectTransform controller)
+ {
+ m_ToRebuild = controller;
+ m_CachedHashFromTransform = controller.GetHashCode();
+ }
+
+ private void Clear()
+ {
+ m_ToRebuild = null;
+ m_CachedHashFromTransform = 0;
+ }
+
+ static LayoutRebuilder()
+ {
+ RectTransform.reapplyDrivenProperties += ReapplyDrivenProperties;
+ }
+
+ static void ReapplyDrivenProperties(RectTransform driven)
+ {
+ MarkLayoutForRebuild(driven);
+ }
+
+ public Transform transform { get { return m_ToRebuild; }}
+
+ public bool IsDestroyed()
+ {
+ return m_ToRebuild == null;
+ }
+
+ static void StripDisabledBehavioursFromList(List<Component> components)
+ {
+ components.RemoveAll(e => e is Behaviour && !((Behaviour)e).isActiveAndEnabled);
+ }
+
+ // 立即重新布局一次,而不用等到帧末尾CanvasUpdateReigstry.PerformUpdate的时候
+ public static void ForceRebuildLayoutImmediate(RectTransform layoutRoot)
+ {
+ var rebuilder = s_Rebuilders.Get();
+ rebuilder.Initialize(layoutRoot);
+ rebuilder.Rebuild(CanvasUpdate.Layout);
+ s_Rebuilders.Release(rebuilder);
+ }
+
+ public void Rebuild(CanvasUpdate executing)
+ {
+ switch (executing)
+ {
+ case CanvasUpdate.Layout:
+ // It's unfortunate that we'll perform the same GetComponents querys for the tree 2 times,
+ // but each tree have to be fully iterated before going to the next action,
+ // so reusing the results would entail storing results in a Dictionary or similar,
+ // which is probably a bigger overhead than performing GetComponents multiple times.
+ PerformLayoutCalculation(m_ToRebuild, e => (e as ILayoutElement).CalculateLayoutInputHorizontal());
+ PerformLayoutControl(m_ToRebuild, e => (e as ILayoutController).SetLayoutHorizontal());
+ PerformLayoutCalculation(m_ToRebuild, e => (e as ILayoutElement).CalculateLayoutInputVertical());
+ PerformLayoutControl(m_ToRebuild, e => (e as ILayoutController).SetLayoutVertical());
+ break;
+ }
+ }
+
+ // 从上到下遍历,执行action
+ private void PerformLayoutControl(RectTransform rect, UnityAction<Component> action)
+ {
+ if (rect == null)
+ return;
+
+ var components = ListPool<Component>.Get();
+ rect.GetComponents(typeof(ILayoutController), components);
+ StripDisabledBehavioursFromList(components);
+
+ // If there are no controllers on this rect we can skip this entire sub-tree
+ // We don't need to consider controllers on children deeper in the sub-tree either,
+ // since they will be their own roots.
+ if (components.Count > 0)
+ {
+ //
+ // Layout control needs to executed top down with parents being done before their children,
+ // because the children rely on the sizes of the parents.
+
+ // 做两次遍历,先执行ILayoutSelfController比如ContentSizeFitter,再执行ILayoutGroup
+
+ // First call layout controllers that may change their own RectTransform
+ for (int i = 0; i < components.Count; i++)
+ if (components[i] is ILayoutSelfController)
+ action(components[i]);
+
+ // Then call the remaining, such as layout groups that change their children, taking their own RectTransform size into account.
+ for (int i = 0; i < components.Count; i++)
+ if (!(components[i] is ILayoutSelfController))
+ action(components[i]);
+
+ for (int i = 0; i < rect.childCount; i++)
+ PerformLayoutControl(rect.GetChild(i) as RectTransform, action);
+ }
+
+ ListPool<Component>.Release(components);
+ }
+
+ private void PerformLayoutCalculation(RectTransform rect, UnityAction<Component> action)
+ {
+ if (rect == null)
+ return;
+
+ var components = ListPool<Component>.Get();
+ rect.GetComponents(typeof(ILayoutElement), components);
+ StripDisabledBehavioursFromList(components);
+
+ // If there are no controllers on this rect we can skip this entire sub-tree
+ // We don't need to consider controllers on children deeper in the sub-tree either,
+ // since they will be their own roots.
+ if (components.Count > 0 || rect.GetComponent(typeof(ILayoutGroup)))
+ {
+
+ // 先从子节点开始,最后到父节点,这样父节点可以得到子节点的信息
+ // Layout calculations needs to executed bottom up with children being done before their parents,
+ // because the parent calculated sizes rely on the sizes of the children.
+
+ for (int i = 0; i < rect.childCount; i++)
+ PerformLayoutCalculation(rect.GetChild(i) as RectTransform, action);
+
+ for (int i = 0; i < components.Count; i++)
+ action(components[i]);
+ }
+
+ ListPool<Component>.Release(components);
+ }
+
+ // 找到rect祖先节点中的layoutGroup并加入队列
+ public static void MarkLayoutForRebuild(RectTransform rect)
+ {
+ if (rect == null)
+ return;
+
+ var comps = ListPool<Component>.Get();
+ RectTransform layoutRoot = rect; // 祖先节点中的layoutGroup
+ while (true)
+ {
+ var parent = layoutRoot.parent as RectTransform;
+ if (!ValidLayoutGroup(parent, comps))
+ break;
+ layoutRoot = parent;
+ }
+
+ // We know the layout root is valid if it's not the same as the rect,
+ // since we checked that above. But if they're the same we still need to check.
+ if (layoutRoot == rect && !ValidController(layoutRoot, comps))
+ {
+ ListPool<Component>.Release(comps);
+ return;
+ }
+
+ MarkLayoutRootForRebuild(layoutRoot);
+ ListPool<Component>.Release(comps);
+ }
+
+ private static bool ValidLayoutGroup(RectTransform parent, List<Component> comps)
+ {
+ if (parent == null)
+ return false;
+
+ parent.GetComponents(typeof(ILayoutGroup), comps);
+ StripDisabledBehavioursFromList(comps);
+ var validCount = comps.Count > 0;
+ return validCount;
+ }
+
+ private static bool ValidController(RectTransform layoutRoot, List<Component> comps)
+ {
+ if (layoutRoot == null)
+ return false;
+ layoutRoot.GetComponents(typeof(ILayoutController), comps);
+ StripDisabledBehavioursFromList(comps);
+ var valid = comps.Count > 0;
+ return valid;
+ }
+
+ private static void MarkLayoutRootForRebuild(RectTransform controller)
+ {
+ if (controller == null)
+ return;
+
+ var rebuilder = s_Rebuilders.Get();
+ rebuilder.Initialize(controller);
+ // 注册到CanvasUpdateRegistry里
+ if (!CanvasUpdateRegistry.TryRegisterCanvasElementForLayoutRebuild(rebuilder))
+ s_Rebuilders.Release(rebuilder);
+ }
+
+ public void LayoutComplete()
+ {
+ // 放回池子里
+ s_Rebuilders.Release(this);
+ }
+
+ public void GraphicUpdateComplete()
+ {}
+
+ public override int GetHashCode()
+ {
+ return m_CachedHashFromTransform;
+ }
+
+ public override bool Equals(object obj)
+ {
+ return obj.GetHashCode() == GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return "(Layout Rebuilder for) " + m_ToRebuild;
+ }
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs.meta
new file mode 100644
index 0000000..ad21a40
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 297af0346d9a6b24e88b4dbdfae053e0
+timeCreated: 1602119378
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs
new file mode 100644
index 0000000..c58abd5
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs
@@ -0,0 +1,112 @@
+using UnityEngine;
+using System.Collections.Generic;
+using UnityEngine.Events;
+
+namespace UnityEngine.UI
+{
+ public static class LayoutUtility
+ {
+ public static float GetMinSize(RectTransform rect, int axis)
+ {
+ if (axis == 0)
+ return GetMinWidth(rect);
+ return GetMinHeight(rect);
+ }
+
+ public static float GetPreferredSize(RectTransform rect, int axis)
+ {
+ if (axis == 0)
+ return GetPreferredWidth(rect);
+ return GetPreferredHeight(rect);
+ }
+
+ public static float GetFlexibleSize(RectTransform rect, int axis)
+ {
+ if (axis == 0)
+ return GetFlexibleWidth(rect);
+ return GetFlexibleHeight(rect);
+ }
+
+ public static float GetMinWidth(RectTransform rect)
+ {
+ return GetLayoutProperty(rect, e => e.minWidth, 0);
+ }
+
+ public static float GetPreferredWidth(RectTransform rect)
+ {
+ return Mathf.Max(GetLayoutProperty(rect, e => e.minWidth, 0), GetLayoutProperty(rect, e => e.preferredWidth, 0));
+ }
+
+ public static float GetFlexibleWidth(RectTransform rect)
+ {
+ return GetLayoutProperty(rect, e => e.flexibleWidth, 0);
+ }
+
+ public static float GetMinHeight(RectTransform rect)
+ {
+ return GetLayoutProperty(rect, e => e.minHeight, 0);
+ }
+
+ public static float GetPreferredHeight(RectTransform rect)
+ {
+ return Mathf.Max(GetLayoutProperty(rect, e => e.minHeight, 0), GetLayoutProperty(rect, e => e.preferredHeight, 0));
+ }
+
+ public static float GetFlexibleHeight(RectTransform rect)
+ {
+ return GetLayoutProperty(rect, e => e.flexibleHeight, 0);
+ }
+
+ public static float GetLayoutProperty(RectTransform rect, System.Func<ILayoutElement, float> property, float defaultValue)
+ {
+ ILayoutElement dummy;
+ return GetLayoutProperty(rect, property, defaultValue, out dummy);
+ }
+
+ public static float GetLayoutProperty(RectTransform rect, System.Func<ILayoutElement, float> property, float defaultValue, out ILayoutElement source)
+ {
+ source = null;
+ if (rect == null)
+ return 0;
+ float min = defaultValue;
+ int maxPriority = System.Int32.MinValue;
+ var components = ListPool<Component>.Get();
+ rect.GetComponents(typeof(ILayoutElement), components);
+
+ for (int i = 0; i < components.Count; i++)
+ {
+ var layoutComp = components[i] as ILayoutElement; //
+ if (layoutComp is Behaviour && !((Behaviour)layoutComp).isActiveAndEnabled)
+ continue;
+
+ int priority = layoutComp.layoutPriority;
+ // If this layout components has lower priority than a previously used, ignore it.
+ if (priority < maxPriority)
+ continue;
+ float prop = property(layoutComp);
+ // If this layout property is set to a negative value, it means it should be ignored.
+ if (prop < 0)
+ continue;
+
+ // If this layout component has higher priority than all previous ones,
+ // overwrite with this one's value.
+ if (priority > maxPriority)
+ {
+ min = prop;
+ maxPriority = priority;
+ source = layoutComp;
+ }
+ // If the layout component has the same priority as a previously used,
+ // use the largest of the values with the same priority.
+ else if (prop > min)
+ {
+ min = prop;
+ source = layoutComp;
+ }
+ }
+
+ ListPool<Component>.Release(components);
+ return min;
+ }
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs.meta
new file mode 100644
index 0000000..e0d1878
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: d180430718b19fe4786c73f6e7c798fa
+timeCreated: 1602119380
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs
new file mode 100644
index 0000000..e24b842
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs
@@ -0,0 +1,30 @@
+namespace UnityEngine.UI
+{
+ [AddComponentMenu("Layout/Vertical Layout Group", 151)]
+ public class VerticalLayoutGroup : HorizontalOrVerticalLayoutGroup
+ {
+ protected VerticalLayoutGroup()
+ {}
+
+ public override void CalculateLayoutInputHorizontal()
+ {
+ base.CalculateLayoutInputHorizontal();
+ CalcAlongAxis(0, true);
+ }
+
+ public override void CalculateLayoutInputVertical()
+ {
+ CalcAlongAxis(1, true);
+ }
+
+ public override void SetLayoutHorizontal()
+ {
+ SetChildrenAlongAxis(0, true);
+ }
+
+ public override void SetLayoutVertical()
+ {
+ SetChildrenAlongAxis(1, true);
+ }
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs.meta
new file mode 100644
index 0000000..9b945bf
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: f050f1af13388a145b34f3d0b59c8955
+timeCreated: 1602119380
+licenseType: Free
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: