Unity_11 게임 UI, 기본 지원 UI, MVC, MVP

SeonggyuMin·2025년 5월 12일

Unity

목록 보기
10/11

1. 게임 UI

1. UI 구성요소

UI는 반드시 Canvas라는 오브젝트에 포함되어 있어야 하며 이는 평면의 도화지와 같은 개념이다. Canvas와 모든 UI는 3차원 오브젝트와는 다르게 RectTransform을 가지고 있다. 또한 RectTransform은 해상도 변경시에도 부모 오브젝트의 위치에 고정하고 위치를 정렬하기 위한 앵커와 회전의 기준점이 되는 피벗을 가지고 있다.

2. Anchor, Pivot

  • 앵커RectTransform이 부모의 어느 위치에 묶일지를 결정하는 기준점이다. 이를 활용하여 UI요소가 화면 크기가 변해도 같은 위치에 있을 수 있도록 할 수 있다.
  • 피벗은 UI 요소 자체의 중심점이다.

팁으로는 Scale With Screen Size, Full HD(1920 X 1080)로 프로젝트를 시작하고 그 다음에 바뀌면 바꾸는 것이 안전하다. 현 상황에서 Pixel size로 바꾸는 것은 쉬운데, 그 반대는 힘들 수 있기 때문이다.

2. 기본 지원 UI

Image / Raw Image

  • UI의 아이콘, 배경, 체력바 등 시각적 요소에 사용되는 UI이다.
  • Image와 달리 Raw Image는 Sprite를 사용할 수 없지만 추가 처리 없이 원시 텍스쳐를 보여줄 수 있기 때문에 처리 속도가 빠른 것이 특징이다.

Button

  • 마우스 클릭 / 화면 터치를 위한 UI 구성요소이며 내부적으로 클릭 시 동작을 정의할 수 있도록 OnClick 이벤트를 내장하고 있고 이벤트 트리거를 사용해 다양한 구현이 가능하다.

Slider

  • 주로 옵션 창에서 볼륨 설정 등에 사용한다.

Scroll View

  • 한정된 영역에 많은 데이터를 넣을 때 사용한다.

TextMeshPro

  • 고해상도 텍스트를 그리는 UI 텍스트 컴포넌트이다. 기존의 Text보다 선명한 것이 장점이다.
  • 한글을 지원하지 않기 때문에 폰트 에셋을 생성하여 사용해야 한다.
Text Asset 생성

- Source Font File : 폰트 원본 파일 삽입
- Sampling Point Size : 텍스쳐화 될 폰트 이미지에 삽입될 글자의 크기, 일반적으로 Auto Sizing을 선택한다.
- Padding : 글자 이미지 간의 여백, 보통 5를 선택한다.
- Packing Method : 폰트들을 한 장의 이미지로 합쳐 아틀라스를 생성한다. 두 옵션의 차이가 크지 않으므로 'Fast'를 선택한다
- Atlas Resolution : 글자로 구성된 한 장의 이미지의 최대 크기, 너무 작다면 폰트가 제대로 출력되지 않을 수 있고 너무 크다면 성능적으로 좋지 않다. 한글이라면 일반적으로 2048 ~ 4096을 추천한다.
- Character Set : 폰트에셋으로 지정해 둘 폰트를 지정하는 단계. 한글폰트가 포함되어야 하므로 Custom Range로 설정한다.
- Character Sequence : 유니코드 단위의 10진수로 범위를 지정한다. `32-126,44032-55203,12593-12643,8200-9900`를 입력하며. 이는 각각 `영문자`, `한글`, `한글 자모음`, `특수문자`의 범위이다.
- RenderMode : 텍스트를 이미지화 할 때 사용되는 렌더링 모드. 거리에 따라 선명도를 계산해 렌더링 하는 방식인 SDF를 사용하고, 그 중에서도 SDF16 을 선택하지만 이 수치는 디바이스 환경이나 해상도 등에 차이가 있을 수 있으며 숫자가 높을수록 더 많은 연산이 발생하므로 많은 테스트를 통해 결정되어야 한다.

3. MVC, MVP

1. MVC

MVC란 (Model - View - Controller)를 사용하는 디자인 패턴이다.

여기서 Model은 데이터를 저장, View는 인터페이스, Controller는 로직을 처리한다.


사진출처

그러나 유니티에서는 시각적 요소(View)에 대해 컴포넌트로 이미 존재한다는 점, MVCView처럼 클래스로 만들지 않고 MonoBehaviour가 자연스럽게 View역할을 수행한다는 점, UI에 이미 자체 이벤트가 있어 별도의 View - Controller 연결 로직 없이도 자연스럽게 이벤트 처리가 가능하다는 점에서 MVC보단 MVP가 선호된다.

2. MVP

MVP란 (Model - View - Presenter)를 사용하는 디자인 패턴으로써, View는 인터페이스로만 정의하고, PresenterView를 직접 조작하는 구조이다.


사진출처

예시 코드

Model

public class PlayerModel : MonoBehaviour
{
    [SerializeField] private int hp;
    public int HP { get { return hp; } set { hp = value; OnHPChanged?.Invoke(hp); } }
    public event Action<int> OnHPChanged;


    [SerializeField] private int jumpCount;
    public int JumpCount { get { return jumpCount; } set { jumpCount = value; OnJumpCountChanged?.Invoke(jumpCount); } }
    public event Action<int> OnJumpCountChanged;
}

Controller

public class PlayerController : MonoBehaviour
{
    [SerializeField] private PlayerModel playerModel;
    private Rigidbody rb;

    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(Vector3.up * 10f, ForceMode.Impulse);
            playerModel.JumpCount++;
        }

        if (Input.GetKeyDown(KeyCode.A))
        {
            playerModel.HP++;
        }

        if (Input.GetKeyDown(KeyCode.D))
        {
            playerModel.HP--;
        }
    }
}

Presenter

public class PlayerPresenter : MonoBehaviour
{
    [Header("Model")]
    [SerializeField] private PlayerModel playerModel;

    [Header("View")]
    [SerializeField] TMP_Text playerJumpCountText;
    [SerializeField] Slider playerHpSlider;

    private void OnEnable()
    {
        playerModel.OnHPChanged += SetHp;
        playerModel.OnJumpCountChanged += SetJumpCount;
    }

    private void OnDisable()
    {
        playerModel.OnHPChanged -= SetHp;
        playerModel.OnJumpCountChanged -= SetJumpCount;
    }

    public void SetHp(int hp)
    {
        playerHpSlider.value = hp;
    }

    public void SetJumpCount(int jumpCount)
    {
        playerJumpCountText.text = $"jumpcount: {jumpCount}";
    }
}

0개의 댓글