본문 바로가기
카테고리 없음

유니티3D의 UI Toolkit (6) - 스크롤 UI + C#

지난 시간에는 '흥부가 기가 막힌' 일들이 일어났었지요 :)
그래서 UI ToolKit 의 스크롤뷰 창을 아래와 같이 채워보았습니다.

흥부의 형 놀부도 질세라, 본인도 기가 막히다고 말하는군요.
그런데 놀부는 흥부처럼 한땀 한땀 Label(레이블)을 수작업으로 넣는게 아니라,
C# 스크립트를 이용해서 자동으로 스크롤뷰를 채우는군요.

UIToolKit 의 스크롤뷰를 채우는 핵심코드

아무래도 놀부가 처세술이 더 나은가 봅니다 :) 어떻게 하는지 보도록 할까요?

이제 성탄 시즌이니만큼 경쾌한 찬양곡 공유 드립니다.
취향 맞으시면 들어보시면서 읽어내려가는 걸 강추드립니다 :)


ScrollView(스크롤뷰)의 이름 명명


먼저 스크롤뷰의 이름을 지어주어야 합니다.
UI Builder(빌더) 창를 열어
1) ScrollView 화면요소를 선택,
2) Inspector(인스펙터) 창의 최상단 입력란에서 이름을 입력해 주세요. 크레이는 'myScroll'로 하겠습니다. 

내용물 '흥부가 기가막혀'는 삭제해도 되지만 삭제하지 않아도 무방합니다.
어차피 C# 스크립트가 스크롤바 내부를 싹~ 비우고 놀부의 사연을 채워줄 테니까요.


C# 스크립트 준비


이제 지난번에 만들었단 MyUI 스크립트를 수정해봅시다.
UI Builder 창을 닫고 MyUI 스크립트를 더블클릭해서 비주얼 스튜디오를 띄워 주세요.

지난번에 버튼으로 레이블 내용을 바꾸는 스크립트가 아래와 같이 남아 있을 겁니다.

using UnityEngine;
using UnityEngine.UIElements;

public class myUi : MonoBehaviour
{
    Label myLabel;
    Button myButton;

    private void OnEnable()
    {
        // UIDocument 컴포넌트를 가져옵니다.
        var uiDocument = GetComponent<UIDocument>();

        // 루트 요소를 가져옵니다.
        var root = uiDocument.rootVisualElement;

        myLabel = root.Q<Label>("myLabel");
        myButton = root.Q<Button>("myButton");
        myButton.clicked += MyButton_clicked;
    }

    private void MyButton_clicked()
    {   
        myLabel.text = "헬로우,유니버스!";
    }
}

우선 내용을 싹 비워 기본 형으로 바꿔 줍니다.
아래와 같이 불필요한 스크립트를 우선 제거해주는데요.

제거 후 남은 스크립트는 아래와 같습니다.

using UnityEngine;
using UnityEngine.UIElements;

public class myUi : MonoBehaviour
{
    private void OnEnable()
    {
        // UIDocument 컴포넌트를 가져옵니다.
        var uiDocument = GetComponent<UIDocument>();

        // 루트 요소를 가져옵니다.
        var root = uiDocument.rootVisualElement;
    
    }

}

스크롤 객체 받아오기


이제 스크롤뷰 객체를 먼저 받아오도록 합시다.
myScroll 객체를 클래스 속성에 선언하고, 이를 받아오는 코드를 삽입합니다.

using UnityEngine;
using UnityEngine.UIElements;

public class myUi : MonoBehaviour
{
    ScrollView myScroll;
    private void OnEnable()
    {
        // UIDocument 컴포넌트를 가져옵니다.
        var uiDocument = GetComponent<UIDocument>();

        // 루트 요소를 가져옵니다.
        var root = uiDocument.rootVisualElement;

        // 스크롤뷰를 받아옵니다.
        myScroll = root.Q<ScrollView>("myScroll");
    }

}

핵심 코드는 아래와 같습니다. 스크롤뷰든 버튼이든 레이블이든 모두 통용되지요.
myScroll = root.Q<ScrollView>("myScroll");
객체 = root.Q<컴포넌트명>("UI이름");


레이블 1개 C#  코드로 채우기


이어서 스크롤뷰를 싹 비우고 레이블을 1개 채우는 코드를 만들어볼텐데요.
실시간으로 생성, 추가해보도록 하겠습니다.

using UnityEngine;
using UnityEngine.UIElements;

public class myUi : MonoBehaviour
{
    ScrollView myScroll;
    private void OnEnable()
    {
        // UIDocument 컴포넌트를 가져옵니다.
        var uiDocument = GetComponent<UIDocument>();

        // 루트 요소를 가져옵니다.
        var root = uiDocument.rootVisualElement;

        // 스크롤뷰를 받아옵니다.
        myScroll = root.Q<ScrollView>("myScroll");

        myScroll.Clear();
        myScroll.Add(new Label("놀부가 기가 막혀"));
    }

}

짐작으로 아실수 있겠지만, 아래코드는 스크롤뷰 내부 영역을 싹 비우는 코드입니다.
myScroll.Clear();

그 다음 실시간으로 레이블 객체을 생성하여
new Label("놀부가 기가 막혀")

생성한 객체를 스크롤바에 추가해줍니다.
myScroll.Add ( 위 내용 );

그 결과로 유니티에서 실행해보면 아래 화면과 같은 결과를 보실 수 있는데요.
"놀부가 기가 막혀"라는 글씨가 있긴 한데, 검정색이라 잘 보이지는 않는군요.

이번에는 레이블 색상을 노란색으로 바꿔볼텐데요.
그러려면 임시로라도 레이블 객체를 변수로 받은 다음 색상을 변경해 주어야 합니다.

using UnityEngine;
using UnityEngine.UIElements;

public class myUi : MonoBehaviour
{
    ScrollView myScroll;
    private void OnEnable()
    {
        // UIDocument 컴포넌트를 가져옵니다.
        var uiDocument = GetComponent<UIDocument>();

        // 루트 요소를 가져옵니다.
        var root = uiDocument.rootVisualElement;

        // 스크롤뷰를 받아옵니다.
        myScroll = root.Q<ScrollView>("myScroll");

        myScroll.Clear();
        Label myLabel = new Label("놀부가 기가 막혀!");
        myLabel.style.color = Color.yellow;
        myScroll.Add(myLabel);
    }

}

<유니티 실행 화면>

이제 글씨가 잘 보이는군요!
핵심 코드는 아래와 같습니다.
레이블을 실시간으로 만들어, 임시로 변수에 넣고,

Label myLabel = new Label("놀부가 기가 막혀!");

글씨 색상을 노란색으로 바꿔 준 다음
myLabel.style.color = Color.yellow;

임시 변수를 스크롤바에 넣어주면 끝!
myScroll.Add(myLabel);


놀부의 욕심, 1000번을 말해!


이렇게 C# 코드를 이용해서 하나의 레이블을 표시한 걸 생각화면,
수작업으로 하나를 표시한 것보다 시간이 더 많이 걸린것 같아 배아픈 놀부입니다.
놀부는 한가지 꾀를 내었는데요.
자동화의 최대 장점은 무엇인가요? 바로 '자동 반복'입니다.

놀부를 '기가 막혀'라는 문구를 1000번이나 표시하기로 마음먹었습니다.
모든 프로그래밍 언어에서 사용하는 for 반복문은 C# 언어에서도 유용하게 사용하지요 :)

using UnityEngine;
using UnityEngine.UIElements;

public class myUi : MonoBehaviour
{
    ScrollView myScroll;
    private void OnEnable()
    {
        // UIDocument 컴포넌트를 가져옵니다.
        var uiDocument = GetComponent<UIDocument>();

        // 루트 요소를 가져옵니다.
        var root = uiDocument.rootVisualElement;

        // 스크롤뷰를 받아옵니다.
        myScroll = root.Q<ScrollView>("myScroll");

        myScroll.Clear();

        for (int i = 1; i < 1000; ++i)
        {
            Label myLabel = new Label("놀부가 " + i.ToString() + " 기가 막혀!");
            myLabel.style.color = Color.yellow;
            myScroll.Add(myLabel);
        }
    }

}

< 유니티 실행 결과 >

몇번이나 기가 막히다고 하였을까요?
스크롤바를 맨 아래로 내려보면,
무려 999번이나 기가 막히다고 이야기한 것을 보실 수 있습니다.
투자 시간 대비 흥부보다 가성비가 높다고 볼 수 있겠지요? :)

핵심코드는 아래와 같습니다.

1 ~ 999까지 999번 반복하는 코드인데요.

for (int i = 1; i < 1000; ++i) { ... }

만일 1000까지 반복하려면 아래와 같이 사용하시면 됩니다.

for (int i = 1; i <= 1000; ++i) { ... }

레이블을 생성할 때 횟수를 표시하는 부분이 추가되었지요.

Label myLabel = new Label("놀부가 " + i.ToString() + " 기가 막혀!");

이와 같이 C# 코드를 이용해서 요소를 추가할 수 있는데요.
필요에 따라 UI툴을 이용해서 배치하는 방법과 C# 코드를 이용해서 배치하는 2가지 방법을 혼용하면
효율이 매우 높을 것으로 생각됩니다.


마무~리


뭐니 뭐니해도 UI Toolkit의 꽃은 XML 입니다.
다음 시간에는 UI Toolkit의 XML을 다뤄보도록 할텐데요.
HTML 코딩에 익숙하신 분이라면 더욱 친숙할 수 있습니다.

필요하신 분께 도움이 되셨나 모르겠군요.
아무쪼록 방문하신 모든 분께 감사드립니다!
건강하세요~

🍜☕🌽🍒🍇🍍🍈🍏


다음편 이야기 : https://itadventure.tistory.com/646

 

유니티3D의 UI Toolkit (7) - XML과 스타일 시트

다시 봄이 오려나 봅니다 :) 최근 이상 기온 때문인지 12월에 포근한 날씨를 경험하네요. 점점 계절의 경계가 불명확해져가는 것 같습니다. 생뚱맞지만 봄 분위기(?) 의 경쾌한 CCM 하나 올려드립

itadventure.tistory.com