com.unity.uiextensions/Runtime/Scripts/Utilities/ScrollRectTweener.cs

141 lines
4.3 KiB
C#
Raw Normal View History

/// Credit Martin Sharkbomb
/// Sourced from - http://www.sharkbombs.com/2015/08/26/unity-ui-scrollrect-tools/
using System.Collections;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[RequireComponent(typeof(ScrollRect))]
[AddComponentMenu("UI/Extensions/ScrollRectTweener")]
public class ScrollRectTweener : MonoBehaviour, IDragHandler
{
ScrollRect scrollRect;
Vector2 startPos;
Vector2 targetPos;
bool wasHorizontal;
bool wasVertical;
public float moveSpeed = 5000f;
public bool disableDragWhileTweening = false;
void Awake()
{
scrollRect = GetComponent<ScrollRect>();
wasHorizontal = scrollRect.horizontal;
wasVertical = scrollRect.vertical;
}
public void ScrollHorizontal(float normalizedX)
{
Scroll(new Vector2(normalizedX, scrollRect.verticalNormalizedPosition));
}
public void ScrollHorizontal(float normalizedX, float duration)
{
Scroll(new Vector2(normalizedX, scrollRect.verticalNormalizedPosition), duration);
}
public void ScrollVertical(float normalizedY)
{
Scroll(new Vector2(scrollRect.horizontalNormalizedPosition, normalizedY));
}
public void ScrollVertical(float normalizedY, float duration)
{
Scroll(new Vector2(scrollRect.horizontalNormalizedPosition, normalizedY), duration);
}
public void Scroll(Vector2 normalizedPos)
{
Scroll(normalizedPos, GetScrollDuration(normalizedPos));
}
float GetScrollDuration(Vector2 normalizedPos)
{
Vector2 currentPos = GetCurrentPos();
return Vector2.Distance(DeNormalize(currentPos), DeNormalize(normalizedPos)) / moveSpeed;
}
Vector2 DeNormalize(Vector2 normalizedPos)
{
return new Vector2(normalizedPos.x * scrollRect.content.rect.width, normalizedPos.y * scrollRect.content.rect.height);
}
Vector2 GetCurrentPos()
{
return new Vector2(scrollRect.horizontalNormalizedPosition, scrollRect.verticalNormalizedPosition);
}
public void Scroll(Vector2 normalizedPos, float duration)
{
startPos = GetCurrentPos();
targetPos = normalizedPos;
if (disableDragWhileTweening)
LockScrollability();
StopAllCoroutines();
StartCoroutine(DoMove(duration));
}
IEnumerator DoMove(float duration)
{
// Abort if movement would be too short
if (duration < 0.05f)
yield break;
Vector2 posOffset = targetPos - startPos;
float currentTime = 0f;
while (currentTime < duration)
{
currentTime += Time.deltaTime;
scrollRect.normalizedPosition = EaseVector(currentTime, startPos, posOffset, duration);
yield return null;
}
scrollRect.normalizedPosition = targetPos;
if (disableDragWhileTweening)
RestoreScrollability();
}
public Vector2 EaseVector(float currentTime, Vector2 startValue, Vector2 changeInValue, float duration)
{
return new Vector2(
changeInValue.x * Mathf.Sin(currentTime / duration * (Mathf.PI / 2)) + startValue.x,
changeInValue.y * Mathf.Sin(currentTime / duration * (Mathf.PI / 2)) + startValue.y
);
}
public void OnDrag(PointerEventData eventData)
{
if (!disableDragWhileTweening)
StopScroll();
}
void StopScroll()
{
StopAllCoroutines();
if (disableDragWhileTweening)
RestoreScrollability();
}
void LockScrollability()
{
scrollRect.horizontal = false;
scrollRect.vertical = false;
}
void RestoreScrollability()
{
scrollRect.horizontal = wasHorizontal;
scrollRect.vertical = wasVertical;
}
}
}