내일배움캠프/Unity Final Projcet

[Unity] UI 패널 전환 효과를 DOTween으로 구현하기

danpat77 2025. 4. 16. 21:23

이번 포스트에서는 Unity UI에서 좌우로 슬라이드 전환되는 패널 전환 시스템을 구현한 과정을 소개합니다.
DOTween을 활용해 부드럽고 직관적인 전환 효과를 만들 수 있었고, 좌우 방향도 자연스럽게 처리해 사용성을 높였습니다.


목표

여러 개의 UI 패널을 Next, Prev 버튼으로 슬라이드 전환할 수 있게 만들고 싶었습니다.
전환 시 화면을 가득 채우는 전체 패널이 부드럽게 좌우로 움직이며 자연스럽게 교체되는 UI를 구현하는 것이 목표였습니다.


완성된 결과 미리보기

버튼 클릭 시, 다음 패널로 자연스럽게 전환되는 모습을 확인할 수 있습니다.

(실제 UI 구현 장면 – GIF )


구현 방식

핵심 기능 요약

  • RectTransform[] panels 배열에 전환할 UI 패널들을 담아 관리
  • currentIndex로 현재 보여지고 있는 패널 인덱스를 추적
  • DOTween을 이용해 anchoredPosition을 변경하며 슬라이드 애니메이션 처리
  • 양쪽 끝에서는 순환되도록 인덱스 범위 자동 조절

주요 코드


1. 기본 변수 선언 및 초기화

public RectTransform[] panels; // 전환 대상 패널들
public float slideDuration = 0.5f; // 슬라이드 애니메이션 지속 시간

[SerializeField] private int currentIndex = 0; // 현재 활성화된 패널 인덱스
private bool isSliding = false; // 슬라이딩 중 여부 체크

[SerializeField] private Button nextButton;
[SerializeField] private Button prevButton;

2. 버튼 이벤트 등록

private void Start()
{
    currentIndex = 0;
    SetOnClickButton();
}

private void SetOnClickButton()
{
    // 좌우 버튼 클릭 시 ShowPanel 호출
    nextButton.onClick.AddListener(() => ShowPanel(currentIndex - 1));
    prevButton.onClick.AddListener(() => ShowPanel(currentIndex + 1));
}

3. ShowPanel() - 전환 애니메이션의 핵심

public void ShowPanel(int index)
{
    // 슬라이딩 중이거나 같은 패널이면 무시
    if (index == currentIndex || isSliding) return;

    // 인덱스 범위 벗어나면 순환 처리
    if (index >= panels.Length) index = 0;
    else if (index < 0) index = panels.Length - 1;

    isSliding = true;

    RectTransform fromPanel = panels[currentIndex];
    RectTransform toPanel = panels[index];

    // 패널 순서 조정 (새 패널을 뒤에 배치)
    fromPanel.transform.SetAsLastSibling();
    toPanel.transform.SetAsFirstSibling();

    // 이동 방향 계산 (왼쪽/오른쪽)
    Vector2 panelPosition = currentIndex > index ? new Vector2(Screen.width, 0) : new Vector2(-Screen.width, 0);

    // 새 패널 위치 지정 및 활성화
    toPanel.gameObject.SetActive(true);
    toPanel.anchoredPosition = panelPosition;

    // DOTween 애니메이션
    fromPanel.DOAnchorPos(-panelPosition, slideDuration).SetEase(Ease.OutCubic);
    toPanel.DOAnchorPos(Vector2.zero, slideDuration).SetEase(Ease.OutCubic)
        .OnComplete(() =>
        {
            // 이전 패널 비활성화 및 리셋
            fromPanel.gameObject.SetActive(false);
            fromPanel.anchoredPosition = Vector2.zero;
            currentIndex = index;
            isSliding = false;
        });
}

구현 시 고민했던 포인트

  • 인덱스 자동 순환: 양쪽 끝에서도 끊기지 않고 루프되도록 처리
  • 중복 클릭 방지: isSliding으로 애니메이션 중 동작 중첩 방지
  • 슬라이드 방향: 현재 인덱스 기준으로 좌우 방향 자동 계산

마무리

이번 패널 전환 시스템은 단순하지만, 사용자 경험을 직관적으로 개선하는 핵심적인 UI 요소입니다.
DOTween을 이용하면 코드량도 줄이고, 애니메이션 퀄리티도 높일 수 있어 추천드립니다.