2025-07-08 10:46:31 +00:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.EventSystems;
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
|
|
|
namespace Superlazy.UI
|
|
|
|
|
{
|
|
|
|
|
public class SLUIScrollRect : SLUIComponent, IBeginDragHandler, IEndDragHandler, IDragHandler
|
|
|
|
|
{
|
|
|
|
|
public bool snap = false;
|
|
|
|
|
public float itemSize;
|
|
|
|
|
public string indexBind;
|
|
|
|
|
public string stateBind;
|
|
|
|
|
|
|
|
|
|
private ScrollRect scrollRect;
|
|
|
|
|
private RectTransform container;
|
|
|
|
|
private bool snapping;
|
|
|
|
|
private Vector2 snapTargetPosition;
|
|
|
|
|
private bool dragging = false;
|
|
|
|
|
private int index = -1;
|
|
|
|
|
|
|
|
|
|
// 나중에 휘리릭용으로 사용할 예정
|
|
|
|
|
//private Vector2 positionOnDragStart = Vector3.zero;
|
|
|
|
|
|
|
|
|
|
protected override void Validate()
|
|
|
|
|
{
|
|
|
|
|
scrollRect = gameObject.GetComponent<ScrollRect>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Init()
|
|
|
|
|
{
|
|
|
|
|
container = scrollRect.content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Enable()
|
|
|
|
|
{
|
|
|
|
|
if (snap)
|
|
|
|
|
{
|
|
|
|
|
snapping = false;
|
|
|
|
|
dragging = false;
|
|
|
|
|
index = -1;
|
|
|
|
|
|
|
|
|
|
if (indexBind != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
SLGame.AddNotify(bindParent.BindPath.CombinePath(indexBind), OnChangeIndex);
|
|
|
|
|
|
|
|
|
|
OnChangeIndex();
|
|
|
|
|
container.anchoredPosition = snapTargetPosition;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
container.anchoredPosition = Vector2.zero;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stateBind != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(stateBind, "Idle");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Disable()
|
|
|
|
|
{
|
|
|
|
|
if (snap)
|
|
|
|
|
{
|
|
|
|
|
snapping = false;
|
|
|
|
|
dragging = false;
|
|
|
|
|
index = -1;
|
|
|
|
|
|
|
|
|
|
if (indexBind != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
SLGame.RemoveNotify(bindParent.BindPath.CombinePath(indexBind), OnChangeIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stateBind != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(stateBind, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnChangeIndex()
|
|
|
|
|
{
|
|
|
|
|
if (snap == false) return;
|
|
|
|
|
|
|
|
|
|
var newIndex = SLGame.SessionGet(bindParent.BindPath).Get(indexBind);
|
|
|
|
|
|
|
|
|
|
if (newIndex == false && index == -1) return; // 삭제 관련 예외
|
|
|
|
|
if (index == newIndex) return;
|
|
|
|
|
|
|
|
|
|
index = newIndex;
|
|
|
|
|
|
|
|
|
|
snapping = true;
|
|
|
|
|
// anchoredPosition은 -로 가기때문에 인덱스 자체는 -로 세팅해야함 // 나중에는 확장가능성 생각해서 추가 개선
|
|
|
|
|
snapTargetPosition = scrollRect.horizontal
|
|
|
|
|
? new Vector2(-newIndex * itemSize, container.anchoredPosition.y)
|
|
|
|
|
: new Vector2(container.anchoredPosition.x, -newIndex * itemSize);
|
|
|
|
|
|
|
|
|
|
if (stateBind != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(stateBind, "Snapping");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ResetPage()
|
|
|
|
|
{
|
|
|
|
|
if (scrollRect.horizontal)
|
|
|
|
|
{
|
|
|
|
|
scrollRect.horizontalNormalizedPosition = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
scrollRect.verticalNormalizedPosition = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LateUpdate()
|
|
|
|
|
{
|
|
|
|
|
if (snapping)
|
|
|
|
|
{
|
|
|
|
|
scrollRect.StopMovement();
|
|
|
|
|
container.anchoredPosition = Vector2.Lerp(container.anchoredPosition, snapTargetPosition, 0.5f);
|
|
|
|
|
|
|
|
|
|
if (Vector3.Distance(container.anchoredPosition, snapTargetPosition) < 5f)
|
|
|
|
|
{
|
|
|
|
|
container.anchoredPosition = snapTargetPosition;
|
|
|
|
|
|
|
|
|
|
snapping = false;
|
|
|
|
|
|
|
|
|
|
if (stateBind != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(stateBind, "Idle");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void OnBeginDrag(PointerEventData eventData)
|
|
|
|
|
{
|
|
|
|
|
if (snap == false) return;
|
|
|
|
|
|
|
|
|
|
//positionOnDragStart = eventData.position;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void OnEndDrag(PointerEventData eventData)
|
|
|
|
|
{
|
|
|
|
|
if (snap == false) return;
|
|
|
|
|
|
|
|
|
|
dragging = false;
|
|
|
|
|
|
|
|
|
|
if (bindParent.BindPath != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
// 바인딩 패스가 있다면 값을 바꿔서 OnChange를 불리게하는쪽으로 일원화
|
|
|
|
|
index = -1;
|
|
|
|
|
// anchoredPosition은 -로 가기때문에 인덱스 자체는 -로 세팅해야함 // 나중에는 확장가능성 생각해서 추가 개선
|
|
|
|
|
if (scrollRect.horizontal)
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(indexBind, Mathf.Clamp(-Mathf.RoundToInt(container.anchoredPosition.x / itemSize), 0, container.sizeDelta.x / itemSize));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(indexBind, Mathf.Clamp(Mathf.RoundToInt(container.anchoredPosition.y / itemSize), 0, container.sizeDelta.y / itemSize));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 별도의 바인딩패스를 사용하지 않는 구성
|
|
|
|
|
snapping = true;
|
|
|
|
|
snapTargetPosition = scrollRect.horizontal
|
|
|
|
|
? new Vector2(Mathf.Clamp(Mathf.Round(container.anchoredPosition.x / itemSize) * itemSize, -container.sizeDelta.x, 0), container.anchoredPosition.y)
|
|
|
|
|
: new Vector2(container.anchoredPosition.x, Mathf.Clamp(Mathf.Round(container.anchoredPosition.y / itemSize) * itemSize, 0, container.anchoredPosition.y));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void OnDrag(PointerEventData eventData)
|
|
|
|
|
{
|
|
|
|
|
if (snap == false) return;
|
|
|
|
|
|
|
|
|
|
snapping = false;
|
|
|
|
|
|
|
|
|
|
if (dragging == false)
|
|
|
|
|
{
|
|
|
|
|
OnBeginDrag(eventData);
|
|
|
|
|
dragging = true;
|
|
|
|
|
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(stateBind, "Dragging");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void StartScreenChange()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|