Mini Project - 9

규수·2026년 4월 27일

개발 공부 일지

목록 보기
33/44

오늘은 이전까지 구현한 코드를 기반으로 실제 게임에 보여질 UI를 구성하는 시간을 가져보겠습니다.

카드들에서 공통적으로 진행되는 Sprite설정 및 카드 선택에 따른 위치 변경에 대하여 주로 구현하였으며, 일부 애니메이션 연출에 대해서는 코드 기반의 애니메이션 연출을 할 수 있는 DOTween을 이용하였습니다.

씬 구현

먼저 씬과 씬별 역할은 다음과 같이 구현하였습니다.

1. Title - 게임 실행시 첫 등장 씬, Play를 통해 InGame으로 연결한다.
2. InGame - 핵심 게임 시스템이 동작되는 씬, 라운드 클리어 유무에 따른 결과 씬으로 연결된다.
3. Clear - 게임 승리시 연결되는 씬, 플레이 기록을 기반으로 코인을 획득하며 Shop으로 연결된다.
4. GameOver - 게임 패배시 연결되는 씬, 플레이한 기록에 대하여 확인할 수 있고 재시작 및 Title로 연결된다.
5. Shop - 상점씬, 다양한 카드를 구매 행위가 이루어지며, 완료 후, 다음 라운드로 연결된다.

각각의 씬에는 원작인 Balatro의 에셋을 참고하여 다음과 같이 구성하였습니다.

  • 싱글톤으로 구현되는 사운드와 Scene전환관리는 Title에 배치하였습니다.
  • InGame의 경우 카드가 실제 드로우 되도록 처리하지만, Clear, Shop에서는 카드가 드로우 되지 않은 상태로 유지되어야 하여 해당 UI 및 스크립트 연결은 제거하는 방식으로 진행하였습니다.

프리팹 구성

프리팹으로는 카드와 슬롯을 프리팹으로 구성하였습니다.

  • 카드의 경우 하나의 UI를 만들어 여러 카드가 생성된다는 점에서 프리팹 구성이 유리하다고 판단되었습니다.

  • 슬롯의 경우에는 현재는 싱글톤으로 유지되다보니 씬 전환에도 유지되는 것을 고려하면 프리팹으로 구성하였습니다.
    다만, 싱글톤 해제를 진행하더라도 현재의 UI를 변경할 필요성이 보이지는 않습니다. 이미 구성된 흐름에서 큰 틀의 UI만 수정하고 프리팹은 활용하는 방식으로 진행하여 비용을 줄이는 방식을 채택할 예정입니다.

기본 구조

카드 프리팹의 경우 다음과 같은 구조로 Hierarchy를 구성하였습니다.

Card
  ㄴ Visual
  	ㄴ BackGround
  	ㄴ Button
    ㄴ CardImage
  • 카드의 경우 사용하는 Asset의 배경이 존재하지 않다보니 일관적으로 BackGround(Image)를 추가하였습니다.
  • 카드를 클릭하였을 때, 클릭함수 관련 호출을 진행하는 과정에서 손쉽게 구현하기 위해 Button을 추가하였습니다.
  • 추가된 버튼의 OnClick()을 통해 스크립트와 연결하여 OnClickCard()함수를 호출하도록 처리하였습니다.
public void OnClickCard()
{
    ShopManager shopManager = UnityEngine.Object.FindFirstObjectByType<ShopManager>();
    if (shopManager != null)
    {
        shopManager.SelectVoucherProduct(this);
    }

}

public void VisualSelect(bool isSelected)
{
    visualRoot.anchoredPosition += isSelected ? new Vector2(0, 30) : new Vector2(0, -30);
    
}
  • 카드를 선택하면 선택되지 않은 카드와의 차이를 두기 위해, VisualSelect함수를 통해 카드의 y축 포지션을 수정하는 방식으로 처리하였습니다.
  • 그 외, 바우처, 조커, 헹성 카드의 경우 상점에서 카드 선택시 구매버튼이 활성화되도록 처리하고 마우스가 호버된 상태일 때 카드에 대한 설명이 출력되도록 프리팹을 구성하였습니다.

 public void OnPointerEnter(PointerEventData eventData)
 {
     if (descriptionPanel != null)
     {
         descriptionText.text = description;
         descriptionPanel.SetActive(true);
     }
 }

 public void OnPointerExit(PointerEventData eventData)
 {
     if (descriptionPanel != null)
     {
         descriptionPanel.SetActive(false);
     }
 }


UI 구현의 경우 코드 구현과는 다르게 배치 자체에 많은 어려움을 겪고 배웠습니다.
Hierarchy의 배치 순서에 따른 노출 우선도, UI 배치에 따른 부가적인 코드 구현 등 처음 시작 할때는 AI의 도움을 받아 생성할 정도로 어려움을 겪었지만,
처음 구성에 대한 보조를 통해 감을 잡다보니 이후 프리팹 구성이나 씬 배치시 처음 작업 속도보다 더 빠르게 구현할 수 있게 되었습니다.

0개의 댓글