ProjectDDD/Packages/SLUnity/SLUI/SLUIScrollRect.cs

193 lines
6.2 KiB
C#
Raw Normal View History

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()
{
}
}
}