유니티/UI

유니티 이중 스크롤 뷰

민또배기 2022. 4. 18. 13:25
반응형

유니티 버전 : 2020.3.25f1(URP)

작업환경 : Mac (Monterey 12.2.1)

 

제가 원했던 동작은 아래 사진처럼 슬라이드를 하면 해당하는 메뉴가 나오게 되는 동작을 구현하고 싶었습니다.

하지만 스크롤 뷰 안에 스크롤 뷰를 넣으면 되겠구나 싶었지만 동작되지 않았습니다. 나중에 생성된 스크롤 뷰가 기존의 스크롤 뷰를 가리기 때문에 동작이 되지 않은것이죠

찾아보니 에셋스토어에서 판매되는 것도 있었는데... 그거도 좋지만 한번 구현해보는 방법도 좋겠다는 생각이들었습니다.

물론 이 또한 다른 분께서 만들어주신 코드가 있었습니다.(주소는 맨 아래)

 

' 하위 아이템으로 추가된 스크롤 뷰의 이벤트 상위 스크롤 뷰에 이벤트를 다시 돌려주는 방식 ' 이라고 합니다. 그러니 아래 사진처럼 내부 스크롤 뷰에 있는 이벤트로 배경 스크롤 뷰를 동작시키면 됩니다. 좌우로 움직일 땐 내부 스크롤이 동작되고 상하로 움직일 땐 배경 스크롤이 동작되게 한다는 것으로 이해 했습니다.

만약을 위해 배경 스크롤 뷰는 Horizontal을 꺼두시고(삭제) 내부 스크롤 뷰는 Vertical을 꺼두시면(삭제) 합니다.

 

소스코드는 다음과 같습니다.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class ScrollTest : ScrollRect
{
    bool routeToParent = false;

    void DoForParents<T>(Action<T> action) where T : IEventSystemHandler
    {
        Transform parent = transform.parent;
        while (parent != null)
        {
            foreach (var component in parent.GetComponents<Component>())
            {
                if (component is T)
                {
                    action((T)(IEventSystemHandler)component);
                }
            }
            parent = parent.parent;
        }
    }

    public override void OnInitializePotentialDrag(PointerEventData eventData)
    {
        DoForParents<IInitializePotentialDragHandler>((parent) => { parent.OnInitializePotentialDrag(eventData); });
        base.OnInitializePotentialDrag(eventData);
    }

    public override void OnDrag(PointerEventData eventData)
    {
        if (routeToParent) DoForParents<IDragHandler>((parent) => { parent.OnDrag(eventData); });
        else base.OnDrag(eventData);
    }


    public override void OnBeginDrag(PointerEventData eventData)
    {
        if (!horizontal && Math.Abs(eventData.delta.x) > Math.Abs(eventData.delta.y)) routeToParent = true;
        else if (!vertical && Math.Abs(eventData.delta.x) < Math.Abs(eventData.delta.y)) routeToParent = true;
        else routeToParent = false;

        if (routeToParent) DoForParents<IBeginDragHandler>((parent) => { parent.OnBeginDrag(eventData); });
        else base.OnBeginDrag(eventData);
    }

    public override void OnEndDrag(PointerEventData eventData)
    {
        if (routeToParent) DoForParents<IEndDragHandler>((parent) => { parent.OnEndDrag(eventData); });
        else base.OnEndDrag(eventData);
    }

}

작성을 하시면 넣어주셔야하는데 Scroll View 의 ScrollRect컴포넌트를 삭제한 뒤 위 소스코드를 추가합니다.

안그러면 추가되지 않습니다. 내부 스크롤 뷰에는 Parent 오브젝트를 추가합니다.

 

 

https://drehzr.tistory.com/516#google_vignette

 

 

 

반응형

'유니티 > UI' 카테고리의 다른 글

유니티 텍스트 메쉬 프로(Text Mesh Pro)한글 사용하기  (0) 2023.03.07
유니티 UI - infinite scroll  (0) 2022.05.24
Unity TabMenu  (0) 2022.05.16
Unity Circle Slider UI  (0) 2022.04.18
유니티 Swipe Menu(Carousel) UI  (0) 2022.04.07