2025.03.20 (목)

윤혜진·2025년 3월 20일

📍오늘의 학습 키워드

  • ATM 만들기 (1)

    • UI 배치
    • 데이터와 UI 연동
    • 버튼을 통한 입/출금 UI창 변경

📍학습 내용

  • UI 배치

    • 내가 구현한 방식:
      • 나름 앵커를 설정해서 잘 구현했다고 생각했지만, Free Aspect로 설정하고 화면을 위 아래로 늘리니 보이지 않는 UI가 생겼음.
      • 튜터님의 피드백을 통해 아래처럼 늘려도 UI가 잘 보이도록 앵커를 변경해주었다.

  • 받았던 피드백:
    • 앵커를 신경써주어야 함
    • 신경쓰지 않으면 어떤 환경에서는 UI가 제대로 출력되지 않을 수 있음
    • 요즘은 디스플레이 크기가 다양하기 때문에 1:1~1:2.5 비율까지 신경써주면 좋음
    • 일단 1920:1080 크기로 작업하고, 테스트할 때는 Free Aspect로 설정하고 늘리고 줄이며 테스트 하는 습관을 들일 것
    • BackGround 같은 경우에는 아래처럼 앵커를 설정해줄 것!!
  • 데이터와 UI 연동

    • 내가 구현한 방식:
      • Canvas에 UI를 관리해주는 UIManager 스크립트를 붙여 GameManager에서 값을 변경할 때마다 UIManager에 있는 프로퍼티를 통해 UI의 값 또한 변경해주는 코드를 짬.
      • 자세한 코드는 아래 겪은 어려움 란에서!!
    • 받았던 피드백:
      • 잘 구현해주었으나 조금 돌아가는 느낌이 듦.
      • 클래스를 두 개 나눌 필요 없이 GameManager에서 바로 Text 컴포넌트를 받아와서 수정해주어도 충분!
  • 버튼을 통한 입/출금 UI창 변경

    • 내가 구현한 방식:

      • OnValidate()에서 Find() 메서드를 통해 UI창들을 찾아서 스크립트로 연결해줌.
      private void OnValidate()
      {
          UI_Deposit = transform.Find("Deposit").gameObject;
          UI_Withdraw = transform.Find("Withdraw").gameObject;
          ATM = transform.Find("ATM").gameObject;
      }
    • 받았던 피드백:

      • Find()로 찾아 연결하는 방식은 나중에 이름이 바뀌었을 때 오류가 날 수도 있음
      • 이 정도는 Inspector창에서 직접 연결해주는 편이 낫다.
      • 만약 연결하려는 객체가 기능이 많아서 각자의 클래스를 들고 있는 상태라면, 자식 객체가 생성되는 순간 자식의 Awake에서 부모에게 걔가 나다! 하고 연결해주는 방식을 사용하는 편이 좋다. => 기억했다가 나중에 써먹어볼것!

📍겪은 어려움

  • 프로퍼티를 이용한 데이터 연동에서 일어난 오류

    • 프로퍼티는 데이터가 변경되는 것을 감지할 수 있기 때문에 데이터와 UI를 연결하는 부분에서도 써먹을 수 있을 거라 생각했음.

    • 나의 계획: GameManager에서 UsetData를 변경하면, set에서 UI의 텍스트를 변경시켜주는 함수를 실행시킨다.

    • 결과: 그런데 데이터를 변경시켜주어도 UI의 텍스트는 변경되지 않았다.

    • 추정: 프로퍼티가 get과 set을 감지하려면 프로퍼티 본인을 변경하거나 가져와야 하는데, UsetData나 Text의 프로퍼티를 만들어봤자 본인이 아닌 그 안의 string 변수를 건들이기 때문에 제대로 감지하지 못하는 것 같았다.

    • 그렇게 생각한 이유:

      public Text balanceText;
      public Text BalanceText
      {
          get { return balanceText; }
          set
          {
              BalanceText = balanceText;
              Test();
          }
      }
      
      private void Start()
      {
          BalanceText.text = "10000";
      }
      
      public void Test()
      {
          Debug.Log("Text.text를 변경해도 프로퍼티가 제대로 감지함!");
      }
    • 프로퍼티가 BalanceText.text를 변경할 때도 변화를 감지한다면 Test 메서드가 실행되면서 설정된 log가 뜰 것임.

    • 결과: 보다시피 Balance의 text값은 바뀌었지만 Text() 메서드는 실행되지 않았다...

  • 수정한 방식:

    public Text balanceText;
    private int balance;
    public int Balance
    {
        get { return balance; }
        set
        {
            balance = value;
            balanceText.text = Formating(balance);
            Test();
        }
    }
    
    private void Start()
    {
        balance = 10000;
    }
    private string Formating(int num)
    {
        return string.Format("{0:N0}", num); 
    }
    
    public void Test()
    {
        Debug.Log("프로퍼티가 제대로 작동함");
    }
  • UserData에서 각 필드의 프로퍼티를 만들거나, UIManager에서 Text 프로퍼티를 만드는 대신, int형 프로퍼티를 새로 만들고 이 int형 Balance 프로퍼티가 수정될 때마다 balanceText.text의 값도 수정되도록 만들었다. (해당 코드에서 사용된 Formating 메서드는 천 단위마다 ,를 찍어주는 메서드이다.)

  • 결과: 잘 변경된다!!!!!!

📍회고 및 반성

  • UI 수업 때 배웠던 디자인 패턴도 잘 써보고 싶었는데 생각만큼 잘 되지 않았다... (옵저버 패턴 같은 거)
  • 그래도 구현하고 비교해보니 내가 프로퍼티로 구현한 것도 MVC라는 패턴에 속하는 것 같았음.
  • 시간이 남는대로 디자인 패턴도 공부하고 정리해보고 싶다!
  • 적용할만한 디자인 패턴을 발견하면 과거 작업물들을 리팩토링을 하며 적용해보는 것도 괜찮지 않을까? 일단 염두에 두기!

0개의 댓글