[Unity] 3. 유저 인터페이스 UI

치치·2025년 2월 17일
0

Unity

목록 보기
3/27
post-thumbnail

UI


렌더링 파이프 라인 : 3D 그래픽스를 화면에 출력하는 과정에서의 여러 단계를 관리하는 시스템


<스페이스 (좌표계) >

  • 스페이스란?
    객체의 위치, 회전, 크기 등을 표현하는 기준이 되는 공간을 의미한다

  1. 로컬 스페이스 (Local Space)
    '객체 자신'의 좌표계를 의미
  • 게임 오브젝트 자체의 공간 (ex) 블렌더, 마야 등

  • 지정된 좌표값이 월드 스페이스에 그대로 적용된다
    (보통은 0, 0, 0)

  • 객체가 자기 자신을 기준으로 위치하고 회전하며 크기를 설정하는 좌표계이다

  • 객체가 부모의 자식으로 존재할때는, 부모 객체에 영향을 받는다


  1. 월드 스페이스 (World Space)
  • 3차원 공간에 게임 오브젝트를 배치하는 공간이다

  • 모든 객체는 월드 스페이스에서의 위치를 가지고, 씬 내의 고정된 좌표계이다

  • 부모 객체가 이동하거나 회전해도, 자식 객체는 월드 스페이스에서 고정된 위치를 가진다


  1. 뷰 스페이스 (View Space)
  • 카메라를 기준으로 하는 좌표계이다

  • Camera Space 라고도 한다

  • 카메라를 기준으로 카메라 앞에 객체들이 어떻게 배치될 지 나타낸다

  • 3차원 공간과 UI를 배치하는 공간이 다르다


  1. 스크린 스페이스(Screen Space)
  • 화면 상의 2D 좌표계를 의미한다

  • UI 배치, 마우스 위치와 관련있다

  • 스크린 스페이스에서 화면 좌표 (0, 0) 은 왼쪽 하단을 나타낸다

마우스로 게임씬에서 화면 클릭 시 스크린 스페이스로잡힌다 (2D)
-> 월드 스페이스의 게임 오브젝트를 클릭 하고 싶으면 따로 잡아주어야한다 (스페이스 변경)


렌더링 문제

Canvas 컴포넌트의 Render Mode를 사용해야한다
✅ 렌더링 모드에 따라 렌더링 되는 우선순위가 바뀐다


Screen Space - Overlay

  • UI가 화면 위에 오버레이 된 형태로 렌더링 된다
    -> UI가 항상 화면의 최상위 레이어로 렌더링되기 때문에 게임 오브젝트들이 가려질 수 있다

Screen Space - Camera

  • UI가 카메라의 시점에서 렌더링 된다
    -> UI가 카메라 앞에 위치하며, 게임 오브젝트와 겹치지 않도록 조정이 가능하다

World Space

  • UI가 3D 공간에 배치되어 3D 오브젝트처럼 렌더링 된다


UI 컴포넌트 다루기

UI 컴포넌트 계층구조

  • Canvas : UI를 배치하는 창
    -> 계층 구조로 자식에 여러개의 UI들이 배치될 수 있다
    -> ex) 이미지, 버튼, 레이아웃 등

EventSystem

  • 마우스 입력은 카메라에서 Ray(광선)를 발사해서 충돌이 발생하면 이벤트 발생

  • 이벤트 시스템이 없으면 버튼 컴포넌트가 제대로 동작하지 않는다 (상호작용x)

  • 이미지를 생성하면 기존 위치가 다르기 때문에 Rect Transform 위치를 초기화해주기 (0, 0, 0)


Transform pivot

  • 이미지의 기본 Pivot(기준점)은 디폴트 값 (0.5 / 0.5) 이다

  • 기준점을 가운데로 잡으려면 이미지의 반반위치로 잡으면 된다



Canvas 우선순위

  • 계층 구조상 제일 위에있는 UI 컴포넌트가 제일 밑에 배치된다
    -> 아래로 갈수록 위에 보인다
    -> 해당 이미지에서는 Image가 버튼 아래에 깔린 것 처럼 보임


Canvas - 이미지 적용하기

  • 이미지를 처음 유니티로 가져오면 Texture Type디폴트값으로 잡혀있다
    -> 디폴트 값은 기본 텍스쳐 타입으로, 일반적으로 이미지가 3D 모델에 적용될 텍스쳐일 경우, 이 값으로 사용된다
  • 그냥 이미지에 적용하려고 하면 안들어가진다
    -> 타입을 Sprite (2D and UI)로 설정해주기

여러 Texture Type

  • Default
    3D 모델의 표면에 맵핑되는 일반적인 텍스처에 사용
    -> 실제 3D 모델링의 텍스쳐들의 타입은 모두 디폴트 타입
  • Sprite (2D and UI)
  1. 2D 게임에서 스프라이트로 사용될 텍스쳐를 설정할 때 사용
  2. UI 요소나 2D 캐릭터, 배경 등의 이미지를 처리할 때 적합
  • Cursor
    게임 내 커스텀 마우스 커서로 사용하기 위한 텍스쳐 타입이다

  • Cookie
    씬의 광원 쿠키에 사용되는 기본 파라미터 텍스쳐이다
    -> 쿠키란 실제 배치된 오브젝트가 아닌 사물의 그림자 연출을 위해 사용되는 텍스쳐

  • Lightmap
    움직이지 않는 정적인 물체에 조명효과를 설정한 텍스쳐이다



Anchor Presets 사용 이유

  • 일반적으로 Rect Transform 으로 UI위치를 잡게되면, 해상도가 변하면 그에 따른 UI의 위치도 서로 변한다
    -> 해상도에 따라 UI의 위치가 달라짐. 이러면 안된다
    -> 해상도에 따라 UI의 위치가 변동되지 않게 고정

  • shift : 기준점의 위치도 변동
  • alt : UI의 위치 이동
  • stretch : 너비 늘리기


Anchor Presets 사용

  • shift + alt 로 pivot값과 위치가 둘 다 바뀐다

버튼 컴포넌트

  • 버튼 컴포넌트 - 자식으로 Text 컴포넌트를 가지고 있다 -> 버튼의 이름
  • Text 컴포넌트 안에 내장된 것들은 컴포넌트의 프로퍼티
    -> 프로퍼티는 스크립트 내에서 접근하여 값 변경이 가능함


버튼을 일정한 간격으로 배치하고 싶다면?

Layout Group 컴포넌트 사용

Vertical Layout Group -> 수직 정렬
Horizontal Layout Group -> 수평 정렬

UI - Panel

  1. 패널 생성
    -> 이 패널은 위의 Layout Group 컴포넌트를 사용하기 위해 생성한 것
    -> 내부의 이미지 컴포넌트는 지워도 된다
  • Panel 이란?
    -> Canvas 컴포넌트 안에서 사용되는 UI 요소로, UI 요소를 구성하는 컨테이너 역할
    -> 패널에 레이아웃 그룹 추가 시 자동으로 내부 UI들을 정렬하고 관리할 수 있다

Panel은 UI들을 묶는 컨테이너 역할
-> 예를 들어, 팝업창을 구현할때 팝업창에 사용되는 이미지, 버튼, 텍스트 등을 하나로 패널로 하나로 묶어서 사용


  1. Layout Group컴포넌트 추가

  1. Child Alignment 자식 정렬 방법
    레이아웃 그룹 컴포넌트가 부착된 게임오브젝트를 내부에서 어느 위치를 중심으로 콘텐츠들을 정렬할 것인가를 의미한다

  1. Spacing -> UI 요소 간의 간격

  1. 간격 조절을 위한 컴포넌트 Content Size Fitter (수직 / 수평)

Content Size Fitter

  • 부모 UI 요소의 크기를 자식 UI 요소의 크기에 맞게 자동으로 조정해주는 컴포넌트
    -> 자식 요소들이 동적으로 크기를 조정할때, 부모 요소의 크기가 자동으로 자식에게 맞춰서 변경된다


Vertical Layout Group 컴포넌트가 들어있는 오브젝트의 자식으로 UI를 넣어주면 알아서 정렬된다

결과 :


Layout Group의 자식은 좌표 수정 불가

버티컬 레이아웃 그룹은 자식 UI 요소들을 자동으로 정렬시킨다. 따라서 자식 UI들에서는 직접적인 위치 조정 불가능


컴포넌트 복사 기능

  • Copy Component -> Paste Component Values

  • 복사하고 싶은 컴포넌트를 Copy Component

  • 붙여넣고 싶은 컴포넌트에다 Paste Component Values



버튼 관리

  • 버튼 매니저 스크립트 하나로 관리하는 게 좋다
    -> 현재는 Text 컴포넌트만 관리해보자
    -> 데이터를 매니저에서 관리하고 유니티 내에서의 text는 그냥 출력용으로만 보이게 하는 것
  1. ButtonManager 스크립트 생성

  2. 빈 게임 오브젝트 생성 후, 버튼 매니저 스크립트 넣어주기
    -> 버튼 관리용 오브젝트임



✅ 스크립트 내의 값을 변경해도 실제로 적용되지 않는 이유

  • C#에서 배열은 참조타입

  • private, protected로 선언한 변수들은 유니티 인스펙터 상에서 노출되지 않는다

ex) public 으로 선언한 data 변수
-> 인스펙터 창에서도 값이 나타나고, Debug.Log로도 확인하였다
-> 인스펙터 내에서 값을 변경할 수 있다는 의미

  • 스크립트 내에서 값을 변경해보았다
    10 -> 50
    근데 실제로 실행하면 인스펙터 창에 적용되어있는 10이 출력된다
    -> 인스펙터 창의 값을 조정해야 한다

왜 스크립트에 내용이 적용이 되지 않을까?

  • C# 컴파일 과정 -> C++보다 과정이 느림
  1. c# 스크립트를 작성한다 (코드)

  2. .Net (닷넷 프레임워크)에 의해 IL 언어를 생성하고 dll 파일이 생성 (dynamic library Link)

  3. 운영체제(윈도우,맥, 리눅스)에 맞춰서 기계어 코드로 변환
    -> iOS는 JIT 컴파일 시 문자가 되기 떄문에, JIT 컴파일이 금지된다 (AOT만 가능)

  • AOT (Ahead - of - Time) : C# 코드를 IL 언어로 변환

  • JIT (Just - in - Time) : IL언어를 네이티브 머신 코드(기계어)로 변환

dll이 생성되면 이 데이터 값이 여기에 온거기 때문에 C# 스크립트 단계에서 값을 변경해도 의미없음 (스크립트에서 값 변경해도 변경안되는 이유임)

유니티 직렬화

정확하게 말하자면, 유니티 직렬화 시스템이 기존 인스펙터의 값을 유지하기 때문에, 코드의 변경한 값이 적용되지 않는 걸로 보이는 것

ex)
1. data변수의 값을 10으로 지정한 스크립트를 저장 -> 컴파일 되고 dll 파일 생성 (data = 10이 포함됨)
2. 유니티 에디터 인스펙터에 data값이 10으로 자동 설정됨
3. 스크립트 내에서 값을 변경하여 컴파일 하면 새로운 dll 파일이 생성
-> 하지만 기존의 인스펙터 값을 유지하기 때문에 data = 10이 남아있다



버튼 스크립트

  • 스크립트 내에서 Text 컴포넌트를 가져오기 위해서는 UnityEngine.UI 네임스페이스를 지정해주어야한다

  • 버튼 컴포넌트를 배열로 설정
    public Text[] texts;
    C# 배열 : 자료형타입 [] 배열의 이름
    -> 배열은 참조형이기 때문에 하나의 포인터인 느낌

  • 포인터 변수가 스택에 생성, 관리힙에 생성된 변수는 외부에서 크기를 지정한다 (인스펙터 창)
    -> 스크립트 내에서 new 사용하여 동적으로 크기를 할당할 수 있긴 하다



인스펙터창 잠금 버튼

  • 다른 게임 오브젝트들을 더블클릭해도 인스펙터가 변경되지 않는다

  • 게임 오브젝트들을 인스펙터창의 컴포넌트에 할당해야할 때, 드래그를 편하게 하기 위해 사용할듯


text 게임 오브젝트 이름

Text 타입의 배열내의 요소에 name으로 접근하면 Text컴포넌트의 이름에 접근

text 게임 오브젝트 내의 컴포넌트에 적용된 text 프로퍼티

Text 컴포넌트내에 들어있는 프로퍼티에 스크립트로 접근하기

text. ~~~ 로 작성하게 되면 text 게임 오브젝트에 들어있는 컴포넌트의 프로퍼티에 접근할 수 있다



버튼 컴포넌트 활용

버튼에 들어갈 문자열을 string배열로 만들고, 인스펙터창에서 수정이 가능하게 해보자

public으로 선언했기 때문에 Text 타입과 string 타입 모두 인스펙터창에서 값 변경과 크기 수정이 가능하다

인스펙터창에서 정의한 문자열이 그대로 Text컴포넌트의 프로퍼티인 text에 적용된다


결과:

profile
뉴비 개발자

0개의 댓글