오늘은 프로젝트 A에서 사용할 팝업 UI 컨트롤러를 만들어볼 생각이다.
팝업이 단순히 하나씩만 표시되게 한다면 컨트롤러가 굳이 필요하지 않을거라 생각했는데
게임의 방향성을 보았을 때 여러 팝업을 열기로 결정이 되어 제작하기로 했다.
우선 기본적으로 새로운 팝업이 열렸을 때 이전 팝업의 상호작용은 불가능해야하며,팝업을 닫을 땐 먼저 열린 팝업이 제일 마지막에 닫혀야한다.
이러한 점을 고려했을 때 후입선출의 특징을 가지고 있다는 것을 알 수 있다.
그렇기 때문에 후입선출의 자료구조인 Stack을 활용하여 컨트롤러를 제작해보았다.
우선 한 컨트롤러로 모든 PopUp들을 컨트롤하기 위해선 캡슐화가 필요했다.
public interface IPopUp
{
public void Active();
public void UnActive();
public void ActiveRayTarget();
public void UnActiveRayTarget();
}
Active와 UnActive를 통해 팝업 오브젝트의 Active 상태를 컨트롤 하고 ActiveRayTarget과 UnActiveRayTarget을 통해 팝업 오브젝트의 상호작용을 컨트롤 해주기 위해 이렇게 4가지의 메서드를 캡슐화 해보았다.
그리고 정의된 인터페이스를 통해 팝업 컨트롤이 필요한 클래스에 적절히 인터페이스를 구현해주었다.
public class ExplainCanclePopUp : MonoBehaviour, IPopUp
{
// something...
public void Active()
{
StartCoroutine(FadeIn());
}
public void UnActive()
{
StartCoroutine(FadeOut());
}
public void ActiveRayTarget()
{
img.raycastTarget = true;
}
public void UnActiveRayTarget()
{
img.raycastTarget = false;
}
private IEnumerator FadeIn()
{
// Something...
}
private IEnumerator FadeOut()
{
// Something...
}
}
나는 취소 상호작용을 설명해주는 PopUp UI에 인터페이스를 구현해주었다.
팝업이 열릴 땐 Fade In이 되고, 팝업이 닫힐 땐 Fade Out이 되도록 구현해주었고
raycastTarget의 값을 변경하여 상호작용 컨트롤을 구현해주었다.
다음은 위와 같이 구현된 여러 개의 팝업 UI를 컨트롤 해줄 PopUpController를 구현해볼려고 한다.
public class PopUpController : MonoBehaviour
{
private Stack<IPopUp> popUpStack = new Stack<IPopUp>();
public void PushPopUp(IPopUp popUp) { }
public void PopPopUp() { }
}
앞서 설명했듯이 후입선출의 특징으로 팝업 리스트를 관리해주기 위해 Stack 자료구조로 정의해주었다.
또한 팝업을 삽입, 삭제를 할 수 있는 간단한 메서드도 정의해주었다.
삽입에 대한 구현은 다음과 같다.
public void PushPopUp(IPopUp popUp)
{
if (popUpStack.Count > 0)
{
var _top = popUpStack.Top();
if (_top.Equals(popUp)) return;
_top.UnActiveRayTarget();
}
popUpStack.Push(popUp);
popUp.Active();
popUp.ActiveRayTarget();
}
public static class ExtensionMethods
{
public static T Top<T>(this Stack<T> values)
{
var _top = values.Pop();
values.Push(_top);
return _top;
}
}
Stack에 팝업을 Push하기전 열려있는 팝업이 존재하는지 체크를 해주고 있다면 해당 팝업의 상호작용을 하지 못하도록 제어해준다.
이후 새로 열린 팝업을 리스트에 Push 해주고 해당 팝업을 Active하고 상호작용이 가능하도록 해준다.
+ C# Stack 자료구조는 Pop 메서드를 통해 마지막에 대입된 값을 반환 받을 수 있기 때문에
데이터의 삭제를 원치 않을 경우엔 번거롭게 다시 추가해주는 작업을 거쳐야 된다.
그렇기 때문에 나는 기존 Stack 클래스의 확장 메서드로 Top을 정의해주었다.
삭제에 대한 구현은 다음과 같다.
public void PopPopUp()
{
if (popUpStack.Count.Equals(0))
{
PushPopUp(optionPopUp);
return;
}
var _pop = popUpStack.Pop();
_pop.UnActiveRayTarget();
_pop.UnActive();
popUpStack.Top().ActiveRayTarget();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Escape)) PopPopUp();
}
삭제 구현도 삽입과 마찬가지로 간단하다.
삭제에선 닫히는 팝업을 제어해주고 닫힌 팝업 이전에 있는 팝업을 활성화 시켜주면 된다.
이 프로젝트에선 팝업 닫기 버튼 이외에도 ESC키를 이용하여 팝업을 닫을 수 있도록 하였기 때문에
Update문에서 Input을 체크해주었고,
아무런 팝업이 열려있지 않을 때 ESC 키를 상호작용하면 옵션 팝업이 열리도록 구현해주었다.
이렇게 하나의 팝업 컨트롤러를 통해 관리하니 비교적 코드도 많이 쓰지 않고 구현한 것 같다.
더 좋은 방식이 있다면 댓글로 추천해주시면 감사하겠습니다!
'Unity' 카테고리의 다른 글
유니티 프로젝트 개발 일지 - 4 (유니티 Line 그리기) (0) | 2024.12.21 |
---|---|
유니티 프로젝트 개발 일지 - 3 (렌더링) (0) | 2024.12.20 |
유니티 프로젝트 개발 일지 - 1 (상태 패턴) (1) | 2024.12.18 |
유니티 프로젝트 개발 일지 - 0 (0) | 2024.12.17 |
[Unity] Asset Management(에셋 관리) - Resources, AssetBundle, Addressable (4) | 2024.09.23 |