Skip to content

Instantly share code, notes, and snippets.

@QubitsDev
Last active July 22, 2023 21:43
Show Gist options
  • Save QubitsDev/0f5424557199f616fcd000b30c99e035 to your computer and use it in GitHub Desktop.
Save QubitsDev/0f5424557199f616fcd000b30c99e035 to your computer and use it in GitHub Desktop.
Unity3d ScrollRect Auto-Scroll, Dropdown Use: Places this component in the Template of Dropdown (with the ScrollRect component)
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[RequireComponent(typeof(ScrollRect))]
[AddComponentMenu("UI/ScrollRect Auto-Scroll")]
public class ScrollRectAutoScroll : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public float scrollSpeed = 10f;
private bool mouseOver = false;
[Header("Navigation")]
public Selectable selectOnTop;
public Selectable selectOnBottom;
private Selectable[] m_SelectableList;
private Navigation[] m_NavigationList;
private List<Selectable> m_Selectables = new List<Selectable>();
private ScrollRect m_ScrollRect;
private Vector2 m_NextScrollPosition = Vector2.up;
public void Refresh()
{
if (m_ScrollRect)
{
m_ScrollRect.content.GetComponentsInChildren(m_Selectables);
}
RemakeNavigation();
}
void OnEnable()
{
Refresh();
}
void Awake()
{
m_ScrollRect = GetComponent<ScrollRect>();
}
void Start()
{
Refresh();
ScrollToSelected(true);
}
void Update()
{
// Scroll via input.
InputScroll();
if (!mouseOver)
{
// Lerp scrolling code.
m_ScrollRect.normalizedPosition = Vector2.Lerp(m_ScrollRect.normalizedPosition, m_NextScrollPosition, scrollSpeed * Time.deltaTime);
}
else
{
m_NextScrollPosition = m_ScrollRect.normalizedPosition;
}
}
void InputScroll()
{
if (m_Selectables.Count > 0)
{
if (Input.GetButtonDown("Horizontal") || Input.GetButtonDown("Vertical") || Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
{
ScrollToSelected(false);
}
}
}
void ScrollToSelected(bool quickScroll)
{
int selectedIndex = -1;
Selectable selectedElement = EventSystem.current.currentSelectedGameObject ? EventSystem.current.currentSelectedGameObject.GetComponent<Selectable>() : null;
if (selectedElement)
{
selectedIndex = m_Selectables.IndexOf(selectedElement);
}
if (selectedIndex > -1)
{
if (quickScroll)
{
m_ScrollRect.normalizedPosition = new Vector2(0, 1 - (selectedIndex / ((float)m_Selectables.Count - 1)));
m_NextScrollPosition = m_ScrollRect.normalizedPosition;
}
else
{
m_NextScrollPosition = new Vector2(0, 1 - (selectedIndex / ((float)m_Selectables.Count - 1)));
}
}
}
public void OnPointerEnter(PointerEventData eventData)
{
mouseOver = true;
}
public void OnPointerExit(PointerEventData eventData)
{
mouseOver = false;
ScrollToSelected(false);
}
void RemakeNavigation()
{
m_SelectableList = m_ScrollRect.content.GetComponentsInChildren<Selectable>();
m_NavigationList = new Navigation[m_SelectableList.Length];
for (int i = 0; i < m_SelectableList.Length; i++)
{
m_NavigationList[0] = m_SelectableList[0].navigation;
}
if (m_SelectableList.Length > 1)
{
for (int i = 0; i < m_NavigationList.Length; i++)
{
// First item navigation.
if (i == 0)
{
m_NavigationList[0].mode = Navigation.Mode.Explicit;
if (selectOnTop)
{
m_NavigationList[0].selectOnUp = selectOnTop;
}
m_NavigationList[0].selectOnDown = m_SelectableList[1];
m_SelectableList[0].navigation = m_NavigationList[0];
}
else
{
m_NavigationList[i].mode = Navigation.Mode.Explicit;
if (i < m_NavigationList.Length - 1)
{
m_NavigationList[i].selectOnUp = m_SelectableList[i - 1];
m_NavigationList[i].selectOnDown = m_SelectableList[i + 1];
}
// Last item navigation.
else
{
m_NavigationList[i].selectOnUp = m_SelectableList[i - 1];
}
m_SelectableList[i].navigation = m_NavigationList[i];
}
}
}
else
{
m_NavigationList[0].mode = Navigation.Mode.Explicit;
if (selectOnTop)
{
m_NavigationList[0].selectOnUp = selectOnTop;
}
m_SelectableList[0].navigation = m_NavigationList[0];
}
}
}
@QubitsDev
Copy link
Author

Update adding the option to generate vertical navigation

@happimal
Copy link

Line 18, I don't get how the list gets its objects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment