Updated UIVerticalScroller for standards and added UIHorizontalScroller
Resolves: https://github.com/Unity-UI-Extensions/com.unity.uiextensions/issues/205pull/413/head
parent
70661a4823
commit
4b1c5412f1
|
@ -620,7 +620,7 @@ namespace UnityEditor.UI
|
|||
rectTransformCenter.anchorMax = new Vector2(1f, 0.6f);
|
||||
rectTransformCenter.sizeDelta = Vector2.zero;
|
||||
|
||||
uiscr.center = uiScrollerCenter.GetComponent<RectTransform>();
|
||||
uiscr.Center = uiScrollerCenter.GetComponent<RectTransform>();
|
||||
|
||||
//Setup Content container
|
||||
RectTransform rectTransformContent = childContent.GetComponent<RectTransform>();
|
||||
|
@ -669,10 +669,91 @@ namespace UnityEditor.UI
|
|||
|
||||
Selection.activeGameObject = uiVerticalScrollerRoot;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region UI Button
|
||||
[MenuItem("GameObject/UI/Extensions/Controls/UI Button", false)]
|
||||
#region UIHorizontal Scroller
|
||||
[MenuItem("GameObject/UI/Extensions/Layout/UI Horizontal Scroller", false)]
|
||||
static public void AddUIHorizontalScroller(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject uiHorizontalScrollerRoot = CreateUIElementRoot("UI Horizontal Scroller", menuCommand, s_ThickGUIElementSize);
|
||||
|
||||
GameObject uiScrollerCenter = CreateUIObject("Center", uiHorizontalScrollerRoot);
|
||||
|
||||
GameObject childContent = CreateUIObject("Content", uiHorizontalScrollerRoot);
|
||||
|
||||
// Set RectTransform to stretch
|
||||
RectTransform rectTransformScrollSnapRoot = uiHorizontalScrollerRoot.GetComponent<RectTransform>();
|
||||
rectTransformScrollSnapRoot.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
rectTransformScrollSnapRoot.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rectTransformScrollSnapRoot.anchoredPosition = Vector2.zero;
|
||||
rectTransformScrollSnapRoot.sizeDelta = new Vector2(500f, 150f);
|
||||
|
||||
// Add required ScrollRect
|
||||
ScrollRect sr = uiHorizontalScrollerRoot.AddComponent<ScrollRect>();
|
||||
sr.vertical = false;
|
||||
sr.horizontal = true;
|
||||
sr.movementType = ScrollRect.MovementType.Unrestricted;
|
||||
var uiscr = uiHorizontalScrollerRoot.AddComponent<UIHorizontalScroller>();
|
||||
|
||||
//Setup container center point
|
||||
RectTransform rectTransformCenter = uiScrollerCenter.GetComponent<RectTransform>();
|
||||
rectTransformCenter.anchorMin = new Vector2(0.3f,0f);
|
||||
rectTransformCenter.anchorMax = new Vector2(0.6f,1f);
|
||||
rectTransformCenter.sizeDelta = Vector2.zero;
|
||||
|
||||
uiscr.Center = uiScrollerCenter.GetComponent<RectTransform>();
|
||||
|
||||
//Setup Content container
|
||||
RectTransform rectTransformContent = childContent.GetComponent<RectTransform>();
|
||||
rectTransformContent.anchorMin = Vector2.zero;
|
||||
rectTransformContent.anchorMax = new Vector2(1f, 1f);
|
||||
rectTransformContent.sizeDelta = Vector2.zero;
|
||||
|
||||
sr.content = rectTransformContent;
|
||||
|
||||
// Add sample children
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
GameObject childPage = CreateUIObject("Page_" + i, childContent);
|
||||
|
||||
GameObject childText = CreateUIObject("Text", childPage);
|
||||
|
||||
//Setup 1st Child
|
||||
Image pageImage = childPage.AddComponent<Image>();
|
||||
pageImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
|
||||
pageImage.type = Image.Type.Sliced;
|
||||
pageImage.color = s_DefaultSelectableColor;
|
||||
|
||||
RectTransform rectTransformPage = childPage.GetComponent<RectTransform>();
|
||||
rectTransformPage.anchorMin = new Vector2(0.5f, 0);
|
||||
rectTransformPage.anchorMax = new Vector2(0.5f, 1f);
|
||||
rectTransformPage.sizeDelta = new Vector2(80f, 0f);
|
||||
rectTransformPage.pivot = new Vector2(0.5f, 0.5f);
|
||||
rectTransformPage.localPosition = new Vector3(80 * i, 0, 0);
|
||||
childPage.AddComponent<Button>();
|
||||
|
||||
var childCG = childPage.AddComponent<CanvasGroup>();
|
||||
childCG.interactable = false;
|
||||
|
||||
//Setup Text on Item
|
||||
Text text = childText.AddComponent<Text>();
|
||||
text.text = "Item_" + i;
|
||||
text.alignment = TextAnchor.MiddleCenter;
|
||||
text.color = new Color(0.196f, 0.196f, 0.196f);
|
||||
|
||||
//Setup Text on Item
|
||||
RectTransform rectTransformPageText = childText.GetComponent<RectTransform>();
|
||||
rectTransformPageText.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
rectTransformPageText.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rectTransformPageText.pivot = new Vector2(0.5f, 0.5f);
|
||||
}
|
||||
|
||||
Selection.activeGameObject = uiHorizontalScrollerRoot;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UI Button
|
||||
[MenuItem("GameObject/UI/Extensions/Controls/UI Button", false)]
|
||||
static public void AddUIButton(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject uiButtonRoot = CreateUIElementRoot("UI Button", menuCommand, s_ThickGUIElementSize);
|
||||
|
|
|
@ -0,0 +1,276 @@
|
|||
/// Credit Ahmad S. Al-Faqeeh
|
||||
/// Sourced from - https://github.com/Unity-UI-Extensions/com.unity.uiextensions/issues/205
|
||||
/// Based on the UIVerticalScroller
|
||||
///
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(ScrollRect))]
|
||||
[AddComponentMenu("Layout/Extensions/Horizontal Scroller")]
|
||||
public class UIHorizontalScroller : MonoBehaviour
|
||||
{
|
||||
private float[] distReposition;
|
||||
private float[] distance;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("desired ScrollRect")]
|
||||
private ScrollRect scrollRect;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Elements to populate inside the scroller")]
|
||||
private GameObject[] arrayOfElements;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Center display area (position of zoomed content)")]
|
||||
private RectTransform center;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Size / spacing of elements")]
|
||||
private RectTransform elementSize;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Scale = 1/ (1+distance from center * shrinkage)")]
|
||||
private Vector2 elementShrinkage = new Vector2(1f / 200, 1f / 200);
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Minimum element scale (furthest from center)")]
|
||||
private Vector2 minScale = new Vector2(0.7f, 0.7f);
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Select the item to be in center on start. (optional)")]
|
||||
private int startingIndex = -1;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Stop scrolling past last element from inertia.")]
|
||||
private bool stopMomentumOnEnd = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Set Items out of center to not interactible.")]
|
||||
private bool disableUnfocused = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Button to go to the next page. (optional)")]
|
||||
private GameObject scrollLeftButton;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Button to go to the previous page. (optional)")]
|
||||
private GameObject scrollRightButton;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Event fired when a specific item is clicked, exposes index number of item. (optional)")]
|
||||
private UnityEvent<int> onButtonClicked;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Event fired when the focused item is Changed. (optional)")]
|
||||
private UnityEvent<int> onFocusChanged;
|
||||
|
||||
public int FocusedElementIndex { get; private set; }
|
||||
|
||||
public RectTransform Center { get => center; set => center = value; }
|
||||
|
||||
//Scrollable area (content of desired ScrollRect)
|
||||
public RectTransform ScrollingPanel { get { return scrollRect.content; } }
|
||||
|
||||
public string Result { get; private set; }
|
||||
|
||||
public UIHorizontalScroller() { }
|
||||
|
||||
public UIHorizontalScroller(RectTransform center, RectTransform elementSize, ScrollRect scrollRect, GameObject[] arrayOfElements)
|
||||
{
|
||||
this.scrollRect = scrollRect;
|
||||
this.elementSize = elementSize;
|
||||
this.arrayOfElements = arrayOfElements;
|
||||
this.center = center;
|
||||
}
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
if (!scrollRect)
|
||||
{
|
||||
scrollRect = GetComponent<ScrollRect>();
|
||||
}
|
||||
|
||||
if (!center)
|
||||
{
|
||||
Debug.LogError("Please define the RectTransform for the Center viewport of the scrollable area");
|
||||
}
|
||||
|
||||
if (!elementSize)
|
||||
{
|
||||
elementSize = center;
|
||||
}
|
||||
|
||||
if (arrayOfElements == null || arrayOfElements.Length == 0)
|
||||
{
|
||||
var childCount = scrollRect.content.childCount;
|
||||
if (childCount > 0)
|
||||
{
|
||||
arrayOfElements = new GameObject[childCount];
|
||||
for (int i = 0; i < childCount; i++)
|
||||
{
|
||||
arrayOfElements[i] = scrollRect.content.GetChild(i).gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (scrollLeftButton)
|
||||
{
|
||||
scrollLeftButton.GetComponent<Button>().onClick.AddListener(() => ScrollLeft());
|
||||
}
|
||||
|
||||
if (scrollRightButton)
|
||||
{
|
||||
scrollRightButton.GetComponent<Button>().onClick.AddListener(() => ScrollRight());
|
||||
}
|
||||
|
||||
UpdateChildren(startingIndex, arrayOfElements);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recognises and resizes the children.
|
||||
/// </summary>
|
||||
/// <param name="startingIndex">Starting index.</param>
|
||||
/// <param name="arrayOfElements">Array of elements.</param>
|
||||
public void UpdateChildren(int startingIndex = -1, GameObject[] arrayOfElements = null)
|
||||
{
|
||||
// Set _arrayOfElements to arrayOfElements if given, otherwise to child objects of the scrolling panel.
|
||||
if (arrayOfElements != null)
|
||||
{
|
||||
this.arrayOfElements = arrayOfElements;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.arrayOfElements = new GameObject[ScrollingPanel.childCount];
|
||||
for (int i = 0; i < ScrollingPanel.childCount; i++)
|
||||
{
|
||||
this.arrayOfElements[i] = ScrollingPanel.GetChild(i).gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
// resize the elements to match elementSize rect
|
||||
for (var i = 0; i < this.arrayOfElements.Length; i++)
|
||||
{
|
||||
AddListener(arrayOfElements[i], i);
|
||||
|
||||
RectTransform r = this.arrayOfElements[i].GetComponent<RectTransform>();
|
||||
r.anchorMax = r.anchorMin = r.pivot = new Vector2(0.5f, 0.5f);
|
||||
r.localPosition = new Vector2(i * elementSize.rect.size.x,0);
|
||||
r.sizeDelta = elementSize.rect.size;
|
||||
}
|
||||
|
||||
// prepare for scrolling
|
||||
distance = new float[this.arrayOfElements.Length];
|
||||
distReposition = new float[this.arrayOfElements.Length];
|
||||
FocusedElementIndex = -1;
|
||||
|
||||
// if starting index is given, snap to respective element
|
||||
if (startingIndex > -1)
|
||||
{
|
||||
startingIndex = startingIndex > this.arrayOfElements.Length ? this.arrayOfElements.Length - 1 : startingIndex;
|
||||
SnapToElement(startingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddListener(GameObject button, int index)
|
||||
{
|
||||
var buttonClick = button.GetComponent<Button>();
|
||||
buttonClick.onClick.RemoveAllListeners();
|
||||
buttonClick.onClick.AddListener(() => onButtonClicked?.Invoke(index));
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (arrayOfElements.Length < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < arrayOfElements.Length; i++)
|
||||
{
|
||||
var arrayElementRT = arrayOfElements[i].GetComponent<RectTransform>();
|
||||
distReposition[i] = center.position.x - arrayElementRT.position.x;
|
||||
distance[i] = Mathf.Abs(distReposition[i]);
|
||||
|
||||
//Magnifying effect
|
||||
Vector2 scale = Vector2.Max(minScale, new Vector2(1 / (1 + distance[i] * elementShrinkage.x), (1 / (1 + distance[i] * elementShrinkage.y))));
|
||||
arrayElementRT.transform.localScale = new Vector3(scale.x, scale.y, 1f);
|
||||
}
|
||||
|
||||
float minDistance = Mathf.Min(distance);
|
||||
int oldFocusedElement = FocusedElementIndex;
|
||||
|
||||
for (var i = 0; i < arrayOfElements.Length; i++)
|
||||
{
|
||||
arrayOfElements[i].GetComponent<CanvasGroup>().interactable = !disableUnfocused || minDistance == distance[i];
|
||||
if (minDistance == distance[i])
|
||||
{
|
||||
FocusedElementIndex = i;
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
var textComponentTxtMeshPro = _arrayOfElements[i].GetComponentInChildren<TMPro.TMP_Text>();
|
||||
if (textComponentTxtMeshPro != null)
|
||||
{
|
||||
result = textComponentTxtMeshPro.text;
|
||||
}
|
||||
#else
|
||||
var textComponent = arrayOfElements[i].GetComponentInChildren<Text>();
|
||||
if (textComponent != null)
|
||||
{
|
||||
Result = textComponent.text;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (FocusedElementIndex != oldFocusedElement && onFocusChanged != null)
|
||||
{
|
||||
onFocusChanged.Invoke(FocusedElementIndex);
|
||||
}
|
||||
|
||||
if (!UIExtensionsInputManager.GetMouseButton(0))
|
||||
{
|
||||
// scroll slowly to nearest element when not dragged
|
||||
ScrollingElements();
|
||||
}
|
||||
|
||||
// stop scrolling past last element from inertia
|
||||
if (stopMomentumOnEnd
|
||||
&& (arrayOfElements[0].GetComponent<RectTransform>().position.x > center.position.x
|
||||
|| arrayOfElements[arrayOfElements.Length - 1].GetComponent<RectTransform>().position.x < center.position.x))
|
||||
{
|
||||
scrollRect.velocity = Vector2.zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void ScrollingElements()
|
||||
{
|
||||
float newX = Mathf.Lerp(ScrollingPanel.anchoredPosition.x, ScrollingPanel.anchoredPosition.x + distReposition[FocusedElementIndex], Time.deltaTime * 2f);
|
||||
Vector2 newPosition = new Vector2(newX, ScrollingPanel.anchoredPosition.y);
|
||||
ScrollingPanel.anchoredPosition = newPosition;
|
||||
}
|
||||
|
||||
public void SnapToElement(int element)
|
||||
{
|
||||
float deltaElementPositionX = elementSize.rect.width / 1.2f * element;
|
||||
Vector2 newPosition = new Vector2(-deltaElementPositionX, ScrollingPanel.anchoredPosition.y);
|
||||
ScrollingPanel.anchoredPosition = newPosition;
|
||||
}
|
||||
|
||||
public void ScrollLeft()
|
||||
{
|
||||
float deltaLeft = elementSize.rect.width / 1.2f;
|
||||
Vector2 newPositionLeft = new Vector2(ScrollingPanel.anchoredPosition.x - deltaLeft, ScrollingPanel.anchoredPosition.y);
|
||||
ScrollingPanel.anchoredPosition = Vector2.Lerp(ScrollingPanel.anchoredPosition, newPositionLeft, 1);
|
||||
}
|
||||
|
||||
public void ScrollRight()
|
||||
{
|
||||
float deltaRight = elementSize.rect.width / 1.2f;// arrayOfElements[0].GetComponent<RectTransform>().rect.width;
|
||||
Vector2 newPositionRight = new Vector2(ScrollingPanel.anchoredPosition.x + deltaRight, ScrollingPanel.anchoredPosition.y);
|
||||
ScrollingPanel.anchoredPosition = newPositionRight;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8fe84cbf30cb0874091fd899fe1457d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -10,53 +10,69 @@ namespace UnityEngine.UI.Extensions
|
|||
[AddComponentMenu("Layout/Extensions/Vertical Scroller")]
|
||||
public class UIVerticalScroller : MonoBehaviour
|
||||
{
|
||||
[Tooltip("desired ScrollRect")]
|
||||
public ScrollRect scrollRect;
|
||||
[Tooltip("Center display area (position of zoomed content)")]
|
||||
public RectTransform center;
|
||||
[Tooltip("Size / spacing of elements")]
|
||||
public RectTransform elementSize;
|
||||
[Tooltip("Scale = 1/ (1+distance from center * shrinkage)")]
|
||||
public Vector2 elementShrinkage = new Vector2(1f / 200, 1f / 200);
|
||||
[Tooltip("Minimum element scale (furthest from center)")]
|
||||
public Vector2 minScale = new Vector2(0.7f, 0.7f);
|
||||
[Tooltip("Select the item to be in center on start.")]
|
||||
public int startingIndex = -1;
|
||||
[Tooltip("Stop scrolling past last element from inertia.")]
|
||||
public bool stopMomentumOnEnd = true;
|
||||
[Tooltip("Set Items out of center to not interactible.")]
|
||||
public bool disableUnfocused = true;
|
||||
[Tooltip("Button to go to the next page. (optional)")]
|
||||
public GameObject scrollUpButton;
|
||||
[Tooltip("Button to go to the previous page. (optional)")]
|
||||
public GameObject scrollDownButton;
|
||||
[Tooltip("Event fired when a specific item is clicked, exposes index number of item. (optional)")]
|
||||
public IntEvent OnButtonClicked;
|
||||
[Tooltip("Event fired when the focused item is Changed. (optional)")]
|
||||
public IntEvent OnFocusChanged;
|
||||
[HideInInspector]
|
||||
public GameObject[] _arrayOfElements;
|
||||
|
||||
public int focusedElementIndex { get; private set; }
|
||||
|
||||
public string result { get; private set; }
|
||||
|
||||
private float[] distReposition;
|
||||
private float[] distance;
|
||||
//private int elementsDistance;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("desired ScrollRect")]
|
||||
private ScrollRect scrollRect;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Elements to populate inside the scroller")]
|
||||
private GameObject[] arrayOfElements;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Center display area (position of zoomed content)")]
|
||||
private RectTransform center;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Size / spacing of elements")]
|
||||
private RectTransform elementSize;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Scale = 1/ (1+distance from center * shrinkage)")]
|
||||
private Vector2 elementShrinkage = new Vector2(1f / 200, 1f / 200);
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Minimum element scale (furthest from center)")]
|
||||
private Vector2 minScale = new Vector2(0.7f, 0.7f);
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Select the item to be in center on start.")]
|
||||
private int startingIndex = -1;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Stop scrolling past last element from inertia.")]
|
||||
private bool stopMomentumOnEnd = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Set Items out of center to not interactible.")]
|
||||
private bool disableUnfocused = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Button to go to the next page. (optional)")]
|
||||
private GameObject scrollUpButton;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Button to go to the previous page. (optional)")]
|
||||
private GameObject scrollDownButton;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Event fired when a specific item is clicked, exposes index number of item. (optional)")]
|
||||
private UnityEvent<int> onButtonClicked;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Event fired when the focused item is Changed. (optional)")]
|
||||
private UnityEvent<int> onFocusChanged;
|
||||
|
||||
public int FocusedElementIndex { get; private set; }
|
||||
|
||||
public RectTransform Center { get => center; set => center = value; }
|
||||
|
||||
public string Result { get; private set; }
|
||||
|
||||
//Scrollable area (content of desired ScrollRect)
|
||||
[HideInInspector]
|
||||
public RectTransform scrollingPanel{ get { return scrollRect.content; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor when not used as component but called from other script, don't forget to set the non-optional properties.
|
||||
/// </summary>
|
||||
public UIVerticalScroller()
|
||||
{
|
||||
}
|
||||
public RectTransform ScrollingPanel{ get { return scrollRect.content; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor when not used as component but called from other script
|
||||
|
@ -66,7 +82,7 @@ namespace UnityEngine.UI.Extensions
|
|||
this.center = center;
|
||||
this.elementSize = elementSize;
|
||||
this.scrollRect = scrollRect;
|
||||
_arrayOfElements = arrayOfElements;
|
||||
this.arrayOfElements = arrayOfElements;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -78,21 +94,28 @@ namespace UnityEngine.UI.Extensions
|
|||
{
|
||||
scrollRect = GetComponent<ScrollRect>();
|
||||
}
|
||||
|
||||
if (!center)
|
||||
{
|
||||
Debug.LogError("Please define the RectTransform for the Center viewport of the scrollable area");
|
||||
}
|
||||
|
||||
if (!elementSize)
|
||||
{
|
||||
elementSize = center;
|
||||
}
|
||||
if (_arrayOfElements == null || _arrayOfElements.Length == 0)
|
||||
|
||||
if (arrayOfElements == null || arrayOfElements.Length == 0)
|
||||
{
|
||||
_arrayOfElements = new GameObject[scrollingPanel.childCount];
|
||||
for (int i = 0; i < scrollingPanel.childCount; i++)
|
||||
var childCount = ScrollingPanel.childCount;
|
||||
if (childCount > 0)
|
||||
{
|
||||
_arrayOfElements[i] = scrollingPanel.GetChild(i).gameObject;
|
||||
}
|
||||
arrayOfElements = new GameObject[childCount];
|
||||
for (int i = 0; i < childCount; i++)
|
||||
{
|
||||
arrayOfElements[i] = ScrollingPanel.GetChild(i).gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,96 +124,94 @@ namespace UnityEngine.UI.Extensions
|
|||
/// </summary>
|
||||
/// <param name="startingIndex">Starting index.</param>
|
||||
/// <param name="arrayOfElements">Array of elements.</param>
|
||||
public void updateChildren(int startingIndex = -1, GameObject[] arrayOfElements = null)
|
||||
public void UpdateChildren(int startingIndex = -1, GameObject[] arrayOfElements = null)
|
||||
{
|
||||
// Set _arrayOfElements to arrayOfElements if given, otherwise to child objects of the scrolling panel.
|
||||
if (arrayOfElements != null)
|
||||
{
|
||||
_arrayOfElements = arrayOfElements;
|
||||
this.arrayOfElements = arrayOfElements;
|
||||
}
|
||||
else
|
||||
{
|
||||
_arrayOfElements = new GameObject[scrollingPanel.childCount];
|
||||
for (int i = 0; i < scrollingPanel.childCount; i++)
|
||||
this.arrayOfElements = new GameObject[ScrollingPanel.childCount];
|
||||
for (int i = 0; i < ScrollingPanel.childCount; i++)
|
||||
{
|
||||
_arrayOfElements[i] = scrollingPanel.GetChild(i).gameObject;
|
||||
this.arrayOfElements[i] = ScrollingPanel.GetChild(i).gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
// resize the elements to match elementSize rect
|
||||
for (var i = 0; i < _arrayOfElements.Length; i++)
|
||||
for (var i = 0; i < this.arrayOfElements.Length; i++)
|
||||
{
|
||||
int j = i;
|
||||
_arrayOfElements[i].GetComponent<Button>().onClick.RemoveAllListeners();
|
||||
if (OnButtonClicked != null)
|
||||
{
|
||||
_arrayOfElements[i].GetComponent<Button>().onClick.AddListener(() => OnButtonClicked.Invoke(j));
|
||||
}
|
||||
RectTransform r = _arrayOfElements[i].GetComponent<RectTransform>();
|
||||
AddListener(arrayOfElements[i], i);
|
||||
|
||||
RectTransform r = this.arrayOfElements[i].GetComponent<RectTransform>();
|
||||
r.anchorMax = r.anchorMin = r.pivot = new Vector2(0.5f, 0.5f);
|
||||
r.localPosition = new Vector2(0, i * elementSize.rect.size.y);
|
||||
r.sizeDelta = elementSize.rect.size;
|
||||
}
|
||||
|
||||
// prepare for scrolling
|
||||
distance = new float[_arrayOfElements.Length];
|
||||
distReposition = new float[_arrayOfElements.Length];
|
||||
focusedElementIndex = -1;
|
||||
|
||||
//scrollRect.scrollSensitivity = elementSize.rect.height / 5;
|
||||
distance = new float[this.arrayOfElements.Length];
|
||||
distReposition = new float[this.arrayOfElements.Length];
|
||||
FocusedElementIndex = -1;
|
||||
|
||||
// if starting index is given, snap to respective element
|
||||
if (startingIndex > -1)
|
||||
{
|
||||
startingIndex = startingIndex > _arrayOfElements.Length ? _arrayOfElements.Length - 1 : startingIndex;
|
||||
startingIndex = startingIndex > this.arrayOfElements.Length ? this.arrayOfElements.Length - 1 : startingIndex;
|
||||
SnapToElement(startingIndex);
|
||||
}
|
||||
}
|
||||
private void AddListener(GameObject button, int index)
|
||||
{
|
||||
var buttonClick = button.GetComponent<Button>();
|
||||
buttonClick.onClick.RemoveAllListeners();
|
||||
buttonClick.onClick.AddListener(() => onButtonClicked?.Invoke(index));
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
|
||||
if (scrollUpButton)
|
||||
scrollUpButton.GetComponent<Button>().onClick.AddListener(() =>
|
||||
{
|
||||
ScrollUp();
|
||||
});
|
||||
|
||||
{
|
||||
scrollUpButton.GetComponent<Button>().onClick.AddListener(() => ScrollUp());
|
||||
}
|
||||
if (scrollDownButton)
|
||||
scrollDownButton.GetComponent<Button>().onClick.AddListener(() =>
|
||||
{
|
||||
ScrollDown();
|
||||
});
|
||||
updateChildren(startingIndex, _arrayOfElements);
|
||||
{
|
||||
scrollDownButton.GetComponent<Button>().onClick.AddListener(() => ScrollDown());
|
||||
}
|
||||
UpdateChildren(startingIndex, arrayOfElements);
|
||||
}
|
||||
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_arrayOfElements.Length < 1)
|
||||
if (arrayOfElements.Length < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _arrayOfElements.Length; i++)
|
||||
for (var i = 0; i < arrayOfElements.Length; i++)
|
||||
{
|
||||
distReposition[i] = center.GetComponent<RectTransform>().position.y - _arrayOfElements[i].GetComponent<RectTransform>().position.y;
|
||||
var arrayElementRT = arrayOfElements[i].GetComponent<RectTransform>();
|
||||
|
||||
distReposition[i] = center.position.y - arrayElementRT.position.y;
|
||||
distance[i] = Mathf.Abs(distReposition[i]);
|
||||
|
||||
//Magnifying effect
|
||||
Vector2 scale = Vector2.Max(minScale, new Vector2(1 / (1 + distance[i] * elementShrinkage.x), (1 / (1 + distance[i] * elementShrinkage.y))));
|
||||
_arrayOfElements[i].GetComponent<RectTransform>().transform.localScale = new Vector3(scale.x, scale.y, 1f);
|
||||
arrayElementRT.transform.localScale = new Vector3(scale.x, scale.y, 1f);
|
||||
}
|
||||
|
||||
// detect focused element
|
||||
float minDistance = Mathf.Min(distance);
|
||||
int oldFocusedElement = focusedElementIndex;
|
||||
for (var i = 0; i < _arrayOfElements.Length; i++)
|
||||
int oldFocusedElement = FocusedElementIndex;
|
||||
|
||||
for (var i = 0; i < arrayOfElements.Length; i++)
|
||||
{
|
||||
_arrayOfElements[i].GetComponent<CanvasGroup>().interactable = !disableUnfocused || minDistance == distance[i];
|
||||
arrayOfElements[i].GetComponent<CanvasGroup>().interactable = !disableUnfocused || minDistance == distance[i];
|
||||
if (minDistance == distance[i])
|
||||
{
|
||||
focusedElementIndex = i;
|
||||
FocusedElementIndex = i;
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
var textComponentTxtMeshPro = _arrayOfElements[i].GetComponentInChildren<TMPro.TMP_Text>();
|
||||
if (textComponentTxtMeshPro != null)
|
||||
|
@ -198,19 +219,19 @@ namespace UnityEngine.UI.Extensions
|
|||
result = textComponentTxtMeshPro.text;
|
||||
}
|
||||
#else
|
||||
var textComponent = _arrayOfElements[i].GetComponentInChildren<Text>();
|
||||
var textComponent = arrayOfElements[i].GetComponentInChildren<Text>();
|
||||
if (textComponent != null)
|
||||
{
|
||||
result = textComponent.text;
|
||||
Result = textComponent.text;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (focusedElementIndex != oldFocusedElement && OnFocusChanged != null)
|
||||
{
|
||||
OnFocusChanged.Invoke(focusedElementIndex);
|
||||
}
|
||||
|
||||
if (FocusedElementIndex != oldFocusedElement)
|
||||
{
|
||||
onFocusChanged?.Invoke(FocusedElementIndex);
|
||||
}
|
||||
|
||||
if (!UIExtensionsInputManager.GetMouseButton(0))
|
||||
{
|
||||
|
@ -218,11 +239,10 @@ namespace UnityEngine.UI.Extensions
|
|||
ScrollingElements();
|
||||
}
|
||||
|
||||
|
||||
// stop scrolling past last element from inertia
|
||||
if (stopMomentumOnEnd
|
||||
&& (_arrayOfElements[0].GetComponent<RectTransform>().position.y > center.position.y
|
||||
|| _arrayOfElements[_arrayOfElements.Length - 1].GetComponent<RectTransform>().position.y < center.position.y))
|
||||
&& (arrayOfElements[0].GetComponent<RectTransform>().position.y > center.position.y
|
||||
|| arrayOfElements[arrayOfElements.Length - 1].GetComponent<RectTransform>().position.y < center.position.y))
|
||||
{
|
||||
scrollRect.velocity = Vector2.zero;
|
||||
}
|
||||
|
@ -230,37 +250,30 @@ namespace UnityEngine.UI.Extensions
|
|||
|
||||
private void ScrollingElements()
|
||||
{
|
||||
float newY = Mathf.Lerp(scrollingPanel.anchoredPosition.y, scrollingPanel.anchoredPosition.y + distReposition[focusedElementIndex], Time.deltaTime * 2f);
|
||||
Vector2 newPosition = new Vector2(scrollingPanel.anchoredPosition.x, newY);
|
||||
scrollingPanel.anchoredPosition = newPosition;
|
||||
float newY = Mathf.Lerp(ScrollingPanel.anchoredPosition.y, ScrollingPanel.anchoredPosition.y + distReposition[FocusedElementIndex], Time.deltaTime * 2f);
|
||||
Vector2 newPosition = new Vector2(ScrollingPanel.anchoredPosition.x, newY);
|
||||
ScrollingPanel.anchoredPosition = newPosition;
|
||||
}
|
||||
|
||||
public void SnapToElement(int element)
|
||||
{
|
||||
float deltaElementPositionY = elementSize.rect.height * element;
|
||||
Vector2 newPosition = new Vector2(scrollingPanel.anchoredPosition.x, -deltaElementPositionY);
|
||||
scrollingPanel.anchoredPosition = newPosition;
|
||||
|
||||
Vector2 newPosition = new Vector2(ScrollingPanel.anchoredPosition.x, -deltaElementPositionY);
|
||||
ScrollingPanel.anchoredPosition = newPosition;
|
||||
}
|
||||
|
||||
public void ScrollUp()
|
||||
{
|
||||
float deltaUp = elementSize.rect.height / 1.2f;
|
||||
Vector2 newPositionUp = new Vector2(scrollingPanel.anchoredPosition.x, scrollingPanel.anchoredPosition.y - deltaUp);
|
||||
scrollingPanel.anchoredPosition = Vector2.Lerp(scrollingPanel.anchoredPosition, newPositionUp, 1);
|
||||
Vector2 newPositionUp = new Vector2(ScrollingPanel.anchoredPosition.x, ScrollingPanel.anchoredPosition.y - deltaUp);
|
||||
ScrollingPanel.anchoredPosition = Vector2.Lerp(ScrollingPanel.anchoredPosition, newPositionUp, 1);
|
||||
}
|
||||
|
||||
public void ScrollDown()
|
||||
{
|
||||
float deltaDown = elementSize.rect.height / 1.2f;
|
||||
Vector2 newPositionDown = new Vector2(scrollingPanel.anchoredPosition.x, scrollingPanel.anchoredPosition.y + deltaDown);
|
||||
scrollingPanel.anchoredPosition = newPositionDown;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class IntEvent:UnityEvent<int>
|
||||
{
|
||||
|
||||
Vector2 newPositionDown = new Vector2(ScrollingPanel.anchoredPosition.x, ScrollingPanel.anchoredPosition.y + deltaDown);
|
||||
ScrollingPanel.anchoredPosition = newPositionDown;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue