어느 게임에서나 흔히 볼 수 있는 Drag & Drop.
이 기능의 원리를 알아보고 Unity 상에서의 구현 과정을 알아보겠다.
이후엔 디자인패턴 중 하나인 MVC에 대해 예시와 함께 알아보고
MVC 패턴과 흡사한 MVP 패턴도 같이 알아보겠다.

시작 // ing // 종료
드래그는 이 3Step으로 구성된다.
각 Step마다 필요한 기능이 무엇이 있는 지를 스크립트를 작성하며 알아보겠다.
드래그가 가능하게 할 이미지에 부착할 스크립트.
해당 스크립트를 통해 Drag & Drop 중 Drag 기능을 구현
순서대로 진행해보자.
UI, EventSystem 추가.
인터페이스 3가지를 지정하여 3Step을 구현하도록 제작
IBeginDragHandler, IDragHandler, IEndDragHandler
원하는 위치로의 드래그 실패 시, 돌아갈 정보를 저장하기 위해 부모패널의 트랜스폼값 저장
이미지의 투명화, blocksRaycasts 설정을 위해 CanvasGroup을 AddComponent
드래깅 시작 시, 필요한 기능을 모아둔 메서드
인자값은 PointerEventData
이 내부에 드래깅에 필요한 모든 정보가 들어 있음.
드래깅 도중, 필요한 기능을 모아둔 메서드
마찬가지로 인자값 PointerEventData
(마우스)포인터의 위치로 포지션값을 변경
드래깅 마무리 시, 필요한 기능을 모아둔 메서드
드래그 할 이미지에 부착할 스크립트 작성은 이걸로 마무리.
드랍이 가능한 패널에 부착할 스크립트.
해당 스크립트를 통해 Drag & Drop 중 Drop 기능을 구현

여기도 IDropHandler 라는 인터페이스를 부착.
드래그 중이던 대상의 부모를 해당 패널로 변경하는 메서드 제작.
패널A의 자식객체인 이미지를
패널B로 옮겨보겠다

우측 상단의 하이어라키를 보면 패널 A에서 상위 객체인 Canvas로 이동되는 모습
투명도 등의 설정도 전부 적용되었다.
이후 image 필드를 통해
드래그 도중엔 크기를 작게 만드는 등의 기능을 넣어보는 것도 좋을 듯.
기본적인 Drag & Drop은 구현했으니
이제 서론 아래의 움짤인 드래그하여 객체 생성 구현으로 넘어가보겠다.

마우스의 위치값을 받아와
해당 위치의 충돌 정보를 받아와 Instantiate
이 함수는 OnEndDrag 메서드에 추가하고
메서드 실행 이후엔 기존 이미지 오브젝트는 파괴하도록 구현하여 완료
설계를 3가지 핵심 구성요소로 나누는 디자인 패턴.

MVC 패턴을 활용하여 Player의 Hp가 줄어들고 늘어나는 기능을 제작해보겠다.
핵심 3요소 중, 데이터와 로직을 담당할 Model 스크립트를 만들어보겠다.

private int health = 100;
public int Health => health;

다음은 MVC 중 V, View 스크립트를 작성하겠다.
정보의 출력을 담당할 View 스크립트.

마지막으로 C, Controller 스크립트를 작성하겠다.
입력을 감지하여 데이터(Model)를 변경하고
화면 표시(View)와 데이터(Model)를 서로 연결하는 역할.
이건 코드 내용이 좀 길고, 내가 추후에 까먹더라도 다시 기억하기 위해
하나하나 풀어서 적어두겠다.
[SerializeField] private PlayerView _playerView;
private PlayerModel _playerModel;
private InputAction _damageAction;
private InputAction _healingAction;

여기가 가장 중요

_playerModel.OnHealthChanged += _playerView.UpdateHealthUI;
_playerModel 에서 체력이 변경될 때마다 발생하는 이벤트에
_playerView 의 체력 업데이트 메서드를 구독시켜줌
이로써 Controller는 데이터(Model)와 UI(View)의 연결을 관리하는 역할만 하고
서로를 직접 호출하지 않는 느슨한 결합 상태가 됨.

스크립트가 활성화될 때 입력 액션을 활성화하고
입력이 발생했을 때 호출될 메서드를 등록.
입력이 수행(performed) 되었을 때, 각 메서드를 호출하도록 연결

구독 해제~

해당 메서드를 수행하여 모델의 메서드를 실행하여 데이터를 변화시킴.
스크립트 작성이 완료되었으니
체력 변화를 테스트해보겠다.

체력 회복, 감소 정상 작동
PlayerController 는 중개자 역할을 수행하여 사용자의 입력을 받아
PlayerModel 의 데이터를 수정, PlayerView와 연결된 이벤트를 통해
PlayerView 를 업데이트
MVC랑 비슷하지만 다른 디자인 패턴
View와 Model은 서로를 알 필요가 없으며, Presenter를 통해서만 간접적으로 소통하게 됨.
코드의 결합도를 낮추고 유지보수성 및 테스트 용이성을 극대화
View는 데이터(Model)를 알 필요 없이 Presenter의 명령만 따르면 되고
Presenter는 실제 View 대신 Mock View를 사용하여 테스트 가능
MVC: View는 Model을 직접 구독하여 데이터를 가져옴.
MVP: View는 Presenter의 인터페이스를 참조.
Presenter가 Model의 변경 이벤트를 구독
이 이벤트가 발생하면 View의 메서드를 직접 호출하여 View를 업데이트
간단하지만 방식을 모르면 만들 수 없거나 어려운 게 내 생각보다 많다.
여러 예시 코드를 보는 습관을 들이자.
또한 MVC를 사용할 때의 간단한 구현 등의 메리트보단
개인적으론 Model 의존성을 해결하고 테스트에 용이한 MVP 쪽을 더 사용하게 될 것 같다.
TIL의 요약 파트가 그냥 목차 같습니다. 큰 주제로 묶어서 간단한 설명을 추가해 주세요.