0410 - Unity 부트캠프 [4일차]

Hyeon O·2025년 4월 10일

Unity_BootCamp 1주차

목록 보기
4/5
post-thumbnail

📚 오늘의 학습

이번 주차의 모든 강의를 완강했기에
오늘은 완강한 강의 내용 중 부분적으로 회고 및 탐구를 진행하고
튜터님의 라이브 세션을 통해 내가 모르던 것들 위주로 메모를 해보려 한다.

- 이전 강의 회고 및 추가 탐구

  1. Destory() 딜레이 버그

  2. Application.targetFrameRate와 VSync 의 충돌 가능성

- 라이브 세션에서 얻어간 내용

  1. TextTMP와 폰트 설정

  2. PPU(Pixels per Unit)에 대해서

  3. 그 외의 팁





🧠 오늘 새롭게 배운 것 & 다시 떠올린 개념들

1. 이전 강의 회고 및 추가 탐구

지금까지 들었던 강의에서 정리했던 내용에서

좀 더 알아볼 만한 내용을 탐구하고 정리해본다.

1. Destroy() 딜레이로 인한 버그

팀원과 TIL 피드백을 하던 도중,

한 분께서 이와 관련해서

일대일 반응을 하는 하나의 총알 오브젝트가 겹쳐있는 두 오브젝트에 모두 반응을 하는 현상을 발견하였다고 했다.


예를 들어, 권총 한 발을 쐈는데 같이 붙어있는 오브젝트 2개가 동시에 맞은 것이다.

현실에서는 있을 수도 있지만 게임 구현 상에서는 그러면 안된다.

이 원인은 그럼 어디서 발생한 것일까?

구현된 코드에 따라 다르겠지만,

Destory()를 쓴 경우, 지연 파괴 특성이 원인일 가능성이 높다.

총은 조금 더 앞에 있는 오브젝트가 맞았지만,

다음 프레임까지 총알은 삭제되지 않기 때문에,

그 전에 다른 오브젝트와 만나서

두 오브젝트에 영향을 준 것이다.

그렇다면 한 번 실험을 해보자.

하나의 오브젝트로 보이지만 2개를 겹쳐두었고

y축으로 0.03만큼의 위치 차이를 가지고 있는 상태이다.

실행을 해보면,

둘 다 상호작용하는 것을 볼 수 있다.

좀 더 직관적으로 보기 위해 많은 고양이를 희생(?)시켜서 실험해보면

앞에서 부터 뒤에 몇 마리까지 게이지가 오른 것을 확인 할 수 있고
오른쪽에 5마리 고양이가 총알 한 발에 같이 맞은 애들이다.


그럼, 이를 방지하기 위한 방법은 무엇일까?

첫 번째는 Destory() 함수를 반드시 사용해야 하는 경우, 고양이의 생성과 RigidBody 특성을 이용해서 중복 충돌을 방지하는 방법이 있다.

하지만 위 방법은 게임 기획에 있어서 확장 범위를 좁혀질 수 있기에 최후의 수단으로 하는 것이 좋을 것 같다.

두 번째 방법은 총알의 유효성을 논리적으로 제한하여 방지하는 방법이다.

기존 코드에서 투사체에 bool isValid 를 추가하여 충돌 시점에만 유효 처리는 하는 것이다.

 private void OnTriggerEnter2D(Collider2D collision)
 {
     if(collision.gameObject.CompareTag("Food"))
     {

         if(energy < full)
         {

             energy += 1.0f;
             front.localScale = new Vector3(energy / full, 1.0f, 1.0f);
             Destroy(collision.gameObject);

             if (energy == 5.0f)
             {
                 if (!isfull)
                 {
                     isfull = true;
                     hungryCat.SetActive(false);
                     fullCat.SetActive(true);
                     Destroy(gameObject, 5.0f);
                     GameManager.instance.AddScore();
                 }
             }

         }
        

     }
 }
private void OnTriggerEnter2D(Collider2D collision)
{
    if (!isValid) return; // 이미 다른 오브젝트와 충돌했으면 처리 중단 
    if (collision.CompareTag("Cat"))
    {
        isValid = false;
    }

} //기존 코드에서 추가된 코드

고양이와 투사체(음식)의 충돌 관련 코드만 가져왔다.

고양이의 트리거 메소드에서 충돌 시 작업과 충돌한 상대 오브젝트를 삭제하는 작업을 진행하고

투사체(음식) 코드에 트리거 메소드를 추가 구현하여

if(!isValid) 조건문을 통해

isValidfalse 라면 바로 리턴한다.

즉, 아래 코드를 진행하지 않는다

반대로 true 라면 아래 코드를 진행하여 isValid 값을 false 로 변경하여 만일 다음 타겟과 충돌 시 관련 작업을 무시하도록 한다.

위 코드로 실험을 진행해보자.

실험 결과 많이 겹쳐져 있어도 단일 대상만 잘 타격한다

세 번쨰로, 구현 자체를 바꿔서 오브젝트 투사체가 아닌, Raycast 로 구현하는 것이다.

Raycast 는 즉시 충돌 결과를 계산하므로 프레임 지연과는 관계가 없다.

따라서 아예 '총알이 날아가면서 맞출 수 있는 대상'을 발사 순간에 판단하는 Raycast방식이 더 구조적이고 안정적일 수 있다.

Raycast 에 대한 내용은 추후에 다룰 시간이 있으면 따로 한번 정리해 볼 생각이다.

<요약>
Destroy()는 즉시 제거가 아니기 때문에, 충돌 처리 시 한 발에 여러 오브젝트가 반응할 수 있음.
이를 방지하려면 isValid 플래그 또는 Raycast 활용이 효과적.


2. Application.targetFrameRate와 VSync 의 충돌 가능성

2일 차 TIL에서 정리한 내용에서

<2일차 TIL 링크>

다음과 같은 내용을 정리하였는데

이게 어떻게 충돌 가능성이 존재하는지에 대해서 한 번 알아보자.

우선 VSync에 대해서 알아야 한다.

VSync은 GPU가 화면 주사율에 맞춰 프레임 출력을 조절해주는 기술을 의미한다.

화면 찢어짐(Screen Trearing)을 방지하는데 목적을 가진다.

화면 찢어짐은 GPU가 프레임을 너무 빨리 렌더링하면, 모니터가 아직 이전 프레임을 다 출력하지 않았는데 다음 프레임을 표시하려고 해서, 화면이 수평으로 찢긴 듯한 현상을 의미한다.

VSync은 모니터가 다음 프레임을 출력할 준비가 될 때까지 GPU를 대기시킨다.

유니티에는 이 둘에 대한 우선 순위 규칙이 존재한다.

  • VSync가 활성화(VSync Count = 1 이상)되어 있다면, → Application.targetFrameRate 설정은 무시된다. → 프레임은 모니터 주사율(예: 60Hz)에 맞춰 고정됩니다.
  • VSync가 꺼져 있을 때(VSync Count = 0)Application.targetFrameRate적용됩니다. → 예: targetFrameRate = 144로 설정하면, GPU가 가능한 한 144fps에 맞춰 프레임을 생성.

따라서

QualitySettings.vSyncCount = 1인데 Application.targetFrameRate = 30으로 설정하면?

→ 결과적으로 VSync가 우선, 60fps로 유지된다.

targetFrameRate무시

반대로 vSyncCount = 0으로 꺼둔 상태에서 targetFrameRate = 1000이라면?

→ 가능한 최대 fps로 계속 렌더링됨. 이때 GPU 부하가 매우 심할 수 있음.

극적인 예시이지만 참고해두자…


2. 라이브 세션에서 얻어간 것들

1. TextTMP 폰트 사용법에 대해서

Untiy에서 문자를 화면 상에 표현할 때, Text 오브젝트를 사용한다.

그런데 Text 오브젝트를 생성할 때 보면 2가지가 있다.
바로 Text(Legacy)와 TMP이다.

Text(Legacy)는 기존 텍스트 UI인 반면

TMP는 기존보다 렌더링 품질과 성능이 개선된 UI다.

기존 Tex UI 처럼 canvas에 생성해서 사용하면 되고

특히 폰트를 가져와 사용할 때, 기존에 비해 더욱 향상된 모습을 보여준다.

기존 폰트파일 “이름.ttf” 를 TMP 텍스트에 사용하려면

아래 Font Asset Creator 에 들어가서

위의 창이 열리면,

Source Font File 에 ttf 파일을 드래그&드롭 해준다.

파일이 들어가면 위의 설정을 상황에 맞게 해서 저장하면

위의 이미지 처럼 SDF 파일이 생성되고 이 폰트 파일을 TMP 컴포넌트에서 사용하면 된다.

아래는 기존과 TMP의 성능 차이를 직접 보기위해 캡쳐한 이미지이다.

왼쪽이 기존 텍스트고 오른쪽이 TMP이다. 선의 마감이나 디테일이 같은 폰트임에도 불구하고 압도적으로 향상되었다.


2. 픽셀에 대해서

디자인 아트를 픽셀로 할 때,

반드시 알아두어야 할 내용으로

아래는 픽셀 에셋 인스펙터 창의 한 부분으로

Pixels Per Unit 속성에 집중해보자. PPU라고도 불리며 2D 게임 개발에서는 중요한 개념이다.

위 속성은 PPU = 500이라고 하며, 스프라이트 500픽셀이 Unity 월드 유닛 1칸에 대응한다는 의미이다.

한 유닛은 아래 이미지가 들어가있는 사각형이다.

즉, 저 사각형에 500픽셀이 들어가게 설정한 것이다.

만일 이 값은 절반인 250으로 변경하면 어떻게 될까?

한 유닛에 250개까지 들어간다는 의미가 될 것이고,

한 유닛에 들어가는 500개의 사각형과

한 유닛에 들어가는 250개의 사각형은

당연하게도 250개가 더 클 것이다
그래서 250으로 설정한 이미지가 더 커진다.

간단하게 생각해보면

아래 두 이미지의 사각형안에 작은 사각형의 크기를 비교해보면 된다.

(참고)

위 그림을 보면 4의 배수로 설정하면 딱 맞다고 볼 수 있다.

그렇다면 유닛에 들어가는 픽셀은 4의 배수이어야 하는 거 아닌가?

구현하는데 있어서 기능의 큰 문제는 아니지만,
픽셀 깨짐, 흐릿한 이미지 등등, 픽셀 디자인에 있어서

4의 배수로 맞추는 것이 안정적이고 권장된다고 한다.

위의 참고 관련 링크

3. 그 외 팁들

  1. 오브젝트 생성 시 위치를 중앙으로 고정시키는 방법

    아래 Create Objects at Origin 체크 시 새 오브젝트들이 월드 중앙에 고정적으로 생성된다.

  1. Visual Studio단축키

    ctrl + Shift + n : 게임 오브젝트 생성 단축키

    ctrl + Shift + c : 콘솔 창 열기

    ctrl + p : 게임 실행

    ctrl + b : 빌드 한 후 게임 실행

  2. Resource 파일 주의사항

    Resource 파일에 사용하지 않는 파일을 넣으면 안된다.

    빌드할 때 같이 빌드되는 파일이기 때문에,

    사용하지 않는 파일을 넣으면 메모리를 낭비하게 된다.



💭 오늘의 회고

🎯 오늘 얻은 인사이트

  • Destroy()의 지연 특성은 단순한 충돌 문제가 아니라 설계적 관점에서 다뤄야 할 주제였다.
  • TMP와 PPU는 단순 UI 설정이 아니라, 렌더링과 아트 디테일 전체를 조정할 수 있는 트리거임을 알게 됐다.
  • 빌드 전 Resource 파일 주의사항에 대해서 인지하게 되었다.

🤔 나의 고민

  • TIL을 모르는 개념 중심으로 모두 정리할지, 하나의 주제를 깊게 정리할지 아직 기준이 필요하다.
  • 지금은 알고 있는 것보다 모르는 것이 많으니 다 정리 중
profile
천천히, 꾸준하게, 끝까지

0개의 댓글