학습 개요

약 4일동안 만든 카드 매칭 게임도 마무리 단계에 접어들었다.

오늘의 시간은 대부분 게임의 사소한 디테일을 추가하거나 버그 픽스를 하면서 보냈다.

카드 랜덤 배치 알고리즘 수정

원래 사용하던 OrderBy(x => Random.Range() 방식은 간단하지만 본질적으로 “무작위 셔플”이 아니다. 그 이유는 다음과 같다.

  • Random.Range는 충돌(동일한 값이 나오는 경우)이 생기기 쉬운 부동소수형 난수이다

  • 키 값이 충돌하거나 부동소수의 정밀도 문제로 인해 OrderBy의 정렬 순서가 완전히 랜덤하지 않을 수 있다.

  • 특히, 작은 배열에서는 유사하게 섞이는 경우가 자주 발생하고, 이게 쌓이면 패턴처럼 느껴질 수 있다.

따라서 카드가 항상 특정 패턴으로 섞이는 문제가 발생할 수 있다.

그러므로 셔플 방식을 Fisher-Yates Shuffle로 바꿔주었다.

for (int i = boardSize - 1; i > 0; i--) //Fisher-Yates Shuffle
      {
          int rand = Random.Range(0, i + 1);
          (arr[i], arr[rand]) = (arr[rand], arr[i]);
      }

Fisher-Yates Shuffle은 각 요소를 배열의 뒷부분부터 하나씩 무작위로 교환하는 방싯으로 모든 순열이 균등한 확률로 생성된다.

카드 애니메이션과 Trasform 처리

  • 카드 애니메이션으로 rotation의 y값을 180도 회전시킨 후, 다시 되돌아가기 전에 게임오브젝트가 비활성화 되어 180도 돌아간 생태로 유지되는 문제가 발생

  • 애니메이터가 활성화되어 있으면 스크립트에서 transform.roatation을 직접 설정해도 적용되지 않는다는 점을 알게 되었다.

  • 애니메이터를 잠시 비활성화 하고, roatation 값을 수정하는 방식으로 해결

AudioSource 제어

  • 오디오소스를 .Stop().Play()하면 처음부터 다시 재생된다.

  • 중간부터 이어서 재생하고 싶으면, .Pause()/.UnPause()로 제어 가능

코루틴 조기 종료

  • 코루틴 또한 메서드처럼 yield break를 통해 중간에 탈출 가능
 IEnumerator FlipCard()
    {
        if (GameManager.Instance.firstCard == card) //같은 카드 두번 클릭 방지
        {
            yield break;
        }

소수점 포맷팅

  • 점수를 표시할 때 “F2”를 사용하면 12.345 → 12.35 형태로 반올림된 두 자리 소수점 출력.

  • “N2”는 동일하게 두 자리 출력하면서도 천 단위 쉼표(,)가 붙는 형식: 12345.6 → 12,345.60

오늘 배운 핵심 정리

  • 유니티 애니메이터를 통해 Transformroatation을 건드릴 경우, 애니메이터가 활성화되어 있으면 스크립트에서 rotation값을 수정해도 적용이 되지 않으므로 주의가 필요하다.
  • 애니메이션을 사용할 때에는 시간의 흐름에 따른 애니메이션 컨트롤러의 트랜지션 흐름을 정확하게 파악하고 있어야 불필요한 버그를 방지할 수 있을 듯 하다.

댓글남기기