Reputation: 1047
I work on a simple scrollable UI in Unity.
I use the following script (assigned to the Empty) to make it scrollable:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PageSwiper : MonoBehaviour, IDragHandler, IEndDragHandler
{
private Vector3 scrollableUILocation;
// Start is called before the first frame update
void Start()
{
scrollableUILocation = transform.position;
}
public void OnDrag(PointerEventData data)
{
float difference = data.pressPosition.x - data.position.x;
transform.position = scrollableUILocation - new Vector3(difference, 0, 0);
}
public void OnEndDrag(PointerEventData data)
{
scrollableUILocation = transform.position;
}
}
The problem is that I can scroll the UI panel outside of the screen. So I need to make it impossible, or make it so that if I scroll it too far, it smoothly returns back (to the end or to the start of the UI panel, depending on which is closer)
How can I do it?
I tried to implement the following solution but it doesn't work:
I added two Empty object on the left and on the right from the UI panel. I tried to make my UI panel to smoothly move at the position of one of those empty objects in case if I would move it close enough to them. But it doesn't work.
public void OnEndDrag(PointerEventData data)
{
if (Vector3.Distance(transform.position, StartPoint.transform.position) < 1.0f)
{
StartCoroutine(SmoothMove(transform.position, StartPoint.transform.position, easing));
}
else if (Vector3.Distance(transform.position, EndPoint.transform.position) < 1.0f)
{
StartCoroutine(SmoothMove(transform.position, EndPoint.transform.position, easing));
}
}
IEnumerator SmoothMove(Vector3 startpos, Vector3 endpos, float seconds)
{
float t = 0f;
while (t <= 1.0)
{
t += Time.deltaTime / seconds;
transform.position = Vector3.Lerp(startpos, endpos, Mathf.SmoothStep(0f, 1f, t));
yield return null;
}
}
Upvotes: 2
Views: 8392
Reputation: 1
Upvotes: 0
Reputation: 10701
So you'd be better off with a ScrollRect as it already contains all the needed actions for this kind of feature.
MovementType will define how the system reacts when reaching the end of the container (from the documentation):
Considering you have a long button system, maybe it needs to be dynamic, so you'd look into ContentSizeFitter.
You add a scroll view object. This will include by default:
Now add a Text component to the Content object, NOT a text child, a component to it. Also add a ContentSizeFitter and set the vertical fit to prefered size. This is because I will deal with vertical expansion.
Make sure the Viewport occupies the space that should serve as mask. For first practice, place the ScrollView object in the middle and set the anchors of Viewport to 0,1 so it takes the whole parent.
There is plenty more you can do and I would suggest to look into the free Unity UI extension library as it has some fancy accordeon or endless scrolling effects.
Upvotes: 2