유니티에서 엔딩 크레딧 등 플레이어에게 자동으로 긴 글을 보여줄 때 자동으로 스크롤이 되어 글 또는 콘텐츠를 보여줄 필요가 있습니다. 이것을 가능하게 하기 위해 자동 스크롤 기능을 구현하고 정리하였습니다.
💬 서론
- 스크롤 뷰 영역을 자동으로 스크롤해줍니다.
- 스크롤 뷰의 콘텐츠의 크기에 상관없이 일정한 속도로 자동 스크롤을 사용할 수 있습니다.
- 또한 런타임도중 콘텐츠 영역의 크기가 변해도 일정한 속도를 보장합니다.
✅ 구현(스크립트 작성)
· AutoScroll.cs
더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class AutoScroll : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
[Header("자동으로 스크롤 할 양(width 또는 height)")]
[SerializeField] private float mScrollSpeed = 0.1f; // 스크롤 속도
[Header("자동 스크롤을 시작할 딜레이 시간")]
[SerializeField] private float mScrollDelay = 2f; // 자동 스크롤 시작 딜레이
[Header("세로 방향의 스크롤인가?")]
[SerializeField] private bool mIsVerticalScroll;
[Header("직접 스크롤 할 대상의 트랜스폼")]
[SerializeField] private RectTransform mScrollRectTransform;
private ScrollRect mScrollRect; // 스크롤 영역
private Coroutine? mCoAutoScroll; // 자동 스크롤 코루틴
private bool mIsPointerEnter = false; // 현재 포인터가 영역에 들어왔는가?
private void Awake()
{
mScrollRect = GetComponent<ScrollRect>();
}
private void OnEnable()
{
ToggleAutoScroll(true);
}
private void OnDisable()
{
ToggleAutoScroll(false);
}
private void ToggleAutoScroll(bool isEnable)
{
mScrollRect.velocity = Vector2.zero;
if (mCoAutoScroll is not null)
StopCoroutine(mCoAutoScroll);
if (isEnable)
{
mCoAutoScroll = StartCoroutine(CoAutoScroll());
mIsPointerEnter = false;
}
}
private IEnumerator CoAutoScroll()
{
yield return new WaitForSecondsRealtime(mScrollDelay);
while (true)
{
// 스크롤 방향에 따라 계산
if (mIsVerticalScroll)
mScrollRect.verticalNormalizedPosition -= mScrollSpeed * Time.deltaTime / mScrollRectTransform.sizeDelta.y;
else
mScrollRect.horizontalNormalizedPosition -= mScrollSpeed * Time.deltaTime / mScrollRectTransform.sizeDelta.x;
// 스크롤의 끝 영역에 도달했다면 방향을 반전
if ((mIsVerticalScroll ? mScrollRect.verticalNormalizedPosition : mScrollRect.horizontalNormalizedPosition) <= 0f || (mIsVerticalScroll ? mScrollRect.verticalNormalizedPosition : mScrollRect.horizontalNormalizedPosition) >= 1f)
mScrollSpeed = -mScrollSpeed;
// 영역에 포인터가 진입한 상태에서 클릭 또는 드래그를 했다면?
if (mIsPointerEnter && (Input.GetMouseButton(0) || Input.GetAxis("Mouse ScrollWheel") > 0))
ToggleAutoScroll(false);
yield return null;
}
}
public void OnPointerEnter(PointerEventData eventData)
{
mIsPointerEnter = true;
}
public void OnPointerExit(PointerEventData eventData)
{
mIsPointerEnter = false;
ToggleAutoScroll(true);
}
}
private IEnumerator CoAutoScroll()
- 스크롤 영역을 자동으로 스크롤해줍니다.
- 스크롤의 방향에 맞게 verticalNormalizedPosition 또는 horizontalNormalizedPosition의 값을 조절하여 스크롤의 위치를 변경합니다.
- mScrollRectTransform.sizeDelta의 크기만큼 나누어 스크롤 뷰의 콘텐츠의 크기에 상관없이 동일한 속도로 스크롤을 할 수 있도록 합니다.
- 이 기능은 런타임 도중 실시간으로 변하는 크기에도 적응하여 동일한 속도를 유지하도록 합니다.
public void OnPointerEnter(PointerEventData eventData)
{
mIsPointerEnter = true;
}
- 사용자의 커서나 터치가 스크롤 뷰 영역에 들어왔다면 mIsPointerEnter을 활성화저저여 포인터가 들어온 상태로 설정해 놓습니다.
- 이 값이 참일 경우 코루틴에서 사용자가 클릭(또는 터치)하거나, 마우스 스크롤을 사용하는 경우 코루틴을 멈춰 자동 스크롤을 중단하도록 합니다.
✅ 적용 방법
- ScrollRect 컴포넌트가 있는 Scroll View 오브젝트에 AutoScroll 스크립트를 사용합니다.
- mScrolRectTransform은 가로, 세로의 길이를 참고하기 위해 사용하며 Content 트랜스폼을 사용합니다.
- 스크롤뷰가 가로방향인지, 세로방향인지 설정을 합니다.
- 자동으로 스크롤할 양을 설정하고, 스크롤 시작 딜레이시간을 설정하면 끝입니다.
✅ 결과
- 위 영상과 같이 일반적인 상태에서는 자동으로 스크롤이 됩니다.
- 스크롤 영역에 끝에 도달하는 경우 스크롤의 방향이 반대가 됩니다.
- 자동 스크롤 도중 플레이어가 직접 스크롤을 수행하는 경우 자동 스크롤은 멈추고, 사용자의 마우스 포인터가 스크롤뷰 영역을 벗어나는 경우 자동 스크롤이 다시 시작되는 것을 볼 수 있습니다.
'unity game modules' 카테고리의 다른 글
[유니티] 레벨, 경험치 시스템 (0) | 2023.03.24 |
---|---|
[유니티] 환경 사운드 (Ambient Area) (0) | 2023.03.23 |
[유니티] 외곽선 쉐이더 구현 및 관리 (0) | 2023.03.21 |
[유니티] Skybox Blender (0) | 2023.03.09 |
[유니티] 검기 이펙트, VFX 관리 (0) | 2023.03.07 |