부트캠프/본캠프

[내일배움캠프_2025AUG1]팀 프로젝트 4일차, 커스터마이징

Young_A 2025. 8. 1. 23:41

목차

    팀 프로젝트 4일차, 커스터마이징

     

    벌써 8월이다...

    그리고 금요일이다.

     

    아침에 유데미 강의를 듣고, 오전 스크럼을 진행했다.

    팀원 모두가 알차게 작업 리스트를 갖고 해산했다.

    나는 이번에 커스터마이징을 진행하기로 했는데, 마땅한 아이디어가 없다고 했더니 팀원들이 좋은 아이디어를 내주셔서 그대로 진행하려고 한다.


    유니티 디버그 모드

    유니티에서도 (당연하지만) 디버그 모드가 있다.

    저걸 누른 다음에 꼭!! 💥기다려야 함!💥

    승질머리 급한 나로서는 자꾸 안기다리고 유니티로 돌아가서 게임 실행하고 "뭐야, 왜 안돼?" 하는 경우가 반복되었다...

     

    준비가 다 되고 나면 유니티에서 뭐라고 하는데, 디버그 모드로 진행하겠다고 하면 된다!

    그리고 디버그 걸릴 상황에 처해주면 비주얼 스투디오에서 해당 코드에서 진행이 멈춰져 있는 것을 확인할 수 있다.


    이미지로 체력바 UI 만들기

    BlackPixel은 아무것도 없는 하얀 픽셀 하나인 이미지다.

    Image Type Filled, Fill Method Horizontal, Fill Origin을 Left로 하면, 아래의 Fill Amount 슬라이더로 조절하면 슬라이더를 이용한 것처럼 사용할 수 있다.

    아직 슬라이더를 사용해본적이 없어서 비교할 순 없겠지만 이 것도 꽤나 간단해서 급하게 UI 프로토타입을 만들어야할 때 사용하면 좋을 것 같다.


    UIManager 분석

    public class UIManager : MonoBehaviour
    {
        [Header("Stats")]
        [SerializeField] private PlayerStats stats;
    
        [Header("Bars")]
        [SerializeField] private Image healthBar;
        [SerializeField] private Image manaBar;
        [SerializeField] private Image expBar;
    
        [Header("Text")]
        [SerializeField] private TextMeshProUGUI levelTMP;
        [SerializeField] private TextMeshProUGUI healthTMP;
        [SerializeField] private TextMeshProUGUI manaTMP;
        [SerializeField] private TextMeshProUGUI expTMP;
    
        private void Update()
        {
            UpdatePlayerUI();
        }
    
        private void UpdatePlayerUI()
        {
            levelTMP.text = $"Level {stats.Level}";
        }
    }

    강의를 들으며 작성한 UIManager 중에 마음에 드는 부분들을 몇개 짚고 넘어가면 좋을 것 같다.

     

    첫째로, Scriptable Object를 사용하여 제작한 PlayerStats만 참조하는 점.

    Player.cs를 전부 가져와서 사용하는 것보다 훨씬 덜 유기적이라 코드 관리가 쉬울 것 같다는 생각이 들었다.

    테스트를 진행하더라도 Scriptable Object의 특성을 이용해 테스트를 하기에도 보다 간편해질 것 같다.

     

    둘째로, [Header]를 이용한 점.

    알고 있던 기능이지만 잘 사용하지 않았는데 꽤나 괜찮아보인다.

     

    셋째로, Update() 내부에 직접 코드를 짜는 것이 아닌, 메소드만 호출하는 점.

    Update같은 경우, 해당 기능만 구현될 것이라는 보장이 없다.

    따라서 메소드로 구현하고 메소드를 호출하는 한 줄만 작성하는 것이 추후 기능이 계속 추가되면서 길어질 Update()을 한 눈에 파악하고 관리하기 좋을 것 같다는 생각이 들었다.


    Mathf.Lerp 보간

    저번에는 강의 따라가기 급해서 일단 정리만 했었던 것 같다.

    다시 마주하니 조금 어려워서 다시 한번 정리해보려고 한다.

    healthBar.fillAmount = stats.Health / stats.MaxHealth;

    나는 위와 같이 단순히 계산된 비율을 바로 fillAmount에 넣어서 체력을 표현하려고 했다.

     

    하지만 강사님은 아래와 같이 Mathf.Lerp를 이용하셨다.

    healthBar.fillAmount = Mathf.Lerp(healthBar.fillAmount, stats.Health / stats.MaxHealth, 10f * Time.deltaTime);

     

    내가 생각했던 방식은 단순하지만, 체력이 변할 때 체력바가 훅 줄거나 늘어나서 시각적으로 부자연스러울 수 있다.

    마치 콘솔 TextRPG를 만들 때 수준의 그래픽이 되는 것이다.

     

    하지만 Mathf.Lerp를 이용할 경우 체력바가 부드럽게 애니메이션 되면서 변화한다.

    이는 사용자가 줄어드는 애니메이션을 직접 확인 할 수 있어 자연스럽게 체력이 줄어든다는 것을 인지하기 쉽다.

     

    Lerp는 현재 값과 목표 값 사이를 선형 보간해주는 함수인데,

    Time.deltaTime과 곱해줘서 프레임마다 조금씩 변화하게 만드는 것이 포인트였다.

     

    게임은 UI 그래픽도 매우 중요하다.

    게임의 플레이는 실시간으로 진행되는 만큼, 유저에게 게임 상황을 인지하기 쉽도록 하는 것이 게임에 몰입을 할 수 있는 요소라고 생각하기 때문이다.

    그런 의미에서 게임 개발을 하게 된다면 무조건 사용할 수 밖에 없는 함수 및 개념일 것 같다.


    타일맵 자르기

    타일맵을 자르기 전에 Sprite를 어떻게 셋팅해야하는 지는 이제 어느정도 익숙해졌다.

     

    하지만 타일맵을 자르는 방법은 4가지가 있다. 

    우선 가장 많이 쓰이는 2가지는 Automatic과 Grid by cell size

     

    Automatic은 빈 공간을 기준으로 자르는 방법이다.

    타일마다 빈 공간이 하나씩 있는 경우, Automatic을 선택하여 편하게 작업할 수 있다.

    단, 2개의 오브젝트를 한 타일에 놓아야하는 경우도 있을 것이다. (장갑이라거나 등등)

    그 경우에는 해당 오브젝트만 따로 수정할 수도 있다.

    상단의 중앙 이미지를 보면 선택된 오브젝트는 본래 2개로 나뉘어졌으나 따로 합쳐주었다.

     

    Grid by cell size는 정사각형 타일들이 정렬된 채로 준비되어있을 때 사용하면 좋다.

    16 x 16으로 자동으로 잘라준다. 

    아직 한번도 사용해보지 않은 Grid by cell count와 isometric grid 옵션도 있다.

     

    Grid by cell count는 해당 스프라이트를 총 몇 개의 행과 열로 나눌 지 결정할 수 있고,

    isometric grid는 찾아보니 3D처럼 보이지만 실제로는 2D로 표현된 타일맵을 자를때 쓴다고 한다.
    카메라를 45도 방향으로 기울인 듯한 시점을 표현할 때는 보통 타일 하나가 마름모(다이아몬드) 형태로 생기기 때문에, 이를 위한 옵션이라고 한다.


    느낀점

    오늘은 도전 과제를 구현 시작했다.

    커스터마이징 + 상점 구현을 할텐데, 욕심이 생겨서 체력을 늘린다거나 하는.. 효과를 넣고 싶지만!!

    다들 주말엔 쉬기로 했기 때문에 하지 않기로 했다.

     

    TIL 적을게 별로 없다.

    그때마다 작성했어야했는데 깜빡하고 구현에 집중하느라...

    오늘은 점심 때 팀원들한테는 점심 맛있게 드시라고 말은 해놓고 이것만 하고 먹어야지 하다가 점심을 걸렀다!

    ㅜㅜ 집에 간식도 없었어서 오후 내내 집중 못하고 진행했던 것 같다.


    내일 학습 할 것은 무엇인지

    내일은 안할 수도 있을 것 같다.

    이틀 중 하루는 과제를 마무리하고, 나머지 하루는 개인 학습을 하지 않을까?