Unity2D 궁수의 전설 UI 따라만들기 (2)
다음의 영상을 참고하여 궁수의 전설 UI를 제작하고 있다.
지난 번 글까지는 좌우로 이동가능한 패널이 있는 가로 스크롤 뷰까지 완성했다.
이어서 각 패널 안에 들어가는 세로 스크롤 패널을 만들어보자.
세로 스크롤되는 패널 만들기
새로 추가한 Scroll View의 이름을 ShopScrollView
로 해주자.
원래의 ShopPanel 이미지는 지워주자.
또한 나머지는 가로 Scroll View와 전부 반대 설정이다.
이제 스크롤뷰는 완성이다.
아래에 Image를 추가해놓고 위아래로 움직여보면 잘 움직이는 것을 확인할 수 있다.
가로와 세로 스크롤 동시에 되게 만들기
지금 현재 상태로는 문제가 하나 있다.
새로 만든 세로 스크롤 뷰는 문제없이 동작하지만, 기존의 가로 스크롤뷰가 작동을 안하게 된다.
자식 오브젝트인 세로 스크롤 뷰가 더 앞에 있어서 그런데, 이를 해결하기 위해 자식 오브젝트에서 가로 드래그가 발생할 경우, 이 이벤트를 부모 오브젝트로 옮겨주는 방식을 사용할 것이다.
자식 스크롤뷰의 Scroll Rect 재구성
먼저 ShopScrollView의 Scroll Rect 컴포넌트를 제거하자.
그리고 ScrollScript라는 이름의 스크립트를 새로 생성해서 ShopScrollView에 붙여주자.
ScrollScript를 열어서 Monobehaviour 대신 ScrollRect를 상속받도록 고쳐주자.
public class ScrollScript : ScrollRect
{
}
이제 이것을 저장하고 Inspector에서 확인해보면, Scroll Rect와 완전히 똑같은 Inspector 구성을 보이는 것을 알 수 있다.
이제 이 Inspector를 구성하자.
Content
에는 ShopScrollView/Viewport
하위에 있는 Content
를,
Horizental
은 체크 해제,
Viewport
에는 ShopScrollView
의 Viewport
를,
Vertical Scrollbar
에는 Scrollbar Vertical 오브젝트를 넣어주자.
이제 스크립트를 작성하자.
우리는 기존에 인터페이스를 받아 OnBeginDrag
를 작성해줬던 것처럼
OnBeginDrag
와 OnEndDrag
를 override 해줄 것이다!
이제 다음과 같이 코드를 작성해주자.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ScrollScript : ScrollRect
{
bool forParent;
GameObject parentScrollView;
NestedScrollManager NM;
ScrollRect parentScrollRect;
protected override void Start()
{
parentScrollView = transform.parent.parent.parent.gameObject;
NM = parentScrollView.GetComponent<NestedScrollManager>();
parentScrollRect = parentScrollView.GetComponent<ScrollRect>();
}
public override void OnBeginDrag(PointerEventData eventData)
{
// 드래그 시작하는 순간 수평이동이 크면 부모가 드래그 시작한 것, 수직이동이 크면 자식이 드래그 시작한 것
forParent = Mathf.Abs(eventData.delta.x) > Mathf.Abs(eventData.delta.y);
if (forParent)
{
parentScrollRect.OnBeginDrag(eventData);
NM.OnBeginDrag(eventData);
}
else base.OnBeginDrag(eventData);
}
public override void OnDrag(PointerEventData eventData)
{
if (forParent)
{
parentScrollRect.OnDrag(eventData);
}
else base.OnDrag(eventData);
}
public override void OnEndDrag(PointerEventData eventData)
{
if (forParent)
{
parentScrollRect.OnEndDrag(eventData);
NM.OnEndDrag(eventData);
}
else base.OnEndDrag(eventData);
}
}
위 코드는
드래그를 했을 때
수직이동이 크면
그대로 자기자신의 ScrollRect
의 OnBeginDrag
를,
수평이동이 크다면
부모 스크롤뷰의 OnBeginDrag
들을 호출해준다.
옆으로 갔다가 돌아오면 세로 스크롤뷰의 위치 초기화
이제 옆 패널로 갔다가 돌아오면 그 패널이 가장 위로 다시 올라가 있도록 만들어 줄 것이다.
NestedScrollManager.cs
에 다음 내용을 추가해주자.
[SerializeField] Transform contentTr;
public void OnEndDrag(PointerEventData eventData)
{
isDrag = false;
targetPos = SetPos();
// 스크롤뷰 드래그를 멈추면 한 패널만 보이도록 targetPos를 설정
if (curPos == targetPos)
{
if (eventData.delta.x > thresholdSpeed && curPos - distance >= 0)
targetPos = curPos - distance;
else if (eventData.delta.x < -thresholdSpeed && curPos + distance < 1f)
targetPos = curPos + distance;
}
// 목표가 수직스크롤이고, 옆에서 옮겨왔다면 수직스크롤을 맨 위로 올림
for (int i = 0; i < SIZE; ++i)
if (curPos != pos[i] && targetPos == pos[i])
{
Transform child = contentTr.GetChild(i);
if (child.GetComponent<ScrollScript>() != null)
child.GetChild(1).GetComponent<Scrollbar>().value = 1;
break;
}
}
Inspector에선 자식 오브젝트 Content를 넣어주면 된다.
이제 하단의 탭버튼을 만들 차례이다.
해당 부분은 3편에서 다루도록 하겠다.
Uploaded by N2T