Skip to content

Instantly share code, notes, and snippets.

@nicloay
Last active November 26, 2018 11:41
Show Gist options
  • Save nicloay/91285e470de026a8d128f33f49bb22fc to your computer and use it in GitHub Desktop.
Save nicloay/91285e470de026a8d128f33f49bb22fc to your computer and use it in GitHub Desktop.
/// <summary>
/// Ease vector value
/// </summary>
/// <param name="t">Current time (in frames or seconds).</param>
/// <param name="b">Starting value.</param>
/// <param name="c">Change needed in value.</param>
/// <param name="d">Expected easing duration (in frames or seconds).</param>
/// <param name="easeType">EaseType</param>
/// <param name="pingPong">use pingpong (optional)</param>
/// <returns>The correct value.</returns>
public static Vector2 ChangeVector2(float t, Vector2 b, Vector2 c, float d, EaseType easeType, bool pingPong = false)
{
if (pingPong)
{
return new Vector2()
{
x = ChangeFloatPingPong(t, b.x, c.x, d, easeType),
y = ChangeFloatPingPong(t, b.y, c.y, d, easeType)
};
}
else
{
return new Vector2()
{
x = ChangeFloat(t, b.x, c.x, d, easeType),
y = ChangeFloat(t, b.y, c.y, d, easeType)
};
}
}
...
public static IEnumerator<float> _MoveRectAnchoredPosition(RectTransform rectTransform, Vector2 from,
Vector2 to, float time,
EaseType easeType)
{
Vector2 diff = to - from;
float currentTime = 0;
Vector2 value;
while (currentTime < time)
{
currentTime += Time.deltaTime;
currentTime = Mathf.Min(time, currentTime);
value = ChangeVector2(currentTime, from, diff, time, easeType);
rectTransform.anchoredPosition = value;
yield return Timing.WaitForOneFrame;
}
}
...
more code here http://wiki.unity3d.com/index.php?title=Tween =)
using System;
namespace Utils.Ease
{
[Serializable]
public class EaseConfig
{
public EaseType EaseType;
public float Time;
}
}
using System.Collections.Generic;
using MEC;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Utils.Ease;
public class RectSnap : MonoBehaviour, IBeginDragHandler, IEndDragHandler {
public float MinimumVelocityToAdjustPosition = 10;
public EaseConfig MoveEase;
private ScrollRect _rect;
private bool _isDragging = false;
private float _contentPreviousPosition;
private bool _makeTween = false;
void Awake()
{
_rect = GetComponent<ScrollRect>();
_contentPreviousPosition = _rect.content.anchoredPosition.x;
}
void Update()
{
if (Mathf.Abs(_rect.velocity.x) < MinimumVelocityToAdjustPosition && _makeTween)
{
AdjustPosition();
}
}
void AdjustPosition()
{
_makeTween = false;
Vector2 globalOffset = GetClosestDistanceToAnyChild();
Vector2 localOffset = _rect.content.InverseTransformVector(globalOffset);
Vector2 tweenFrom = _rect.content.anchoredPosition;
Vector2 tweenTo = tweenFrom + localOffset;
_rect.enabled = false;
Timing.RunCoroutine(_MakeTween(tweenFrom, tweenTo), "AutoMove");
}
/// <summary>
/// Get Distance to the closest child transform of the content
/// In GLOBAL coordinates
/// </summary>
/// <returns></returns>
private Vector2 GetClosestDistanceToAnyChild()
{
Vector2[] itemsGlobalPositions = new Vector2[_rect.content.childCount];
for (int i = 0; i < _rect.content.childCount; i++)
{
RectTransform childRT = _rect.content.GetChild(i).GetComponent<RectTransform>();
itemsGlobalPositions[i] = childRT.TransformPoint(childRT.rect.center);
}
Vector2 viewPortCenterGlobalPosition = _rect.viewport.TransformPoint(_rect.viewport.rect.center);
float minDistance = float.MaxValue;
Vector2 globalOffset = Vector2.zero;
for (int i = 0; i < itemsGlobalPositions.Length; i++)
{
if (_rect.content.GetChild(i).gameObject.activeInHierarchy)
{
float distance = Vector2.Distance(itemsGlobalPositions[i], viewPortCenterGlobalPosition);
if (distance < minDistance)
{
globalOffset = viewPortCenterGlobalPosition - itemsGlobalPositions[i] ;
minDistance = distance;
}
}
}
return globalOffset;
}
private IEnumerator<float> _MakeTween(Vector2 from , Vector2 to)
{
_rect.enabled = false;
yield return Timing.WaitUntilDone(Ease._MoveRectAnchoredPosition(_rect.content, from, to, MoveEase));
_rect.enabled = true;
}
public void OnBeginDrag(PointerEventData eventData)
{
if (_rect.enabled == false)
{
Timing.KillCoroutines("AutoMove");
_rect.enabled = true;
}
_isDragging = true;
}
public void OnEndDrag(PointerEventData eventData)
{
_isDragging = false;
_makeTween = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment