[Unity] 간단한 MVVM 패턴 적용시키기

조팽이·2024년 9월 2일

Unity

목록 보기
10/13

MVVM은 UI를 작성할 때 많이 사용하는 기법 중 하나이다.
보통 MVC, MVP도 사용을 하지만 MVVM의 장점이 뛰어나 MVVM을 많이 사용하곤 한다.
MVP와 MVVM은 비슷하지만 다른데, MVP는 Presenter가 view마다 하나씩 존재해야하므로 view가 늘어날 수록 점점 더 많은 presenter가 필요한 반면, MVVM은 그렇지 않다.

MVVM을 적용한 간단한 코드를 살펴보겠다.

Model은 간단하므로 ViewModel에 작성하였다.

//viewModel

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using UnityEngine;

public class ViewModel : INotifyPropertyChanged
{
    private String _text = "";

    public String text
    {
        get => _text;
        set
        {
            if (Equals(value, _text)) return;
            _text = value;
            OnPropertyChanged("Text");
        }
    }

    private int _point = 0;

    public int point { get => _point;
        set
        {
            if (Equals(value, _point)) return;
            _point = value;
            OnPropertyChanged("Point");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if(PropertyChanged != null)
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

INotifyPropertyChanged를 사용하였다. 이때 OnPropertyChanged라는 method구현이 필수가 된다. text와 point의 값이 바뀔 때 우리는 OnPropertyChanged를 호출하게 된다.
다음은 view이다.
//view

using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
using UnityEngine.UI;

public class View : MonoBehaviour
{
    ViewModel viewModel;

    private Text text;
    // Start is called before the first frame update
    void Start()
    {
        viewModel = Managers.gm.viewModel;
        text = GetComponent<Text>();
        viewModel.PropertyChanged += OnPlayerViewModelPropertyChanged;
        viewModel.text = "hi";
    }

    private void OnPlayerViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Text")
        {
            viewModel.text = "re-Hi";
            text.text = viewModel.text;
        }
        else if (e.PropertyName == "Point")
        {
            //viewModel.text = "ScoreUp";
            text.text = viewModel.point.ToString();
        }
    }
    
    
}

/button

public class UI_Controller : MonoBehaviour, IBeginDragHandler, IDragHandler
{

    private Button button;

    private void Start()
    {
        button = GetComponent<Button>();
        button.onClick.AddListener(PointUp);
    }

    void PointUp()
    {
        Managers.gm.viewModel.point++;
    }
}

button을 누르게 되면 viewModel의 Binding되어 있던 point의 값이 바뀌게 되며 자동으로 UI에 갱신되는 것을 확인할 수 있다.

profile
게임개발자

0개의 댓글