일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 번역
- inputsystem
- 리눅스
- 자율비행
- UI
- coroutine
- 드론
- 이브
- 언성스토리
- 미니적도의
- 미타니
- 오브젝트이동
- 천체사진
- 온라인
- 라즈베리파이
- 이브뉴스24
- 게임제작
- 유니티
- 데포르메
- C언어
- 킥스타터
- 이브온라인
- DX라이브러리
- 포크스푼
- 점상
- This is EVE
- 스카이트래커
- centos
- 유루캠
- 오픈스택
- Today
- Total
게임개발 예제모음
스크롤뷰 방향키로 조작하기 본문
○ 구현목표
- 유니티의 스크롤뷰는 마우스(또는 터치)등을 통한 드래그 또는 스크롤바를 조작하여 동작한다 - 이 포스팅에선 UI상 목록을 버튼(Button)으로 구현하며 현재 보이는 영역보다 목록이 더 많아 스크롤이 필요한 경우를 한정한다. - 또한 버튼의 이동은 컨트롤러 또는 키보드등 InputSystem의 Vector2값으로 이동하는 경우를 위주로 서술한다. ※ 어차피 마우스나 터치 조작은 다른 설정 없이도 잘 작동하기 때문이다. |
○ 또한 이 포스팅은 아래의 포스팅에서 설명한 현재 선택중인 버튼을 확인하는 EventSystem기능을 활용한다.
2025.06.05 - [유니티 메모장] - 현재 선택중인 버튼 확인
현재 선택중인 버튼 확인
2025.06.04 - [유니티 메모장] - UI만들기 : 하위 메뉴버튼 이동 및 복귀 UI만들기 : 하위 메뉴버튼 이동 및 복귀○ 구현목표메인메뉴에서의 선택으로 하위메뉴 버튼이 나타나 커서가 이동서브메뉴를
capsuleer.tistory.com
○ 방향키를 통한 버튼 이동은 아래 포스팅을 참고 하자.
2025.06.03 - [유니티 메모장] - UI 만들기 : 버튼 선택
UI 만들기 : 버튼 선택
○ 새로 메뉴를 구성하고 컨트롤러(액션맵)을 통한 선택이 가능하도록 구성○ 원하는 메뉴를 만들기 위한 버튼 오브젝트 추가○ 추가한 버튼을 정렬 * Creat Empty를 이용하여 빈 오브젝트 생성후
capsuleer.tistory.com
○ 구현방법
- 최초에 스크롤뷰 내부에 버튼의 위치를 받아와서 화면을 벗어날 경우 스크롤바를 움직이는 로직을 구성했음. - 하지만 스크롤뷰 내부의 버튼은 스크롤뷰 부모 오브젝트의 상대 위치를 받아오면서 화면 밖으로 벗어나는지 판단하지 못한다. - 따라서 별도 스크롤뷰 외부에 RectTransform을 보유한 오브젝트를 추가하고 이 오브젝트를 기준점으로 스크롤을 조절한다. |
○ 버튼 배치
① 버튼 배치 전에 스크롤뷰 오브젝트를 만든다. [ Hierarchy (우클릭) - UI - Scroll View]
② 스크롤뷰를 만들면 자식 오브젝트로 Viewport, Scrollbar Horizontal, Scrollbar Vertical이 같이 생성된다.
※ 스크롤 시킬 오브젝트 (버튼따위)는 Viewport - Content 하위에 위치시킨다.
※ Scrollview의 Scroll Rect 컴포넌트에서 Movement Type을 [Unrestricted]로 변경한다.
옵션명 | 기능 |
Unrestricted | 제한 없음 |
Elastic | Viewport 내부의 컨텐트 내용이 화면 밖으로 벗어나면 부드럽게 화면 안으로 복귀시킨다 |
Clamped | Viewport 내부의 컨텐트 내용이 화면 밖으로 벗어나지 못한다 |
※ 이 포스팅에선 유저의 움직임에 따라 수동으로 스크롤을 조절하므로 제한이 없는 Unrestricted로 설정한다.
※ 이 포스팅에선 가로 스크롤은 사용하지 않으므로 Scrollbar Horizontal은 비활성화 한다.
※ 스크롤뷰 외부에 위치 확인을 위한 오브젝트 하나를 생성한다. (Empty Object로 충분함 - 이후 Cursor오브젝트로 기술)
③ Cursor의 위치 확인을 위한 스크립트 작성 (MyPosition.cs)
※ 새로운 스크립트를 생성하여 Cursor에 추가
※ 스크립트 작성 - 변수 설정
using UnityEngine;
using UnityEngine.EventSystems;
public class MyPosition : MonoBehaviour
{
// EventSystem을 캐싱하기위한 변수 선언
[SerializeField] GameObject ObjectEventSystem;
EventSystem myEventSystem;
// Cursor오브젝트의 위치변경 및 현재위치 확인을 위한 변수
RectTransform myRectTransform;
// 오브젝트의 위치 확은 후 y좌표값을 저장하기위한 변수
[HideInInspector] public float cursorVertical;
void Start()
{
// Cursor오브젝트의 RectTransfrom캐싱
myRectTransform = GetComponent<RectTransform>();
// objectEventSystem의 EventSystem캐싱
myEventSystem = ObjectEventSystem.GetComponent<EventSystem>();
}
}
- cursorVertical변수는 다른 스크립트에서도 참조하기 때문에 public변수로 선언
- 다만 인스펙터에선 보이지 않는것을 원하기 때문에 앞에 [HideInInspector]를 붙여준다
※ 선언한 objectEventSystem에 EventSystem오브젝트를 어태치
※ 스크립트 작성 - 오브젝트의 위치 변경 및 현재 Y좌표값 반환
void Update()
{
// 선택중인 버튼의 현재 위치값을 저장
var temp = myEventSystem.currentSelectedGameObject.transform.position;
// 위에서 확인한 위치로 Cursor오브젝트 이동
myRectTransform.position = temp;
// Cursor오브젝트의 Y좌표값 저장
cursorVertical = myRectTransform.anchoredPosition.y;
}
④ Scrollbar Vertical 조절을 위한 스크립트 작성 (AutoScroll.cs)
※ 새로운 스크립트를 생성하여 Cursor에 추가
※ 스크립트 작성 - 변수선언
public class AutoScroll : MonoBehaviour
{
//ScrollView 관련 변수 선언
[SerializeField] GameObject scrollWindow; //오브젝트 캐싱
RectTransform scrollRectTransfrom; // 오브젝트 캐싱
Vector2 scrollViewSize; // ScrollView의 크기
Vector2 scrollViewPos; // ScrollView의 위치
float svMax; // ScrollView의 최상단 좌표
float svMin; // ScrollView의 최하단 좌표
//Cursor 관련 변수 선언
[SerializeField] GameObject objectCursor; // 오브젝트 캐싱
MyPosition cusorPosition; // 오브젝트 캐싱
//Scrollbar Vertical 관련 변수 선언
[SerializeField] float scrollSpeed = 0.1f;
Scrollbar myScrollbar;
}
※ 관련 오브젝트 어태치
※ 스크립트 작성 - 변수 초기화
void Start()
{
// Scrollbar 캐싱
myScrollbar = GetComponent<Scrollbar>();
// Cursor오브젝트의 스크립트 MyPosition 캐싱
cusorPosition = objectCursor.GetComponent<MyPosition>();
// ScrollView의 RectTransform캐싱
scrollRectTransfrom = scrollWindow.GetComponent<RectTransform>();
// ScrollView의 세로 크기 확인
scrollViewSize.y = scrollRectTransfrom.rect.height;
// ScrollView의 세로좌표 확인
scrollViewPos.y = scrollRectTransfrom.anchoredPosition.y;
// ScrollView의 최상단, 최하단 위치 확인
svMax = scrollViewPos.y + (scrollViewSize.y / 2) - 50;
svMin = scrollViewPos.y - (scrollViewSize.y / 2) + 50;
}
※ 스크립트 작성 - Scrollbar Vertical 조절 (Scrollbar 컴포넌트의 Value속성)
void Update()
{
if (scrollWindow.activeInHierarchy) // Scrollview오브젝트가 활성화시에만 동작
{
if (cusorPosition.cursorVertical < svMin) // Cursor가 최하단 아래에 위치할 때
{
myScrollbar.value -= scrollSpeed * Time.deltaTime; // Value값을 삭감
}
else if (cusorPosition.cursorVertical > svMax) // Cursor가 최상단 위에 위치할 때
{
myScrollbar.value += scrollSpeed * Time.deltaTime; // Value값을 증가
}
}
}
○ 실행 테스트
○ 스크립트 전문
※ MyPosition.cs
using UnityEngine;
using UnityEngine.EventSystems;
public class MyPosition : MonoBehaviour
{
[SerializeField] GameObject ObjectEventSystem;
EventSystem myEventSystem;
RectTransform myRectTransform;
[HideInInspector] public float cursorVertical;
void Start()
{
myRectTransform = GetComponent<RectTransform>();
myEventSystem = ObjectEventSystem.GetComponent<EventSystem>();
}
void Update()
{
var temp = myEventSystem.currentSelectedGameObject.transform.position;
myRectTransform.position = temp;
cursorVertical = myRectTransform.anchoredPosition.y;
}
}
※ AutoScroll.cs
using UnityEngine;
using UnityEngine.UI;
public class AutoScroll : MonoBehaviour
{
[SerializeField] GameObject scrollWindow;
RectTransform scrollRectTransfrom;
Vector2 scrollViewSize;
Vector2 scrollViewPos;
float svMax;
float svMin;
[SerializeField] GameObject objectCursor;
MyPosition cusorPosition;
[SerializeField] float scrollSpeed = 0.1f;
Scrollbar myScrollbar;
void Start()
{
myScrollbar = GetComponent<Scrollbar>();
cusorPosition = objectCursor.GetComponent<MyPosition>();
scrollRectTransfrom = scrollWindow.GetComponent<RectTransform>();
scrollViewSize.y = scrollRectTransfrom.rect.height;
scrollViewPos.y = scrollRectTransfrom.anchoredPosition.y;
svMax = scrollViewPos.y + (scrollViewSize.y / 2) - 50;
svMin = scrollViewPos.y - (scrollViewSize.y / 2) + 50;
}
void Update()
{
if (scrollWindow.activeInHierarchy)
{
if (cusorPosition.cursorVertical < svMin)
{
myScrollbar.value -= scrollSpeed * Time.deltaTime;
}
else if (cusorPosition.cursorVertical > svMax)
{
myScrollbar.value += scrollSpeed * Time.deltaTime;
}
}
}
}
'유니티 메모장' 카테고리의 다른 글
오브젝트간 상호작용을 통한 애니메이션 클립 재생 (1) | 2025.06.11 |
---|---|
함수에서 특정 자료 반환하기 (0) | 2025.06.10 |
CSV파일을 로드하여 TEXT 출력 (0) | 2025.06.06 |
현재 선택중인 버튼 확인 (0) | 2025.06.05 |
UI만들기 : 하위 메뉴버튼 이동 및 복귀 (0) | 2025.06.04 |