로비 UI의 디자인을 변경하고, UI 활성화시 연출이 발생하도록 수정해주었습니다.
먼저 UI의 책을 넘기는 효과는 무료 에셋을 사용하여 구현해주었습니다.
https://assetstore.unity.com/packages/tools/animation/book-page-curl-55588
해당 에셋의 Book.cs 에 추가적으로 FlipEvent 메서드를 만든 뒤, 해당 메서드를 Book 스크립트의 OnFlip 이벤트에 등록하여 책이 넘어가는 효과가 발생할때마다 메서드가 호출되도록 만들어주었습니다.
public void FlipEvent()
{
switch (currentPage)
{
case 0:
lobbyUi.loginUI.SetActive(true);
break;
case 2:
lobbyUi.searchLobbyUI.SetActive(true);
break;
case 4:
lobbyUi.lobbyUI.SetActive(true);
break;
}
}
메뉴에 직접적으로 표기되는 이미지는 넘어가는 효과에 자연스럽게 보일 수 있도록 이미지로 만들어주었습니다
※ 만약 해외출시등을 계획한다면, 리소스 폴더를 통해 리스트에 넣어주거나, TMP를 사용하여 OnFlip시에 변경되도록 만들어주는것이 좋아보일듯 합니다.
버튼을 눌러 특정 UI에서 이동할 때, 이벤트를 발생시켜 책을 넘기는 효과를 발생시키는 방식으로 만들어주었습니다.
//로비 UI의 책 넘기는 효과를 발생시키기 위한 이벤트
public event Action OnFlipRightEvent;
public event Action OnFlipLeftEvent;
public event Action<int> OnFlipToTargetEvent;
public void GameStartButtonControll(bool isActive)
{
if (LobbyManager.Instance.IsLobbyhost() == false) return;
StartButton.interactable = isActive;
}
public void CreateRoomButton()
{
LobbyManager.Instance.CreateLobby(roomCodeInput.text);
searchLobbyUI.SetActive(false);
OnFlipRightEvent?.Invoke();
}
public void JoinRoomButton()
{
LobbyManager.Instance.JoinLobbyByCode(roomCodeInput.text);
searchLobbyUI.SetActive(false);
OnFlipRightEvent?.Invoke();
}
public void LeaveLobbyButton()
{
LobbyManager.Instance.LeaveLobby();
OnFlipLeftEvent?.Invoke();
}
// Book.cs 에 추가적으로 사용하는 AutoFlip.cs
private void Awake()
{
if (!ControledBook)
ControledBook = GetComponent<Book>();
ControledBook.lobbyUi.OnFlipToTargetEvent += StartTargetFlipCoroutine;
}
// Use this for initialization
void Start () {
if (AutoStartFlip)
StartFlipping();
ControledBook.OnFlip.AddListener(new UnityEngine.Events.UnityAction(PageFlipped));
NetworkAuthenticate.Instance.OnAuthenticateSuccessEvent += FlipRightPage;
ControledBook.lobbyUi.OnFlipRightEvent += FlipRightPage;
ControledBook.lobbyUi.OnFlipLeftEvent += FlipLeftPage;
}
UI를 활성화 할 때, 연출을 주기 위해 UIPopup 스크립트에서 전략을 정하고, 전략에 따라 활성화, 비활성화시 연출이 발생하도록 수정해주었습니다.
UI 기반은 팀원분이 작업하셨으며, 해당 기반에 제가 추가작업을 하였기때문에 UI기반에 대한 내용은 없습니다.
public class UIPopup : UIBase
{
//팝업 UI 상속 클래스 (예: 인벤토리창 설정창)
public UIMovementType movement;
//UI 활성화, 비활성화시 전략
private IPopupStrategy strategy;
//전략패턴 지정
private void Awake()
{
strategy = UIPopupFactory.SetPopupStrategy(gameObject, movement);
}
public override void Show()
{
base.Show();
strategy.ShowUI();
}
public override void Hide()
{
base.Hide();
strategy.HideUI();
}
}
일단 페이드인, 아래에서 위로 슬라이드, 효과 없음 세가지의 전략패턴을 만들어주었습니다.
페이드인과 슬라이드 효과는 DOTween 을 사용하여 제작하였으며, 페이드인 연출의 경우 CanvasGroup 컴포넌트를 사용해야하기 때문에 해당 컴포넌트가 없으면 컴포넌트를 추가하도록 만들어주었습니다.
public enum UIMovementType
{
None,
Fade,
SlideBottom
}
public interface IPopupStrategy
{
public void ShowUI();
public void HideUI();
}
//전략패턴 기반
public class UIStrategyBase
{
protected GameObject ui;
protected RectTransform transform;
public UIStrategyBase(GameObject thisUi)
{
ui = thisUi;
transform = ui.GetComponent<RectTransform>();
}
}
//전략 : 아래에서 위로 슬라이드 하며 생성
public class UISlideBottomStrategy : UIStrategyBase, IPopupStrategy
{
public UISlideBottomStrategy(GameObject ui) : base(ui)
{
}
private Vector3 hideVector = new Vector3(960, -1080, 0);
public void HideUI()
{
transform.position = Vector3.zero;
CoroutineManager.Instance.StartMyCoroutine(ActiveUI(false));
}
public void ShowUI()
{
transform.position = hideVector;
CoroutineManager.Instance.StartMyCoroutine(ActiveUI(true));
}
private IEnumerator ActiveUI(bool isActive)
{
if(isActive)
{
ui.SetActive(true);
Tween tween = transform.DOAnchorPosY(0, 1f);
yield return tween.WaitForCompletion();
}
else
{
Tween tween = transform.DOAnchorPosY(-1080, 1);
yield return tween.WaitForCompletion();
ui.SetActive(false);
}
}
}
//전략 : 페이드 인, 아웃
public class UIFadeStrategy : UIStrategyBase, IPopupStrategy
{
private CanvasGroup canvasGroup;
public UIFadeStrategy(GameObject ui) : base(ui)
{
if (!ui.TryGetComponent(out canvasGroup))
{
canvasGroup = ui.AddComponent<CanvasGroup>();
}
}
public void HideUI()
{
CoroutineManager.Instance.StartMyCoroutine(Fade(true));
}
public void ShowUI()
{
CoroutineManager.Instance.StartMyCoroutine(Fade(false));
}
IEnumerator Fade(bool isFadeIn)
{
if(isFadeIn)
{
canvasGroup.alpha = 1f;
Tween tween = canvasGroup.DOFade(0, 1);
yield return tween.WaitForCompletion();
ui.SetActive(false);
}
else
{
canvasGroup.alpha = 0f;
ui.SetActive(true);
Tween tween = canvasGroup.DOFade(1, 1);
yield return tween.WaitForCompletion();
}
}
}
//전략 : 아무런 효과가 없음
public class UINoneStrategy : UIStrategyBase, IPopupStrategy
{
public UINoneStrategy(GameObject ui) : base(ui)
{
}
public void HideUI()
{
ui.SetActive(false);
}
public void ShowUI()
{
ui.SetActive(true);
}
}
UI 생성시 전략은 팩토리 패턴을 통해 생성하며, UIPopup 스크립트의 Awake 문에서 Enum값을 기반으로 이 클래스를 통해 전략 객체를 만들어주는것을 볼 수 있습니다.
public static class UIPopupFactory
{
// UI에 전략패턴을 만들어주는 팩토리 메서드
public static IPopupStrategy SetPopupStrategy(GameObject ui, UIMovementType move)
{
IPopupStrategy strategy;
switch (move)
{
case UIMovementType.None:
strategy = new UINoneStrategy(ui);
break;
case UIMovementType.Fade:
strategy = new UIFadeStrategy(ui);
break;
case UIMovementType.SlideBottom:
strategy = new UISlideBottomStrategy(ui);
break;
default:
strategy = new UINoneStrategy(ui);
break;
}
return strategy;
}
}
이번 작업에서는 트러블 슈팅 내용이 따로 존재하지 않습니다.
또한, 추가적인 UI 연출이 필요할경우, 전략을 늘리는 방식으로 대응하게될 것 같습니다.
해야할 일 목록
- 게임 종료 버튼 구현
- 까먹고있었습니다... 추가가 오래걸리는것은 아니기때문에 바로 만들어줄 것 같습니다.
- 로비 뒷 배경 제작
- 책상 오브젝트와 책 형태의 오브젝트를 비추는 형태로 만들어주면 될것이라고 생각하고 있습니다.
- 추가 UI 제작
- 조작법, 옵션 UI를 제작해주어야합니다.
- 조작법은 이미지를 사용하게될 듯 하며, 옵션 UI의 경우 소리 설정등의 내용을 다루게될 것 같습니다.
- 조작 키 변경도 추가하고 싶지만, 해당 내용을 다뤄본적이 없어서 최종적으로 추가할 내용이 없을때 제작을 시도해볼 것 같습니다.
- 네트워크 예외 처리
- 로그인시, 아무것도 입력하지 않으면 오류가 발생하지만, 그대로 다음 페이지에 넘어가는 현상을 발견하였습니다.
- 이 외에도 네트워크 연결에 모두 예외처리를 해주는것이 좋다는 피드백을 받았기 때문에, 추가적인 예외처리를 진행해줄 예정입니다.
'내일배움캠프 > 프로젝트' 카테고리의 다른 글
팀 프로젝트 - 조작 관련 UI 추가, 로비 배경 추가 (0) | 2024.12.31 |
---|---|
팀 프로젝트 - 로비 개선 (0) | 2024.12.27 |
팀 프로젝트 - 게임 종료후 씬 이동 문제 해결 (0) | 2024.12.26 |
팀 프로젝트 - 게임 오버 메커니즘 (0) | 2024.12.24 |
팀 프로젝트 - 퍼즐 정보 관련 인터페이스화 (0) | 2024.12.23 |