using System.Collections; using System.Collections.Generic; using UnityEngine.EventSystems; using UnityEngine.Events; using System; namespace UnityEngine.UI.Extensions { [ExecuteInEditMode] [RequireComponent(typeof(ScrollRect))] [AddComponentMenu("UI/Extensions/ContentSnapScrollHorizontal")] public class ContentScrollSnapHorizontal : MonoBehaviour, IBeginDragHandler, IEndDragHandler { [Serializable] public class StartMovementEvent : UnityEvent { } [Serializable] public class CurrentItemChangeEvent : UnityEvent { } [Serializable] public class FoundItemToSnapToEvent : UnityEvent { } [Serializable] public class SnappedToItemEvent : UnityEvent { } public bool ignoreInactiveItems = true; public MoveInfo startInfo = new MoveInfo(MoveInfo.IndexType.positionIndex, 0); public GameObject prevButton; public GameObject nextButton; public GameObject pagination; [Tooltip("The velocity below which the scroll rect will start to snap")] public int snappingVelocityThreshold = 50; [Header("Paging Info")] [Tooltip("Should the pagination & buttons jump or lerp to the items")] public bool jumpToItem = false; [Tooltip("The time it will take for the pagination or buttons to move between items")] public float lerpTime = .3f; [Header("Events")] [SerializeField] [Tooltip("Event is triggered whenever the scroll rect starts to move, even when triggered programatically")] private StartMovementEvent m_StartMovementEvent = new StartMovementEvent(); public StartMovementEvent startMovementEvent { get { return m_StartMovementEvent; } set { m_StartMovementEvent = value; } } [SerializeField] [Tooltip("Event is triggered whenever the closest item to the center of the scrollrect changes")] private CurrentItemChangeEvent m_CurrentItemChangeEvent = new CurrentItemChangeEvent(); public CurrentItemChangeEvent currentItemChangeEvent { get { return m_CurrentItemChangeEvent; } set { m_CurrentItemChangeEvent = value; } } [SerializeField] [Tooltip("Event is triggered when the ContentSnapScroll decides which item it is going to snap to. Returns the index of the closest position.")] private FoundItemToSnapToEvent m_FoundItemToSnapToEvent = new FoundItemToSnapToEvent(); public FoundItemToSnapToEvent foundItemToSnapToEvent { get { return m_FoundItemToSnapToEvent; } set { m_FoundItemToSnapToEvent = value; } } [SerializeField] [Tooltip("Event is triggered when we finally settle on an element. Returns the index of the item's position.")] private SnappedToItemEvent m_SnappedToItemEvent = new SnappedToItemEvent(); public SnappedToItemEvent snappedToItemEvent { get { return m_SnappedToItemEvent; } set { m_SnappedToItemEvent = value; } } private ScrollRect scrollRect; private RectTransform scrollRectTransform; private RectTransform contentTransform; private List contentPositions; private Vector3 lerpTarget; private float totalScrollableWidth; private DrivenRectTransformTracker tracker; private bool lerp; private float mLerpTime; private int _closestItem; private bool lerpToContentRunning; private bool mSliding; private bool mLerping; private bool contentIsHorizonalLayoutGroup { get { return contentTransform.GetComponent() != null; } } #region Public Info /// /// Returns if the SnapScroll is moving /// public bool moving { get { return sliding || lerping; } } /// /// Returns if the SnapScroll is moving because of a touch /// public bool sliding { get { return mSliding; } } /// /// Returns if the SnapScroll is moving programmatically /// public bool lerping { get { return mLerping; } } /// /// Returns the closest item's index /// *Note this is zero based, and based on position not child order /// public int closestItemIndex { get { return contentPositions.IndexOf(FindClosestFrom(contentTransform.localPosition)); } } /// /// Returns the lerpTarget's index /// *Note this is zero-based, and based on position not child order /// public int lerpTargetIndex { get { return contentPositions.IndexOf(lerpTarget); } } #endregion #region Setup private void Awake() { scrollRect = GetComponent(); scrollRectTransform = (RectTransform) scrollRect.transform; contentTransform = scrollRect.content; if (nextButton) nextButton.GetComponent