Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Moves the Content transform so the current selected object will be inside the Viewport rect
// Source: https://gist.github.com/Z4urce/e1719b3c1641537ced54da24d911f0b0
// Moves the Content transform so the current selected object will be inside the Viewport rect
using UnityEngine;
using UnityEngine.EventSystems;
namespace Utils
{
public sealed class ScrollToSelectionBehaviour : MonoBehaviour
{
public RectTransform Viewport;
public RectTransform Content;
public bool Horizontal = true;
public bool Vertical = true;
public float DistanceDeltaQuotient = 1000f;
public void Update()
{
var selected = EventSystem.current.currentSelectedGameObject;
if (selected == null || !selected.TryGetComponent<RectTransform>(out var rectTransform)) {
return;
}
SnapToTarget(rectTransform);
}
private void SnapToTarget(RectTransform rectTransform)
{
Vector2? snapPos = GetTargetRectSnapPos(rectTransform);
if (!snapPos.HasValue) {
return;
}
var anchoredPos = Content.anchoredPosition;
var destination = new Vector2(Horizontal ? snapPos.Value.x : anchoredPos.x, Vertical ? snapPos.Value.y : anchoredPos.y);
float maxDistanceDelta = Time.deltaTime * DistanceDeltaQuotient;
Content.anchoredPosition = Vector2.MoveTowards(anchoredPos, destination, maxDistanceDelta);
}
private Vector2? GetTargetRectSnapPos(RectTransform targetRectTransform)
{
Canvas.ForceUpdateCanvases();
var rectMinWorldPos = (Vector2) targetRectTransform.TransformPoint(targetRectTransform.rect.min);
var rectMaxWorldPos = (Vector2) targetRectTransform.TransformPoint(targetRectTransform.rect.max);
Vector2? minSnap = CalculateViewportTargetDist(rectMinWorldPos);
Vector2? maxSnap = CalculateViewportTargetDist(rectMaxWorldPos);
return maxSnap ?? minSnap;
}
private Vector2? CalculateViewportTargetDist(Vector2 globalPos)
{
var invTransTarget = (Vector2) Viewport.InverseTransformPoint(globalPos);
if (Viewport.rect.Contains(invTransTarget)) {
return null;
};
var invTransContent = (Vector2) Viewport.InverseTransformPoint(Content.position);
return invTransContent - invTransTarget;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.