CustomUtils Help

UI

프로젝트 바로 가기

소스 코드 바로 가기

MVVM 구조 기반 UI

  • 전통적인 UI의 구조의 경우 개발, 테스트 과정을 전환 하는데 많은 시간이 소요되며 이를 근본적으로 해결 하기 위해서 UI의 구조를 재설계 할 필요가 있음

  • MVVM(Model - View - ViewModel) 패턴 구현의 경우 Unity Test Framework 환경을 기반으로 빠르게 테스트하기 적합

  • ModelViewModel을 결합한 수정 모델을 제공 하고 Model에 대한 반응형 구조를 구축 하여 핵심 로직 개발에만 집중할 수 있도록 지원

  • 최종적으로 사용자는 추가 작업 없이 View, ViewModel, NotifyField 이 세가지 기능을 통해 MVVM 구조의 UI를 개발, 테스트 환경을 제공

«UnityNative»MonoBehaviourUIViewMonoBehaviouruint Priority { get; protected set; }void AttachModelChangedCallback()void ChangeViewModel(UIViewModel viewModel) void SetActive(bool isActive)UIViewTViewModel : UIViewModelTViewModel viewModelvoid OnNotifyModelChanged(string fieldName, NotifyFieldChangedEventArgs args)NewUIViewNewUIViewModelvoid OnNotifyModelChanged(string fieldName, NotifyFieldChangedEventArgs args)«Native»IDisposableUIViewModelSafeDelegate<NotifyModelChangeHandler> OnModelChangedNewUIViewModel0..1
public class SampleUIView : UIView<SampleUIViewModel> { private TextMeshProUGUI _titleText; private TextMeshProUGUI _countText; private Button _increaseCountButton; private Button _decreaseCountButton; private void Awake() { // Initialize UI } protected override void OnNotifyModelChanged(string fieldName, NotifyFieldChangedEventArgs args) { switch (args) { case NotifyCollectionChangedEventArgs listArgs: OnNotifyListChanged(fieldName, listArgs); break; default: OnNotifyPropertyChanged(fieldName); break; } } private void OnNotifyPropertyChanged(string name) { switch (name) { case nameof(viewModel.Title): UpdateTitle(); break; case nameof(viewModel.Count): UpdateCount(); break; } } private void OnNotifyListChanged(string name, NotifyCollectionChangedEventArgs args) { switch (name) { case nameof(viewModel.Collection): UpdateCollection(args); break; case nameof(viewModel.List): UpdateList(args); break; case nameof(viewModel.Dictionary): UpdateDictionary(args); break; } } private void UpdateTitle() => _titleText.text = viewModel.Title; private void UpdateCount() => _countText.text = viewModel.Count.ToString(); private void UpdateCollection(NotifyCollectionChangedEventArgs args) private void UpdateList(NotifyCollectionChangedEventArgs args) private void UpdateDictionary(NotifyCollectionChangedEventArgs args) private void OnClickIncreaseCountButton() => viewModel.IncreaseCount(1); private void OnClickDecreaseCountButton() => viewModel.DecreaseCount(1); }
public class SampleUIViewModel : UIViewModel { public readonly NotifyProperty<string> Title = new(); public readonly NotifyProperty<int> Count = new(); public readonly NotifyCollection<int> Collection = new(); public readonly NotifyList<long> List = new(); public readonly NotifyDictionary<int, long> Dictionary = new (); public void IncreaseCount(int count) => Count.Value += count; public void DecreaseCount(int count) => Count.Value -= count; }
UIView
  • View역할로 전체 Interface에 대한 처리를 담당

  • UIViewModel에 사용자의 Interaction을 전달

UIViewModel
  • ModelViewModel을 결합한 구조로UIView를 통해 받은 Interaction을 처리하는 로직으로 구성

  • NotifyField와 연동하여 추가 적인 작업 없이 반응형 UI 구조 제공하며 직접적으로 View에 접근할 수 없음

NotifyField
  • UIViewModel과 연동하여 동작 하도록 설계되었으며 각 Field의 값이 변경되면 ViewNotifyFieldChangedEventArgs를 발행하여 특정 Field가 변경돈 사실을 고지

  • UIViewModel내의 NotifyFieldUIViewModel이 생성될 때 자동 연동 되며 필요시 Event를 추가로 등록할 수 있음

Last modified: 01 2월 2025