08/24 UI 추가, VFX 완성 + Unity Profiler 심화
댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.
가비지 콜렉터 동작 원리
C#의 GC(Garbage Collector)는 더 이상 사용하지 않는 객체를 자동으로 찾아 메모리를 회수하며, 개념적으로 Mark → Sweep → Compaction 과정으로 이해하면 쉽습니다.
| 단계 | 동작 | 목적 |
|---|---|---|
| 1. Mark | 루트 객체에서 시작해 접근 가능한 객체를 표시 | 사용 중인 객체 식별 |
| 2. Sweep | 표시되지 않은 접근 불가능한 객체의 메모리를 회수 | 불필요한 객체 제거 |
| 3. Compaction | 살아남은 객체들을 한쪽으로 이동 | 메모리 단편화 감소 |
즉, “사용 중인 객체를 찾고(Mark) → 필요 없는 객체를 제거하고(Sweep) → 남은 객체를 정리한다(Compaction)”라고 기억하시면 됩니다.
설계 패턴 MVC, MVP, MVVM
설계 패턴(Design Pattern)은 소프트웨어를 개발하면서 반복적으로 발생하는 구조적 문제를 해결하기 위해 정리된 검증된 설계 방식입니다. 즉, 특정 코드를 그대로 복사해서 사용하는 것이 아니라, 객체와 클래스의 역할을 어떻게 나누고 서로 어떻게 연결할지에 대한 설계 아이디어라고 이해하시면 됩니다.
Unity에서는 특히 게임 로직, 데이터, UI가 한 클래스에 뒤섞이는 문제를 줄이기 위해 MVC, MVP, MVVM 같은 패턴을 활용할 수 있습니다.
| 구분 | MVC | MVP | MVVM |
|---|---|---|---|
| 구성 | Model / View / Controller | Model / View / Presenter | Model / View / ViewModel |
| 핵심 역할 | Controller가 입력과 흐름 제어 | Presenter가 View와 Model 중개 | ViewModel과 View를 데이터 바인딩 |
| 화면 갱신 | Controller 중심 | Presenter가 직접 갱신 | Binding으로 자동 갱신 |
| 특징 | 단순하고 이해하기 쉬움 | 역할 분리가 명확함 | 복잡한 UI 관리에 유리 |
| Unity 활용 | 소규모 프로젝트 | 일반적인 게임 UI | UI/상태가 복잡한 프로젝트 |
패턴의 선택은 상황에 따라 달라지지만, Model과 View는 공통적으로 존재합니다. Model은 데이터와 로직을, View는 UI 표현을 담당합니다.
UI Canvas 렌더링 방식 변경
UI Canvas 컴포넌트에서는 Inspector의 Render Mode 항목을 변경하여 UI가 화면에 렌더링되는 방식을 선택할 수 있습니다.
| Render Mode | 동작 방식 | 카메라 필요 여부 | 특징 | 주로 사용하는 경우 |
|---|---|---|---|---|
| Screen Space - Overlay | UI를 게임 화면 위에 직접 그립니다. | ❌ 필요 없음 | 가장 단순한 방식이며 UI가 항상 화면 위에 표시됩니다. 카메라의 위치나 방향에 영향을 받지 않습니다. | HUD, 체력바, 점수, 메뉴, 일반적인 2D UI |
| Screen Space - Camera | 특정 카메라 앞의 평면에 UI를 배치하여 렌더링합니다. | ✅ 필요 | Render Camera와 Plane Distance를 지정할 수 있습니다. 카메라의 렌더링 과정에 UI가 포함되므로 카메라 설정과 함께 제어하기 좋습니다. | 카메라와 UI의 렌더링 관계를 제어해야 할 때, 일부 연출용 UI |
| World Space | Canvas 자체를 게임 월드 안의 하나의 오브젝트처럼 배치합니다. | ✅ 일반적으로 카메라로 관찰 | Transform의 위치, 회전, 크기를 자유롭게 변경할 수 있으며 다른 3D 오브젝트와 공간적으로 함께 존재합니다. | NPC 머리 위 체력바, 게임 속 모니터·간판, VR/AR UI |
Enemy HPBar 만들기
public class HealthBar : MonoBehaviour
{
[SerializeField] private Health health;
[SerializeField] private Slider slider;
Camera mainCamrea;
void Awake()
{
mainCamrea = Camera.main;
}
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
slider.maxValue = health.MaxHealth;
slider.value = health.MaxHealth;
}
void OnEnable()
{
health.OnDamaged += UpdateHealthBar;
}
void OnDisable()
{
health.OnDamaged -= UpdateHealthBar;
}
// Update is called once per frame
void UpdateHealthBar(int currentHP, int maxHP)
{
slider.value = currentHP;
}
private void LateUpdate()
{
transform.forward = mainCamrea.transform.forward;
}
}
Enemy의 체력바가 월드 공간에 표시되도록 Canvas의 Render Mode를 World Space로 설정합니다.
Health의 OnDamaged 이벤트에 체력바 갱신 메서드를 구독하여 데미지를 받을 때마다 Slider의 값을 현재 체력으로 변경합니다.
또한 LateUpdate()에서 체력바의 방향을 카메라 방향과 일치시켜, Enemy가 어느 방향을 바라보더라도 HPBar가 항상 카메라를 향하도록 설정합니다.
Model과 View를 관리하는 EnemyPresenter 만들기
public class EnemyPresenter : MonoBehaviour
{
[Header("Model")]
[SerializeField] private Health health;
[Header("View")]
[SerializeField] private Slider slider;
[SerializeField] private TMP_Text currHP;
[SerializeField] private TMP_Text maxHP;
private void OnEnable()
{
health.OnDamaged += UpdateHP;
}
private void OnDisable()
{
health.OnDamaged += UpdateHP;
}
private void Start()
{
UpdateHP(health.CurrentHealth, health.MaxHealth);
}
private void UpdateHP(int currHP, int maxHP)
{
if (health.IsDead)
return;
this.slider.value = currHP;
this.slider.maxValue = maxHP;
this.currHP.text = currHP.ToString();
this.maxHP.text = maxHP.ToString();
}
}
Presenter가 Model의 이벤트를 구독해 View를 갱신한다 — View는 Presenter만 알거나 아무것도 몰라도 된다
파티클 시스템을 활용한 사격 효과 구현
파티클 시스템(Particle System)은 불꽃, 연기, 먼지, 폭발처럼 작은 입자들이 모여 만들어지는 시각적 효과를 구현하는 기능이다. 게임에서는 총기 발사, 폭발, 피격 효과 등 다양한 상황에 활용되며, 짧은 시간 동안 많은 입자를 생성하고 각각의 크기, 색상, 속도, 방향, 수명 등을 조절하여 자연스러운 이펙트를 표현할 수 있다. 사격 기능에서는 대표적으로 총구 화염(Muzzle Flash)과 탄환이 물체에 충돌했을 때 발생하는 피격 효과를 표현하는 데 사용된다.
총을 발사하면 총구 부분에서 순간적으로 빛과 화염이 발생하는데, 이를 Muzzle Flash라고 한다. 게임에서는 총구 위치에 미리 파티클 시스템을 배치해 두고, 플레이어가 발사 입력을 했을 때 해당 파티클 시스템을 실행하도록 구현할 수 있다. 총알을 발사하는 처리와 동시에 Muzzle Flash를 재생하면 실제 총기가 발사되는 것과 같은 시각적인 피드백을 줄 수 있다. 효과가 너무 오래 지속되면 부자연스러울 수 있으므로 짧은 시간 동안 강하게 나타났다가 빠르게 사라지도록 설정하는 것이 일반적이다.
총알이 어떤 물체에 맞았는지를 판단하기 위해 레이캐스트(Raycast)를 사용할 수 있다. 레이캐스트는 특정 위치에서 특정 방향으로 보이지 않는 선을 발사하여 그 선과 충돌한 오브젝트의 정보를 확인하는 방식이다. 총을 발사할 때 총구나 카메라의 위치에서 조준 방향으로 레이캐스트를 실행하면 탄환이 맞은 물체뿐만 아니라 충돌 지점(Hit Point)과 해당 표면의 방향을 나타내는 법선 벡터(Normal Vector)도 얻을 수 있다.
피격 효과를 자연스럽게 표현하려면 파티클을 단순히 충돌 위치에 생성하는 것뿐만 아니라 표면의 방향에 맞게 배치해야 한다. 이때 레이캐스트로 얻은 법선 벡터를 활용한다. 법선 벡터는 충돌한 표면에서 바깥쪽을 향하는 수직 방향을 의미하므로, 파티클 시스템의 방향을 법선 벡터와 맞춰 주면 벽, 바닥, 천장 등 어떤 각도의 표면에 총알이 맞더라도 파편이나 불꽃이 표면에서 바깥쪽으로 튀어나오는 자연스러운 효과를 만들 수 있다.

우리들의 게임 발매 이야기

안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.
XR을 활용한 게임 개발 3기(유니티) 수강생입니다. 곧 수료 하지만 앞으로 이곳에 가끔 저의 개발 경험이 나 지식 기록할까 합니다. 더 나아가 이 사이트가 제 개인위키의 역할을 할 수 있으면 좋겠습니다. 한국 게임 시장을 흔들겠습니다


안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.
XR을 활용한 게임 개발 3기(유니티) 수강생입니다. 곧 수료 하지만 앞으로 이곳에 가끔 저의 개발 경험이 나 지식 기록할까 합니다. 더 나아가 이 사이트가 제 개인위키의 역할을 할 수 있으면 좋겠습니다. 한국 게임 시장을 흔들겠습니다
