Update release from development

pull/413/head
Simon (Darkside) Jackson 2021-05-10 19:36:52 +01:00
commit f1f3f8fda9
16 changed files with 500 additions and 274 deletions

View File

@ -806,7 +806,8 @@ namespace UnityEditor.UI
//Setup Template //Setup Template
itemTemplate.name = "ItemTemplate"; itemTemplate.name = "ItemTemplate";
var itemTemplateRT = itemTemplate.GetComponent<RectTransform>(); var itemTemplateRT = itemTemplate.GetComponent<RectTransform>();
itemTemplateRT.sizeDelta = cbbRT.sizeDelta; itemTemplateRT.sizeDelta = cbbRT.sizeDelta - new Vector2(10,0);
itemTemplateRT.anchoredPosition = new Vector2(-5, 0);
var itemTemplateButton = itemTemplate.GetComponent<Button>(); var itemTemplateButton = itemTemplate.GetComponent<Button>();
itemTemplateButton.transition = Selectable.Transition.None; itemTemplateButton.transition = Selectable.Transition.None;
var itemTemplateLayoutElement = itemTemplate.AddComponent<LayoutElement>(); var itemTemplateLayoutElement = itemTemplate.AddComponent<LayoutElement>();
@ -902,7 +903,8 @@ namespace UnityEditor.UI
//Setup Template //Setup Template
itemTemplate.name = "ItemTemplate"; itemTemplate.name = "ItemTemplate";
var itemTemplateRT = itemTemplate.GetComponent<RectTransform>(); var itemTemplateRT = itemTemplate.GetComponent<RectTransform>();
itemTemplateRT.sizeDelta = cbbRT.sizeDelta; itemTemplateRT.sizeDelta = cbbRT.sizeDelta - new Vector2(10, 0);
itemTemplateRT.anchoredPosition = new Vector2(-5, 0);
var itemTemplateButton = itemTemplate.GetComponent<Button>(); var itemTemplateButton = itemTemplate.GetComponent<Button>();
itemTemplateButton.transition = Selectable.Transition.None; itemTemplateButton.transition = Selectable.Transition.None;
var itemTemplateLayoutElement = itemTemplate.AddComponent<LayoutElement>(); var itemTemplateLayoutElement = itemTemplate.AddComponent<LayoutElement>();
@ -1002,7 +1004,8 @@ namespace UnityEditor.UI
//Setup Template //Setup Template
itemTemplate.name = "ItemTemplate"; itemTemplate.name = "ItemTemplate";
var itemTemplateRT = itemTemplate.GetComponent<RectTransform>(); var itemTemplateRT = itemTemplate.GetComponent<RectTransform>();
itemTemplateRT.sizeDelta = cbbRT.sizeDelta; itemTemplateRT.sizeDelta = cbbRT.sizeDelta - new Vector2(10, 0);
itemTemplateRT.anchoredPosition = new Vector2(-5, 0);
var itemTemplateButton = itemTemplate.GetComponent<Button>(); var itemTemplateButton = itemTemplate.GetComponent<Button>();
itemTemplateButton.transition = Selectable.Transition.None; itemTemplateButton.transition = Selectable.Transition.None;
var itemTemplateLayoutElement = itemTemplate.AddComponent<LayoutElement>(); var itemTemplateLayoutElement = itemTemplate.AddComponent<LayoutElement>();

View File

@ -63,7 +63,7 @@ namespace UnityEngine.UI.Extensions
LayoutElement le = this.gameObject.GetComponent<LayoutElement>(); LayoutElement le = this.gameObject.GetComponent<LayoutElement>();
if (le != null) if (le != null && m_Accordion != null)
{ {
if (this.isOn) if (this.isOn)
{ {
@ -99,7 +99,7 @@ namespace UnityEngine.UI.Extensions
Accordion.Transition transition = (this.m_Accordion != null) ? this.m_Accordion.transition : Accordion.Transition.Instant; Accordion.Transition transition = (this.m_Accordion != null) ? this.m_Accordion.transition : Accordion.Transition.Instant;
if (transition == Accordion.Transition.Instant) if (transition == Accordion.Transition.Instant && m_Accordion != null)
{ {
if (state) if (state)
{ {

View File

@ -19,6 +19,11 @@ namespace UnityEngine.UI.Extensions
public Color disabledTextColor; public Color disabledTextColor;
public DropDownListItem SelectedItem { get; private set; } //outside world gets to get this, not set it public DropDownListItem SelectedItem { get; private set; } //outside world gets to get this, not set it
/// <summary>
/// Contains the included items. To add and remove items to/from this list, use the <see cref="AddItem(string)"/>,
/// <see cref="RemoveItem(string)"/> and <see cref="SetAvailableOptions(List{string})"/> methods as these also execute
/// the required methods to update to the current collection.
/// </summary>
public List<string> AvailableOptions; public List<string> AvailableOptions;
//private bool isInitialized = false; //private bool isInitialized = false;
@ -36,7 +41,7 @@ namespace UnityEngine.UI.Extensions
private RectTransform _scrollPanelRT; private RectTransform _scrollPanelRT;
private RectTransform _scrollBarRT; private RectTransform _scrollBarRT;
private RectTransform _slidingAreaRT; private RectTransform _slidingAreaRT;
// private RectTransform scrollHandleRT; private RectTransform _scrollHandleRT;
private RectTransform _itemsPanelRT; private RectTransform _itemsPanelRT;
private Canvas _canvas; private Canvas _canvas;
private RectTransform _canvasRT; private RectTransform _canvasRT;
@ -104,6 +109,9 @@ namespace UnityEngine.UI.Extensions
public AutoCompleteSearchType autocompleteSearchType = AutoCompleteSearchType.Linq; public AutoCompleteSearchType autocompleteSearchType = AutoCompleteSearchType.Linq;
[SerializeField]
private bool _displayPanelAbove = false;
private bool _selectionIsValid = false; private bool _selectionIsValid = false;
[System.Serializable] [System.Serializable]
@ -129,13 +137,15 @@ namespace UnityEngine.UI.Extensions
{ {
Initialize(); Initialize();
} }
public void Start() public void Start()
{ {
if (SelectFirstItemOnStart && AvailableOptions.Count > 0) { if (SelectFirstItemOnStart && AvailableOptions.Count > 0) {
ToggleDropdownPanel (false); ToggleDropdownPanel (false);
OnItemClicked (AvailableOptions [0]); OnItemClicked (AvailableOptions [0]);
} }
} RedrawPanel();
}
private bool Initialize() private bool Initialize()
{ {
@ -155,7 +165,7 @@ namespace UnityEngine.UI.Extensions
_scrollPanelRT = _overlayRT.Find("ScrollPanel").GetComponent<RectTransform>(); _scrollPanelRT = _overlayRT.Find("ScrollPanel").GetComponent<RectTransform>();
_scrollBarRT = _scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>(); _scrollBarRT = _scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>();
_slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>(); _slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>();
// scrollHandleRT = slidingAreaRT.FindChild("Handle").GetComponent<RectTransform>(); _scrollHandleRT = _slidingAreaRT.Find("Handle").GetComponent<RectTransform>();
_itemsPanelRT = _scrollPanelRT.Find("Items").GetComponent<RectTransform>(); _itemsPanelRT = _scrollPanelRT.Find("Items").GetComponent<RectTransform>();
//itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>(); //itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>();
@ -182,39 +192,75 @@ namespace UnityEngine.UI.Extensions
_panelItems = new List<string>(); _panelItems = new List<string>();
RebuildPanel(); RebuildPanel();
//RedrawPanel(); - causes an initialisation failure in U5
return success; return success;
} }
/// <summary>
/// Adds the item to <see cref="this.AvailableOptions"/> if it is not a duplicate and rebuilds the panel.
/// </summary>
/// <param name="item">Item to add.</param>
public void AddItem(string item) public void AddItem(string item)
{ {
AvailableOptions.Add(item); if (!this.AvailableOptions.Contains(item))
RebuildPanel(); {
this.AvailableOptions.Add(item);
this.RebuildPanel();
}
else
{
Debug.LogWarning($"{nameof(AutoCompleteComboBox)}.{nameof(AddItem)}: items may only exists once. '{item}' can not be added.");
}
} }
/// <summary>
/// Removes the item from <see cref="this.AvailableOptions"/> and rebuilds the panel.
/// </summary>
/// <param name="item">Item to remove.</param>
public void RemoveItem(string item) public void RemoveItem(string item)
{ {
AvailableOptions.Remove(item); if (this.AvailableOptions.Contains(item))
RebuildPanel(); {
this.AvailableOptions.Remove(item);
this.RebuildPanel();
}
} }
/// <summary>
/// Sets the given items as new content for the comboBox. Previous entries will be cleared.
/// </summary>
/// <param name="newOptions">New entries.</param>
public void SetAvailableOptions(List<string> newOptions) public void SetAvailableOptions(List<string> newOptions)
{ {
AvailableOptions.Clear(); var uniqueOptions = newOptions.Distinct().ToList();
AvailableOptions = newOptions; if (newOptions.Count != uniqueOptions.Count)
RebuildPanel();
}
public void SetAvailableOptions(string[] newOptions)
{
AvailableOptions.Clear();
for (int i = 0; i < newOptions.Length; i++)
{ {
AvailableOptions.Add(newOptions[i]); Debug.LogWarning($"{nameof(AutoCompleteComboBox)}.{nameof(SetAvailableOptions)}: items may only exists once. {newOptions.Count - uniqueOptions.Count} duplicates.");
} }
RebuildPanel(); this.AvailableOptions.Clear();
this.AvailableOptions = uniqueOptions;
this.RebuildPanel();
}
/// <summary>
/// Sets the given items as new content for the comboBox. Previous entries will be cleared.
/// </summary>
/// <param name="newOptions">New entries.</param>
public void SetAvailableOptions(string[] newOptions)
{
var uniqueOptions = newOptions.Distinct().ToList();
if (newOptions.Length != uniqueOptions.Count)
{
Debug.LogWarning($"{nameof(AutoCompleteComboBox)}.{nameof(SetAvailableOptions)}: items may only exists once. {newOptions.Length - uniqueOptions.Count} duplicates.");
}
this.AvailableOptions.Clear();
for (int i = 0; i < newOptions.Length; i++)
{
this.AvailableOptions.Add(newOptions[i]);
}
this.RebuildPanel();
} }
public void ResetItems() public void ResetItems()
@ -264,7 +310,7 @@ namespace UnityEngine.UI.Extensions
if (i < AvailableOptions.Count) if (i < AvailableOptions.Count)
{ {
itemObjs[i].name = "Item " + i + " " + _panelItems[i]; itemObjs[i].name = "Item " + i + " " + _panelItems[i];
itemObjs[i].transform.Find("Text").GetComponent<Text>().text = _panelItems[i]; //set the text value itemObjs[i].transform.Find("Text").GetComponent<Text>().text = AvailableOptions[i]; //set the text value
Button itemBtn = itemObjs[i].GetComponent<Button>(); Button itemBtn = itemObjs[i].GetComponent<Button>();
itemBtn.onClick.RemoveAllListeners(); itemBtn.onClick.RemoveAllListeners();
@ -331,7 +377,9 @@ namespace UnityEngine.UI.Extensions
_inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y); _inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y);
_scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay _scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay
_scrollPanelRT.anchoredPosition = new Vector2(0, -_rectTransform.sizeDelta.y); //anchor it to the bottom of the button _scrollPanelRT.anchoredPosition = _displayPanelAbove ?
new Vector2(0, DropdownOffset + _rectTransform.sizeDelta.y * _panelItems.Count - 1) :
new Vector2(0, -_rectTransform.sizeDelta.y);
//make the overlay fill the screen //make the overlay fill the screen
_overlayRT.SetParent(_canvas.transform, false); //attach it to top level object _overlayRT.SetParent(_canvas.transform, false); //attach it to top level object
@ -354,6 +402,7 @@ namespace UnityEngine.UI.Extensions
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth); _scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight); _scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
if (scrollbarWidth == 0) _scrollHandleRT.gameObject.SetActive(false); else _scrollHandleRT.gameObject.SetActive(true);
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0); _slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x); _slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x);

View File

@ -21,8 +21,12 @@ namespace UnityEngine.UI.Extensions
[SerializeField] [SerializeField]
private int _itemsToDisplay; private int _itemsToDisplay;
//Sorting disabled as it causes issues.
//[SerializeField]
//private bool _sortItems = true;
[SerializeField] [SerializeField]
private bool _sortItems = true; private bool _displayPanelAbove = false;
[System.Serializable] [System.Serializable]
public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<string> public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<string>
@ -45,7 +49,7 @@ namespace UnityEngine.UI.Extensions
private RectTransform _scrollPanelRT; private RectTransform _scrollPanelRT;
private RectTransform _scrollBarRT; private RectTransform _scrollBarRT;
private RectTransform _slidingAreaRT; private RectTransform _slidingAreaRT;
// private RectTransform scrollHandleRT; private RectTransform _scrollHandleRT;
private RectTransform _itemsPanelRT; private RectTransform _itemsPanelRT;
private Canvas _canvas; private Canvas _canvas;
private RectTransform _canvasRT; private RectTransform _canvasRT;
@ -88,6 +92,11 @@ namespace UnityEngine.UI.Extensions
Initialize(); Initialize();
} }
public void Start()
{
RedrawPanel();
}
private bool Initialize() private bool Initialize()
{ {
bool success = true; bool success = true;
@ -104,7 +113,7 @@ namespace UnityEngine.UI.Extensions
_scrollPanelRT = _overlayRT.Find("ScrollPanel").GetComponent<RectTransform>(); _scrollPanelRT = _overlayRT.Find("ScrollPanel").GetComponent<RectTransform>();
_scrollBarRT = _scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>(); _scrollBarRT = _scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>();
_slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>(); _slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>();
// scrollHandleRT = slidingAreaRT.FindChild("Handle").GetComponent<RectTransform>(); _scrollHandleRT = _slidingAreaRT.Find("Handle").GetComponent<RectTransform>();
_itemsPanelRT = _scrollPanelRT.Find("Items").GetComponent<RectTransform>(); _itemsPanelRT = _scrollPanelRT.Find("Items").GetComponent<RectTransform>();
//itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>(); //itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>();
@ -181,7 +190,7 @@ namespace UnityEngine.UI.Extensions
{ {
_panelItems.Add(option.ToLower()); _panelItems.Add(option.ToLower());
} }
if(_sortItems) _panelItems.Sort(); //if(_sortItems) _panelItems.Sort();
List<GameObject> itemObjs = new List<GameObject>(panelObjects.Values); List<GameObject> itemObjs = new List<GameObject>(panelObjects.Values);
panelObjects.Clear(); panelObjects.Clear();
@ -202,7 +211,7 @@ namespace UnityEngine.UI.Extensions
if (i < AvailableOptions.Count) if (i < AvailableOptions.Count)
{ {
itemObjs[i].name = "Item " + i + " " + _panelItems[i]; itemObjs[i].name = "Item " + i + " " + _panelItems[i];
itemObjs[i].transform.Find("Text").GetComponent<Text>().text = _panelItems[i]; //set the text value itemObjs[i].transform.Find("Text").GetComponent<Text>().text = AvailableOptions[i]; //set the text value
Button itemBtn = itemObjs[i].GetComponent<Button>(); Button itemBtn = itemObjs[i].GetComponent<Button>();
itemBtn.onClick.RemoveAllListeners(); itemBtn.onClick.RemoveAllListeners();
@ -268,7 +277,9 @@ namespace UnityEngine.UI.Extensions
_inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y); _inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y);
_scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay _scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay
_scrollPanelRT.anchoredPosition = new Vector2(0, -_rectTransform.sizeDelta.y); //anchor it to the bottom of the button _scrollPanelRT.anchoredPosition = _displayPanelAbove ?
new Vector2(0, _rectTransform.sizeDelta.y * ItemsToDisplay - 1) :
new Vector2(0, -_rectTransform.sizeDelta.y);
//make the overlay fill the screen //make the overlay fill the screen
_overlayRT.SetParent(_canvas.transform, false); //attach it to top level object _overlayRT.SetParent(_canvas.transform, false); //attach it to top level object
@ -291,6 +302,7 @@ namespace UnityEngine.UI.Extensions
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth); _scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight); _scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
if (scrollbarWidth == 0) _scrollHandleRT.gameObject.SetActive(false); else _scrollHandleRT.gameObject.SetActive(true);
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0); _slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x); _slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x);

View File

@ -31,7 +31,7 @@ namespace UnityEngine.UI.Extensions
private RectTransform _scrollPanelRT; private RectTransform _scrollPanelRT;
private RectTransform _scrollBarRT; private RectTransform _scrollBarRT;
private RectTransform _slidingAreaRT; private RectTransform _slidingAreaRT;
// private RectTransform scrollHandleRT; private RectTransform _scrollHandleRT;
private RectTransform _itemsPanelRT; private RectTransform _itemsPanelRT;
private Canvas _canvas; private Canvas _canvas;
private RectTransform _canvasRT; private RectTransform _canvasRT;
@ -57,7 +57,6 @@ namespace UnityEngine.UI.Extensions
// private int scrollOffset; //offset of the selected item // private int scrollOffset; //offset of the selected item
private int _selectedIndex = -1; private int _selectedIndex = -1;
[SerializeField] [SerializeField]
private int _itemsToDisplay; private int _itemsToDisplay;
public int ItemsToDisplay public int ItemsToDisplay
@ -72,6 +71,9 @@ namespace UnityEngine.UI.Extensions
public bool SelectFirstItemOnStart = false; public bool SelectFirstItemOnStart = false;
[SerializeField]
private bool _displayPanelAbove = false;
[System.Serializable] [System.Serializable]
public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<int> { public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<int> {
} }
@ -86,6 +88,7 @@ namespace UnityEngine.UI.Extensions
ToggleDropdownPanel (false); ToggleDropdownPanel (false);
OnItemClicked (0); OnItemClicked (0);
} }
RedrawPanel();
} }
private bool Initialize() private bool Initialize()
@ -103,7 +106,7 @@ namespace UnityEngine.UI.Extensions
_scrollPanelRT = _overlayRT.Find("ScrollPanel").GetComponent<RectTransform>(); _scrollPanelRT = _overlayRT.Find("ScrollPanel").GetComponent<RectTransform>();
_scrollBarRT = _scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>(); _scrollBarRT = _scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>();
_slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>(); _slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>();
// scrollHandleRT = slidingAreaRT.FindChild("Handle").GetComponent<RectTransform>(); _scrollHandleRT = _slidingAreaRT.Find("Handle").GetComponent<RectTransform>();
_itemsPanelRT = _scrollPanelRT.Find("Items").GetComponent<RectTransform>(); _itemsPanelRT = _scrollPanelRT.Find("Items").GetComponent<RectTransform>();
//itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>(); //itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>();
@ -332,7 +335,9 @@ namespace UnityEngine.UI.Extensions
_mainButton.txt.rectTransform.offsetMax = new Vector2(4, 0); _mainButton.txt.rectTransform.offsetMax = new Vector2(4, 0);
_scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay _scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay
_scrollPanelRT.anchoredPosition = new Vector2(0, -_rectTransform.sizeDelta.y); //anchor it to the bottom of the button _scrollPanelRT.anchoredPosition = _displayPanelAbove ?
new Vector2(0, _rectTransform.sizeDelta.y * ItemsToDisplay - 1) :
new Vector2(0, -_rectTransform.sizeDelta.y);
//make the overlay fill the screen //make the overlay fill the screen
_overlayRT.SetParent(_canvas.transform, false); //attach it to top level object _overlayRT.SetParent(_canvas.transform, false); //attach it to top level object
@ -355,6 +360,7 @@ namespace UnityEngine.UI.Extensions
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth); _scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight); _scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
if (scrollbarWidth == 0) _scrollHandleRT.gameObject.SetActive(false); else _scrollHandleRT.gameObject.SetActive(true);
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0); _slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x); _slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x);

View File

@ -563,7 +563,10 @@ namespace UnityEngine.UI.Extensions
{ {
//outside the handles, move the entire slider along //outside the handles, move the entire slider along
UpdateDrag(eventData, eventData.pressEventCamera); UpdateDrag(eventData, eventData.pressEventCamera);
interactionState = InteractionState.Bar; if (eventData.pointerCurrentRaycast.gameObject == m_FillRect.gameObject)
{
interactionState = InteractionState.Bar;
}
if (transition == Transition.ColorTint) if (transition == Transition.ColorTint)
{ {
targetGraphic = m_FillImage; targetGraphic = m_FillImage;
@ -578,6 +581,7 @@ namespace UnityEngine.UI.Extensions
{ {
return; return;
} }
UpdateDrag(eventData, eventData.pressEventCamera); UpdateDrag(eventData, eventData.pressEventCamera);
} }

View File

@ -73,6 +73,11 @@ namespace UnityEngine.UI.Extensions
value = Math.Max(value, -1); value = Math.Max(value, -1);
value = Math.Min(value, segments.Length - 1); value = Math.Min(value, segments.Length - 1);
if (m_selectedSegmentIndex == value)
{
return;
}
m_selectedSegmentIndex = value; m_selectedSegmentIndex = value;
if (selectedSegment) if (selectedSegment)

View File

@ -103,7 +103,7 @@ namespace UnityEngine.UI.Extensions
private ScrollRect scrollRect = null; private ScrollRect scrollRect = null;
private RectTransform scrollRectTransform = null; private RectTransform scrollRectTransform = null;
private RectTransform contentTransform = null; private RectTransform contentTransform = null;
private List<Vector3> contentPositions = null; private List<Vector3> contentPositions = new List<Vector3>();
private Vector3 lerpTarget = Vector3.zero; private Vector3 lerpTarget = Vector3.zero;
private float totalScrollableWidth = 0; private float totalScrollableWidth = 0;
private DrivenRectTransformTracker tracker ; private DrivenRectTransformTracker tracker ;
@ -514,6 +514,11 @@ namespace UnityEngine.UI.Extensions
#region Behind the Scenes Movement stuff #region Behind the Scenes Movement stuff
public void OnBeginDrag(PointerEventData ped) public void OnBeginDrag(PointerEventData ped)
{ {
if (contentPositions.Count < 2)
{
return;
}
StopMovement(); StopMovement();
if (!Moving) if (!Moving)
{ {
@ -523,6 +528,11 @@ namespace UnityEngine.UI.Extensions
public void OnEndDrag(PointerEventData ped) public void OnEndDrag(PointerEventData ped)
{ {
if (contentPositions.Count <= 1)
{
return;
}
if (IsScrollRectAvailable) if (IsScrollRectAvailable)
{ {
StartCoroutine("SlideAndLerp"); StartCoroutine("SlideAndLerp");

View File

@ -359,11 +359,12 @@ namespace UnityEngine.UI.Extensions
/// *Note, this is based on a 0 starting index - 0 to x /// *Note, this is based on a 0 starting index - 0 to x
/// </summary> /// </summary>
/// <param name="screenIndex">0 starting index of page to jump to</param> /// <param name="screenIndex">0 starting index of page to jump to</param>
public void GoToScreen(int screenIndex) /// <param name="pagination">Override the screen movement if driven from a pagination control</param>
public void GoToScreen(int screenIndex, bool pagination = false)
{ {
if (screenIndex <= _screens - 1 && screenIndex >= 0) if (screenIndex <= _screens - 1 && screenIndex >= 0)
{ {
if (!_lerp) StartScreenChange(); if (!_lerp || pagination) StartScreenChange();
_lerp = true; _lerp = true;
CurrentPage = screenIndex; CurrentPage = screenIndex;

View File

@ -83,9 +83,17 @@ namespace UnityEngine.UI.Extensions
} }
} }
var topCanvas = menuInstance.GetComponent<Canvas>(); Canvas topCanvas = menuInstance.GetComponent<Canvas>();
var previousCanvas = menuStack.Peek().GetComponent<Canvas>(); if (topCanvas != null)
topCanvas.sortingOrder = previousCanvas.sortingOrder + 1; {
Canvas previousCanvas = menuStack.Peek().GetComponent<Canvas>();
if(previousCanvas != null)
{
topCanvas.sortingOrder = previousCanvas.sortingOrder + 1;
}
}
} }
menuStack.Push(menuInstance); menuStack.Push(menuInstance);

View File

@ -178,6 +178,7 @@ namespace UnityEngine.UI.Extensions
// Generate the quads that make up the wide line // Generate the quads that make up the wide line
var segments = new List<UIVertex[]> (); var segments = new List<UIVertex[]> ();
if (lineList) { if (lineList) {
//Loop through list in line pairs, skipping drawing between lines
for (var i = 1; i < pointsToDraw.Length; i += 2) { for (var i = 1; i < pointsToDraw.Length; i += 2) {
var start = pointsToDraw [i - 1]; var start = pointsToDraw [i - 1];
var end = pointsToDraw [i]; var end = pointsToDraw [i];
@ -188,13 +189,15 @@ namespace UnityEngine.UI.Extensions
segments.Add (CreateLineCap (start, end, SegmentType.Start)); segments.Add (CreateLineCap (start, end, SegmentType.Start));
} }
segments.Add(CreateLineSegment(start, end, SegmentType.Middle, segments.Count > 1 ? segments[segments.Count - 2] : null)); // Originally, UV's had to be wrapped per segment to ensure textures rendered correctly, however when tested in 2019.4, this no longer seems to be an issue.
segments.Add(CreateLineSegment(start, end, SegmentType.Middle));
if (lineCaps) { if (lineCaps) {
segments.Add (CreateLineCap (start, end, SegmentType.End)); segments.Add (CreateLineCap (start, end, SegmentType.End));
} }
} }
} else { } else {
//Draw full lines
for (var i = 1; i < pointsToDraw.Length; i++) { for (var i = 1; i < pointsToDraw.Length; i++) {
var start = pointsToDraw [i - 1]; var start = pointsToDraw [i - 1];
var end = pointsToDraw [i]; var end = pointsToDraw [i];
@ -459,5 +462,14 @@ namespace UnityEngine.UI.Extensions
float t = Mathf.Clamp01(dot); float t = Mathf.Clamp01(dot);
return p1 + from_p1_to_p2 * t; return p1 + from_p1_to_p2 * t;
} }
protected override void OnEnable()
{
base.OnEnable();
if (m_points.Length == 0)
{
m_points = new Vector2[1];
}
}
} }
} }

View File

@ -76,7 +76,7 @@ namespace UnityEngine.UI.Extensions
/// <param name="pageNo"></param> /// <param name="pageNo"></param>
public void GoToScreen(int pageNo) public void GoToScreen(int pageNo)
{ {
scrollSnap.GoToScreen(pageNo); scrollSnap.GoToScreen(pageNo, true);
} }

View File

@ -1,10 +1,14 @@
/// Credit SimonDarksideJ /// Credit SimonDarksideJ
/// Sourced from: https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/348/menu-manager-does-not-work-with-the-new /// Sourced from: https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/348/menu-manager-does-not-work-with-the-new
#if UNITY_2019_1_OR_NEWER && !ENABLE_LEGACY_INPUT_MANAGER
#define NEW_INPUT_SYSTEM
#endif
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Controls;
#endif #endif
@ -13,7 +17,7 @@ namespace UnityEngine.UI.Extensions
{ {
public static class UIExtensionsInputManager public static class UIExtensionsInputManager
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
private static bool[] mouseButtons = new bool[3] { false, false, false }; private static bool[] mouseButtons = new bool[3] { false, false, false };
private static Dictionary<KeyCode, bool> keys = new Dictionary<KeyCode, bool>(); private static Dictionary<KeyCode, bool> keys = new Dictionary<KeyCode, bool>();
private static Dictionary<String, bool> buttons = new Dictionary<String, bool>(); private static Dictionary<String, bool> buttons = new Dictionary<String, bool>();
@ -21,7 +25,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetMouseButton(int button) public static bool GetMouseButton(int button)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
if (Mouse.current == null) if (Mouse.current == null)
{ {
return false; return false;
@ -35,7 +39,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetMouseButtonDown(int button) public static bool GetMouseButtonDown(int button)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
if (Mouse.current == null) if (Mouse.current == null)
{ {
return false; return false;
@ -57,7 +61,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetMouseButtonUp(int button) public static bool GetMouseButtonUp(int button)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
if (Mouse.current == null) if (Mouse.current == null)
{ {
return false; return false;
@ -76,7 +80,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetButton(string input) public static bool GetButton(string input)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
ButtonControl buttonPressed = GetButtonControlFromString(input); ButtonControl buttonPressed = GetButtonControlFromString(input);
if (!buttons.ContainsKey(input)) if (!buttons.ContainsKey(input))
@ -90,7 +94,7 @@ namespace UnityEngine.UI.Extensions
#endif #endif
} }
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
private static ButtonControl GetButtonControlFromString(string input) private static ButtonControl GetButtonControlFromString(string input)
{ {
if (Gamepad.current == null) if (Gamepad.current == null)
@ -112,7 +116,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetButtonDown(string input) public static bool GetButtonDown(string input)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
ButtonControl buttonPressed = GetButtonControlFromString(input); ButtonControl buttonPressed = GetButtonControlFromString(input);
if (buttonPressed.isPressed) if (buttonPressed.isPressed)
@ -140,7 +144,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetButtonUp(string input) public static bool GetButtonUp(string input)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
ButtonControl buttonPressed = GetButtonControlFromString(input); ButtonControl buttonPressed = GetButtonControlFromString(input);
if (buttons[input] && !buttonPressed.isPressed) if (buttons[input] && !buttonPressed.isPressed)
@ -156,7 +160,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetKey(KeyCode key) public static bool GetKey(KeyCode key)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
KeyControl keyPressed = GetKeyControlFromKeyCode(key); KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (!keys.ContainsKey(key)) if (!keys.ContainsKey(key))
{ {
@ -169,7 +173,7 @@ namespace UnityEngine.UI.Extensions
#endif #endif
} }
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
private static KeyControl GetKeyControlFromKeyCode(KeyCode key) private static KeyControl GetKeyControlFromKeyCode(KeyCode key)
{ {
if (Keyboard.current == null) if (Keyboard.current == null)
@ -203,7 +207,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetKeyDown(KeyCode key) public static bool GetKeyDown(KeyCode key)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
KeyControl keyPressed = GetKeyControlFromKeyCode(key); KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (keyPressed.isPressed) if (keyPressed.isPressed)
{ {
@ -230,7 +234,7 @@ namespace UnityEngine.UI.Extensions
public static bool GetKeyUp(KeyCode key) public static bool GetKeyUp(KeyCode key)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
KeyControl keyPressed = GetKeyControlFromKeyCode(key); KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (keys[key] && !keyPressed.isPressed) if (keys[key] && !keyPressed.isPressed)
{ {
@ -245,7 +249,7 @@ namespace UnityEngine.UI.Extensions
public static float GetAxisRaw(string axis) public static float GetAxisRaw(string axis)
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
if (Gamepad.current == null) if (Gamepad.current == null)
{ {
return 0f; return 0f;
@ -269,7 +273,7 @@ namespace UnityEngine.UI.Extensions
{ {
get get
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
return Mouse.current.position.ReadValue(); return Mouse.current.position.ReadValue();
#else #else
return Input.mousePosition; return Input.mousePosition;
@ -281,7 +285,7 @@ namespace UnityEngine.UI.Extensions
{ {
get get
{ {
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER #if NEW_INPUT_SYSTEM
return Mouse.current.position.ReadValue(); return Mouse.current.position.ReadValue();
#else #else
return Input.mouseScrollDelta; return Input.mouseScrollDelta;

View File

@ -11,7 +11,7 @@ namespace UnityEngine.UI.Extensions
// The elements between which line segments should be drawn // The elements between which line segments should be drawn
public RectTransform[] transforms; public RectTransform[] transforms;
private Vector2[] previousPositions; private Vector3[] previousPositions;
private RectTransform canvas; private RectTransform canvas;
private RectTransform rt; private RectTransform rt;
private UILineRenderer lr; private UILineRenderer lr;
@ -36,7 +36,7 @@ namespace UnityEngine.UI.Extensions
bool updateLine = false; bool updateLine = false;
for (int i = 0; i < transforms.Length; i++) for (int i = 0; i < transforms.Length; i++)
{ {
if (!updateLine && previousPositions[i] != transforms[i].anchoredPosition) if (!updateLine && previousPositions[i] != transforms[i].position)
{ {
updateLine = true; updateLine = true;
} }
@ -76,10 +76,10 @@ namespace UnityEngine.UI.Extensions
lr.RelativeSize = false; lr.RelativeSize = false;
lr.drivenExternally = true; lr.drivenExternally = true;
previousPositions = new Vector2[transforms.Length]; previousPositions = new Vector3[transforms.Length];
for (int i = 0; i < transforms.Length; i++) for (int i = 0; i < transforms.Length; i++)
{ {
previousPositions[i] = transforms[i].anchoredPosition; previousPositions[i] = transforms[i].position;
} }
} }
} }

View File

@ -2,225 +2,302 @@
/// sourced from: http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-2011648 /// sourced from: http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-2011648
/*USAGE: /*USAGE:
Simply place the script on the ScrollRect that contains the selectable children we'll be scrolling to Simply place the script on the ScrollRect that contains the selectable children you will be scrolling
and drag'n'drop the RectTransform of the options "container" that we'll be scrolling.*/ */
using System.Collections.Generic; using System;
using System.Collections;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions namespace UnityEngine.UI.Extensions
{ {
[RequireComponent(typeof(ScrollRect))] [RequireComponent(typeof(ScrollRect))]
[AddComponentMenu("UI/Extensions/UIScrollToSelection")] [AddComponentMenu("UI/Extensions/UIScrollToSelection")]
public class UIScrollToSelection : MonoBehaviour public class UIScrollToSelection : MonoBehaviour
{ {
#region MEMBERS
//*** ATTRIBUTES ***// [Header("[ References ]")]
[Header("[ Settings ]")] [SerializeField, Tooltip("View (boundaries/mask) rect transform. Used to check if automatic scroll to selection is required.")]
[SerializeField] private RectTransform viewportRectTransform;
private ScrollType scrollDirection = ScrollType.BOTH; [SerializeField, Tooltip("Scroll rect used to reach selected element.")]
[SerializeField] private ScrollRect targetScrollRect;
private float scrollSpeed = 10f;
[Header("[ Input ]")] [Header("[ Scrolling ]")]
[SerializeField] [SerializeField, Tooltip("Allow automatic scrolling only on these axes.")]
private bool cancelScrollOnInput = false; private Axis scrollAxes = Axis.ANY;
[SerializeField] [SerializeField, Tooltip("MOVE_TOWARDS: stiff movement, LERP: smoothed out movement")]
private List<KeyCode> cancelScrollKeycodes = new List<KeyCode>(); private ScrollMethod usedScrollMethod = ScrollMethod.MOVE_TOWARDS;
[SerializeField]
private float scrollSpeed = 50;
//*** PROPERTIES ***// [Space(5)]
// REFERENCES [SerializeField, Tooltip("Scroll speed used when element to select is out of \"JumpOffsetThreshold\" range")]
protected RectTransform LayoutListGroup private float endOfListJumpScrollSpeed = 150;
{ [SerializeField, Range(0, 1), Tooltip("If next element to scroll to is located over this screen percentage, use \"EndOfListJumpScrollSpeed\" to reach this element faster.")]
get { return TargetScrollRect != null ? TargetScrollRect.content : null; } private float jumpOffsetThreshold = 1;
}
// SETTINGS [Header("[ Input ]")]
protected ScrollType ScrollDirection [SerializeField]
{ private MouseButton cancelScrollMouseButtons = MouseButton.ANY;
get { return scrollDirection; } [SerializeField]
} private KeyCode[] cancelScrollKeys = new KeyCode[0];
protected float ScrollSpeed
{
get { return scrollSpeed; }
}
// INPUT // INTERNAL - MEMBERS ONLY
protected bool CancelScrollOnInput private Vector3[] viewRectCorners = new Vector3[4];
{ private Vector3[] selectedElementCorners = new Vector3[4];
get { return cancelScrollOnInput; }
}
protected List<KeyCode> CancelScrollKeycodes
{
get { return cancelScrollKeycodes; }
}
// CACHED REFERENCES #endregion
protected RectTransform ScrollWindow { get; set; }
protected ScrollRect TargetScrollRect { get; set; }
// SCROLLING #region PROPERTIES
protected EventSystem CurrentEventSystem
{
get { return EventSystem.current; }
}
protected GameObject LastCheckedGameObject { get; set; }
protected GameObject CurrentSelectedGameObject
{
get { return EventSystem.current.currentSelectedGameObject; }
}
protected RectTransform CurrentTargetRectTransform { get; set; }
protected bool IsManualScrollingAvailable { get; set; }
//*** METHODS - PUBLIC ***// // REFERENCES
public RectTransform ViewRectTransform
{
get { return viewportRectTransform; }
set { viewportRectTransform = value; }
}
public ScrollRect TargetScrollRect
{
get { return targetScrollRect; }
set { targetScrollRect = value; }
}
// SCROLLING
public Axis ScrollAxes => scrollAxes;
public ScrollMethod UsedScrollMethod => usedScrollMethod;
public float ScrollSpeed => scrollSpeed;
public float EndOfListJumpScrollSpeed => endOfListJumpScrollSpeed;
public float JumpOffsetThreshold => jumpOffsetThreshold;
//*** METHODS - PROTECTED ***// // INPUT
protected virtual void Awake() public MouseButton CancelScrollMouseButtons => cancelScrollMouseButtons;
{ public KeyCode[] CancelScrollKeys => cancelScrollKeys;
TargetScrollRect = GetComponent<ScrollRect>();
ScrollWindow = TargetScrollRect.GetComponent<RectTransform>();
}
protected virtual void Start() // VARIABLES
{ private RectTransform scrollRectContentTransform;
private GameObject lastCheckedSelection;
} // COROUTINES
private Coroutine animationCoroutine;
protected virtual void Update() #endregion
{
UpdateReferences();
CheckIfScrollingShouldBeLocked();
ScrollRectToLevelSelection();
}
//*** METHODS - PRIVATE ***// #region FUNCTIONS
private void UpdateReferences()
{ protected void Awake()
// update current selected rect transform {
if (CurrentSelectedGameObject != LastCheckedGameObject) ValidateReferences();
}
protected void LateUpdate()
{
TryToScrollToSelection();
}
protected void Reset()
{
TargetScrollRect = gameObject.GetComponentInParent<ScrollRect>() ?? gameObject.GetComponentInChildren<ScrollRect>();
ViewRectTransform = gameObject.GetComponent<RectTransform>();
}
private void ValidateReferences()
{
if (!targetScrollRect)
{ {
CurrentTargetRectTransform = (CurrentSelectedGameObject != null) ? targetScrollRect = GetComponent<ScrollRect>();
CurrentSelectedGameObject.GetComponent<RectTransform>() :
null;
// unlock automatic scrolling
if (CurrentSelectedGameObject != null &&
CurrentSelectedGameObject.transform.parent == LayoutListGroup.transform)
{
IsManualScrollingAvailable = false;
}
} }
LastCheckedGameObject = CurrentSelectedGameObject; if (!targetScrollRect)
}
private void CheckIfScrollingShouldBeLocked()
{
if (CancelScrollOnInput == false || IsManualScrollingAvailable == true)
{ {
return; Debug.LogError("[UIScrollToSelection] No ScrollRect found. Either attach this script to a ScrollRect or assign on in the 'Target Scroll Rect' property");
} gameObject.SetActive(false);
return;
}
for (int i = 0; i < CancelScrollKeycodes.Count; i++) if (ViewRectTransform == null)
{ {
if (UIExtensionsInputManager.GetKeyDown(CancelScrollKeycodes[i]) == true) ViewRectTransform = TargetScrollRect.GetComponent<RectTransform>();
{ }
IsManualScrollingAvailable = true;
break; if (TargetScrollRect != null)
} {
} scrollRectContentTransform = TargetScrollRect.content;
} }
private void ScrollRectToLevelSelection() if (EventSystem.current == null)
{ {
// check main references Debug.LogError("[UIScrollToSelection] Unity UI EventSystem not found. It is required to check current selected object.");
bool referencesAreIncorrect = (TargetScrollRect == null || LayoutListGroup == null || ScrollWindow == null); gameObject.SetActive(false);
return;
}
}
if (referencesAreIncorrect == true || IsManualScrollingAvailable == true) private void TryToScrollToSelection()
{ {
return; // update references if selection changed
} GameObject selection = EventSystem.current.currentSelectedGameObject;
RectTransform selection = CurrentTargetRectTransform; if (selection == null || selection.activeInHierarchy == false || selection == lastCheckedSelection ||
selection.transform.IsChildOf(transform) == false)
{
return;
}
// check if scrolling is possible RectTransform selectionRect = selection.GetComponent<RectTransform>();
if (selection == null || selection.transform.parent != LayoutListGroup.transform)
{
return;
}
// depending on selected scroll direction move the scroll rect to selection ViewRectTransform.GetWorldCorners(viewRectCorners);
switch (ScrollDirection) selectionRect.GetWorldCorners(selectedElementCorners);
{
case ScrollType.VERTICAL:
UpdateVerticalScrollPosition(selection);
break;
case ScrollType.HORIZONTAL:
UpdateHorizontalScrollPosition(selection);
break;
case ScrollType.BOTH:
UpdateVerticalScrollPosition(selection);
UpdateHorizontalScrollPosition(selection);
break;
}
}
private void UpdateVerticalScrollPosition(RectTransform selection) ScrollToSelection(selection);
{
// move the current scroll rect to correct position
float selectionPosition = -selection.anchoredPosition.y - (selection.rect.height * (1 - selection.pivot.y));
float elementHeight = selection.rect.height; lastCheckedSelection = selection;
float maskHeight = ScrollWindow.rect.height; }
float listAnchorPosition = LayoutListGroup.anchoredPosition.y;
// get the element offset value depending on the cursor move direction private void ScrollToSelection(GameObject selection)
float offlimitsValue = GetScrollOffset(selectionPosition, listAnchorPosition, elementHeight, maskHeight); {
// initial check if we can scroll at all
if (selection == null)
{
return;
}
// move the target scroll rect // this is just to make names shorter a bit
TargetScrollRect.verticalNormalizedPosition += Vector3[] corners = viewRectCorners;
(offlimitsValue / LayoutListGroup.rect.height) * Time.unscaledDeltaTime * scrollSpeed; Vector3[] selectionCorners = selectedElementCorners;
}
private void UpdateHorizontalScrollPosition(RectTransform selection) // calculate scroll offset
{ Vector2 offsetToSelection = Vector2.zero;
// move the current scroll rect to correct position
float selectionPosition = -selection.anchoredPosition.x - (selection.rect.width * (1 - selection.pivot.x));
float elementWidth = selection.rect.width; offsetToSelection.x =
float maskWidth = ScrollWindow.rect.width; (selectionCorners[0].x < corners[0].x ? selectionCorners[0].x - corners[0].x : 0) +
float listAnchorPosition = -LayoutListGroup.anchoredPosition.x; (selectionCorners[2].x > corners[2].x ? selectionCorners[2].x - corners[2].x : 0);
offsetToSelection.y =
(selectionCorners[0].y < corners[0].y ? selectionCorners[0].y - corners[0].y : 0) +
(selectionCorners[1].y > corners[1].y ? selectionCorners[1].y - corners[1].y : 0);
// get the element offset value depending on the cursor move direction // calculate final scroll speed
float offlimitsValue = -GetScrollOffset(selectionPosition, listAnchorPosition, elementWidth, maskWidth); float finalScrollSpeed = ScrollSpeed;
// move the target scroll rect if (Math.Abs(offsetToSelection.x) / Screen.width >= JumpOffsetThreshold || Math.Abs(offsetToSelection.y) / Screen.height >= JumpOffsetThreshold)
TargetScrollRect.horizontalNormalizedPosition += {
(offlimitsValue / LayoutListGroup.rect.width) * Time.unscaledDeltaTime * scrollSpeed; finalScrollSpeed = EndOfListJumpScrollSpeed;
} }
private float GetScrollOffset(float position, float listAnchorPosition, float targetLength, float maskLength) // initiate animation coroutine
{ Vector2 targetPosition = (Vector2)scrollRectContentTransform.localPosition - offsetToSelection;
if (position < listAnchorPosition + (targetLength / 2))
{
return (listAnchorPosition + maskLength) - (position - targetLength);
}
else if (position + targetLength > listAnchorPosition + maskLength)
{
return (listAnchorPosition + maskLength) - (position + targetLength);
}
return 0; if (animationCoroutine != null)
} {
StopCoroutine(animationCoroutine);
}
//*** ENUMS ***// animationCoroutine = StartCoroutine(ScrollToPosition(targetPosition, finalScrollSpeed));
public enum ScrollType }
{
VERTICAL, private IEnumerator ScrollToPosition(Vector2 targetPosition, float speed)
HORIZONTAL, {
BOTH Vector3 startPosition = scrollRectContentTransform.localPosition;
}
} // cancel movement on axes not specified in ScrollAxes mask
targetPosition.x = ((ScrollAxes | Axis.HORIZONTAL) == ScrollAxes) ? targetPosition.x : startPosition.x;
targetPosition.y = ((ScrollAxes | Axis.VERTICAL) == ScrollAxes) ? targetPosition.y : startPosition.y;
// move to target position
Vector2 currentPosition2D = startPosition;
float horizontalSpeed = (Screen.width / Screen.dpi) * speed;
float verticalSpeed = (Screen.height / Screen.dpi) * speed;
while (currentPosition2D != targetPosition && CheckIfScrollInterrupted() == false)
{
currentPosition2D.x = MoveTowardsValue(currentPosition2D.x, targetPosition.x, horizontalSpeed, UsedScrollMethod);
currentPosition2D.y = MoveTowardsValue(currentPosition2D.y, targetPosition.y, verticalSpeed, UsedScrollMethod);
scrollRectContentTransform.localPosition = currentPosition2D;
yield return null;
}
scrollRectContentTransform.localPosition = currentPosition2D;
}
private bool CheckIfScrollInterrupted()
{
bool mouseButtonClicked = false;
// check mouse buttons
switch (CancelScrollMouseButtons)
{
case MouseButton.LEFT:
mouseButtonClicked |= Input.GetMouseButtonDown(0);
break;
case MouseButton.RIGHT:
mouseButtonClicked |= Input.GetMouseButtonDown(1);
break;
case MouseButton.MIDDLE:
mouseButtonClicked |= Input.GetMouseButtonDown(2);
break;
}
if (mouseButtonClicked == true)
{
return true;
}
// check keyboard buttons
for (int i = 0; i < CancelScrollKeys.Length; i++)
{
if (Input.GetKeyDown(CancelScrollKeys[i]) == true)
{
return true;
}
}
return false;
}
private float MoveTowardsValue(float from, float to, float delta, ScrollMethod method)
{
switch (method)
{
case ScrollMethod.MOVE_TOWARDS:
return Mathf.MoveTowards(from, to, delta * Time.unscaledDeltaTime);
case ScrollMethod.LERP:
return Mathf.Lerp(from, to, delta * Time.unscaledDeltaTime);
default:
return from;
}
}
#endregion
#region CLASS_ENUMS
[Flags]
public enum Axis
{
NONE = 0x00000000,
HORIZONTAL = 0x00000001,
VERTICAL = 0x00000010,
ANY = 0x00000011
}
[Flags]
public enum MouseButton
{
NONE = 0x00000000,
LEFT = 0x00000001,
RIGHT = 0x00000010,
MIDDLE = 0x00000100,
ANY = 0x00000111
}
public enum ScrollMethod
{
MOVE_TOWARDS,
LERP
}
#endregion
}
} }

View File

@ -27,6 +27,7 @@ namespace UnityEngine.UI.Extensions
{ {
//if true user will need to call Init() method manually (in case the contend of the scrollview is generated from code or requires special initialization) //if true user will need to call Init() method manually (in case the contend of the scrollview is generated from code or requires special initialization)
public bool InitByUser = false; public bool InitByUser = false;
private bool _initialised = false;
private ScrollRect _scrollRect; private ScrollRect _scrollRect;
private ContentSizeFitter _contentSizeFitter; private ContentSizeFitter _contentSizeFitter;
private VerticalLayoutGroup _verticalLayoutGroup; private VerticalLayoutGroup _verticalLayoutGroup;
@ -36,8 +37,9 @@ namespace UnityEngine.UI.Extensions
private bool _isHorizontal = false; private bool _isHorizontal = false;
private float _disableMarginX = 0; private float _disableMarginX = 0;
private float _disableMarginY = 0; private float _disableMarginY = 0;
private bool hasDisabledGridComponents = false; private bool _hasDisabledGridComponents = false;
private List<RectTransform> items = new List<RectTransform>(); private List<RectTransform> _items = new List<RectTransform>();
private bool _reset = false;
void Awake() void Awake()
{ {
@ -45,13 +47,19 @@ namespace UnityEngine.UI.Extensions
return; return;
Init(); Init();
} }
public void Init() public void Init()
{ {
if (_initialised)
{
Debug.LogError("Control already initialized\nYou have to enable the InitByUser setting on the control in order to use Init() when running");
return;
}
if (GetComponent<ScrollRect>() != null) if (GetComponent<ScrollRect>() != null)
{ {
_initialised = true;
_scrollRect = GetComponent<ScrollRect>(); _scrollRect = GetComponent<ScrollRect>();
_scrollRect.onValueChanged.AddListener(OnScroll); _scrollRect.onValueChanged.AddListener(OnScroll);
@ -60,7 +68,7 @@ namespace UnityEngine.UI.Extensions
for (int i = 0; i < _scrollRect.content.childCount; i++) for (int i = 0; i < _scrollRect.content.childCount; i++)
{ {
items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>()); _items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
} }
if (_scrollRect.content.GetComponent<VerticalLayoutGroup>() != null) if (_scrollRect.content.GetComponent<VerticalLayoutGroup>() != null)
{ {
@ -78,7 +86,6 @@ namespace UnityEngine.UI.Extensions
{ {
_contentSizeFitter = _scrollRect.content.GetComponent<ContentSizeFitter>(); _contentSizeFitter = _scrollRect.content.GetComponent<ContentSizeFitter>();
} }
} }
else else
{ {
@ -86,80 +93,108 @@ namespace UnityEngine.UI.Extensions
} }
} }
void DisableGridComponents() void ToggleGridComponents(bool toggle)
{ {
if (_isVertical) if (_isVertical)
_disableMarginY = _scrollRect.GetComponent<RectTransform>().rect.height / 2 + items[0].sizeDelta.y; _disableMarginY = _scrollRect.GetComponent<RectTransform>().rect.height / 2 + _items[0].sizeDelta.y;
if (_isHorizontal) if (_isHorizontal)
_disableMarginX = _scrollRect.GetComponent<RectTransform>().rect.width / 2 + items[0].sizeDelta.x; _disableMarginX = _scrollRect.GetComponent<RectTransform>().rect.width / 2 + _items[0].sizeDelta.x;
if (_verticalLayoutGroup) if (_verticalLayoutGroup)
{ {
_verticalLayoutGroup.enabled = false; _verticalLayoutGroup.enabled = toggle;
} }
if (_horizontalLayoutGroup) if (_horizontalLayoutGroup)
{ {
_horizontalLayoutGroup.enabled = false; _horizontalLayoutGroup.enabled = toggle;
} }
if (_contentSizeFitter) if (_contentSizeFitter)
{ {
_contentSizeFitter.enabled = false; _contentSizeFitter.enabled = toggle;
} }
if (_gridLayoutGroup) if (_gridLayoutGroup)
{ {
_gridLayoutGroup.enabled = false; _gridLayoutGroup.enabled = toggle;
} }
hasDisabledGridComponents = true; _hasDisabledGridComponents = !toggle;
} }
public void OnScroll(Vector2 pos) public void OnScroll(Vector2 pos)
{ {
if (_reset)
{
return;
}
if (!hasDisabledGridComponents) if (!_hasDisabledGridComponents)
DisableGridComponents(); {
ToggleGridComponents(false);
}
for (int i = 0; i < items.Count; i++) for (int i = 0; i < _items.Count; i++)
{ {
if (_isVertical && _isHorizontal) if (_isVertical && _isHorizontal)
{ {
if (_scrollRect.transform.InverseTransformPoint(items[i].position).y < -_disableMarginY || _scrollRect.transform.InverseTransformPoint(items[i].position).y > _disableMarginY if (_scrollRect.transform.InverseTransformPoint(_items[i].position).y < -_disableMarginY || _scrollRect.transform.InverseTransformPoint(_items[i].position).y > _disableMarginY
|| _scrollRect.transform.InverseTransformPoint(items[i].position).x < -_disableMarginX || _scrollRect.transform.InverseTransformPoint(items[i].position).x > _disableMarginX) || _scrollRect.transform.InverseTransformPoint(_items[i].position).x < -_disableMarginX || _scrollRect.transform.InverseTransformPoint(_items[i].position).x > _disableMarginX)
{ {
items[i].gameObject.SetActive(false); _items[i].gameObject.SetActive(false);
} }
else else
{ {
items[i].gameObject.SetActive(true); _items[i].gameObject.SetActive(true);
} }
} }
else else
{ {
if (_isVertical) if (_isVertical)
{ {
if (_scrollRect.transform.InverseTransformPoint(items[i].position).y < -_disableMarginY || _scrollRect.transform.InverseTransformPoint(items[i].position).y > _disableMarginY) if (_scrollRect.transform.InverseTransformPoint(_items[i].position).y < -_disableMarginY || _scrollRect.transform.InverseTransformPoint(_items[i].position).y > _disableMarginY)
{ {
items[i].gameObject.SetActive(false); _items[i].gameObject.SetActive(false);
} }
else else
{ {
items[i].gameObject.SetActive(true); _items[i].gameObject.SetActive(true);
} }
} }
if (_isHorizontal) if (_isHorizontal)
{ {
if (_scrollRect.transform.InverseTransformPoint(items[i].position).x < -_disableMarginX || _scrollRect.transform.InverseTransformPoint(items[i].position).x > _disableMarginX) if (_scrollRect.transform.InverseTransformPoint(_items[i].position).x < -_disableMarginX || _scrollRect.transform.InverseTransformPoint(_items[i].position).x > _disableMarginX)
{ {
items[i].gameObject.SetActive(false); _items[i].gameObject.SetActive(false);
} }
else else
{ {
items[i].gameObject.SetActive(true); _items[i].gameObject.SetActive(true);
} }
} }
} }
} }
} }
public void SetDirty()
{
_reset = true;
}
private void LateUpdate()
{
if (_reset)
{
_reset = false;
_items.Clear();
for (int i = 0; i < _scrollRect.content.childCount; i++)
{
_items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
_items[i].gameObject.SetActive(true);
}
ToggleGridComponents(true);
}
}
} }
} }