投稿

[CT] 04. testest (ゲームマル2026夏コンテスト)

[CT] 04. testest (ゲームマル2026夏コンテスト)

[ERROR-CODE-H 개발일지] 3주차 — 사이버펑크 HUD 리메이크와 스킬·사망 연출 구현

개발 기간: 2026.07.20 ~ 2026.07.26 담당 역할: 에셋 2 — HP·Heat·Core 인터페이스 리메이크 및 Skill UI 추가

2주차에는 기존 Heat·Core HUD에 HP UI를 추가하고, HP 감소 파티클과 Low HP 경고를 구현했다. 또한 HP·Heat·Core UI를 하나의 HUD 프리팹으로 정리하면서, 실제 게임에서 재사용할 수 있는 기본적인 인터페이스 구조를 만들었다.

3주차에는 여기서 한 단계 더 나아가, 기능 위주로 구성되어 있던 HUD를 『ERROR-CODE-H』의 사이버펑크 분위기에 어울리는 디자인으로 발전시키는 작업을 맡았다.

이번 주의 주요 목표는 다음과 같았다.

  • Heat 게이지 디자인 리메이크
  • High Heat 및 OverHeat 상태 연출 추가
  • Heat 게이지 전용 Shader Graph 제작
  • HP 배경 이미지 가독성 개선
  • HUD 폰트를 픽셀 스타일로 변경
  • Core 옆에 Skill 아이콘 추가
  • Skill 사용 시 UI 피드백 추가
  • 2주차에 미뤄두었던 사망 연출 구현
  • HUD 프리팹 구조 정리

다만 모든 UI를 한 번에 완전히 리메이크하기에는 작업량이 많았다.

따라서 이번 주에는 Heat UI, Skill UI, 사망 연출을 중심으로 작업하고, HP와 Core UI는 기존 기능 구조를 유지하면서 일부 디자인만 개선했다. 전체적인 리메이크는 이후 작업으로 남겨두었다.

기능 중심 HUD에서 사이버펑크 HUD로

1~2주차의 가장 중요한 목표는 Heat, Core, HP 정보가 실제 게임 시스템과 정상적으로 연결되는지를 확인하는 것이었다.

덕분에 HUD는 필요한 정보를 표시하는 기능 자체는 갖추고 있었지만, 아직 『ERROR-CODE-H』의 어두운 SF 세계관이나 사이버펑크 분위기를 충분히 보여주지는 못하고 있었다.

3주차에는 기존 기능 구조를 유지하면서 시각적인 방향을 다음과 같이 변경했다.

  • 직선적이고 기계적인 프레임 사용
  • 어두운 배경에서 눈에 띄는 높은 색상 대비
  • 일반 상태와 위험 상태의 명확한 색상 구분
  • 숫자와 상태 정보가 시스템 메시지처럼 보이는 형태
  • 기본 폰트를 픽셀 스타일 폰트로 교체
  • HP, Heat, Core, Skill UI의 시각적 언어 통일

즉, 기존 코드를 전부 새로 만드는 것이 아니라 이미 구현되어 있는 데이터 연결 구조는 유지하고, 그 위의 이미지·폰트·색상·상태 연출을 교체하는 방식으로 작업했다.

[캡처 1 삽입 — 2주차 HUD와 3주차 HUD 비교]

기능 중심으로 구성했던 기존 HUD를 사이버펑크 분위기에 맞게 리메이크했다. Heat 프레임과 Fill, 픽셀 폰트, Skill UI 등을 추가해 게임 전체의 분위기와 HUD의 시각적 방향을 맞추었다.

Heat 게이지 디자인 리메이크

이번 주 작업에서 가장 많은 비중을 차지한 것은 Heat 게이지의 리메이크였다.

Heat는 플레이어의 공격과 Core 전환에 영향을 받는 핵심 전투 자원이다.

따라서 단순히 현재 수치를 보여주는 것뿐 아니라, Heat가 위험한 수준까지 올라갔을 때 플레이어가 숫자를 직접 읽지 않아도 이를 바로 알아차릴 수 있어야 했다.

이를 위해 Heat UI는 크게 세 가지 상태를 구분하도록 구성했다.

  • 일반 Heat 상태
  • High Heat 상태
  • OverHeat 상태

각 상태를 판단하기 위한 기본 기준값은 UIManager에서 설정했다.

1
2
3
4
[Header("UI Conditions")]
[SerializeField] private float lowHPThreshold = 0.2f;
[SerializeField] private float highHeatThreshold = 0.8f;
[SerializeField] private float overHeatThreshold = 0.999f;

현재 Heat가 최대 Heat의 80% 이상이면 High Heat, 거의 100%에 도달하면 OverHeat 상태로 판단한다.

Heat 값이 변경될 때마다 현재 비율을 계산하고, 그 결과를 HeatDrawer에 전달하도록 했다.

1
2
3
4
5
6
7
8
9
10
11
private void HandleHeatChanged(float currentHeat, float maxHeat)
{
    bool isHighHeat =
        currentHeat / maxHeat >= highHeatThreshold;

    bool isOverHeat =
        currentHeat / maxHeat >= overHeatThreshold;

    _heatDrawer.SetHeat(currentHeat, isHighHeat);
    _heatDrawer.SetOverHeat(isOverHeat);
}

현재 Heat 수치와 High Heat 여부, OverHeat 여부를 각각 전달함으로써, 게이지의 채움 정도와 위험 상태의 시각 연출을 서로 분리해서 처리할 수 있도록 구성했다.

[캡처 2 삽입 — Normal, High Heat, OverHeat 상태 비교]

Heat 상태에 따라 HUD의 색상과 연출이 달라진다. 기본 상태에서는 일반 색상을 사용하고, Heat가 80% 이상이면 경고 색상으로 전환된다. OverHeat 상태에서는 점멸 효과를 추가해 위험 상태를 더욱 강조했다.

Heat 게이지 전용 Shader Graph 제작

기존 Heat 게이지는 Unity UI 이미지의 fillAmount를 이용해 단순하게 채움 정도를 표현했다.

하지만 새롭게 디자인한 Heat 게이지는 기울어진 프레임과 Fill 이미지를 사용했기 때문에, 기존의 단순한 이미지 채움 방식으로는 원하는 형태를 만들기 어려웠다.

그래서 Heat 게이지 전용 HeatBarShader.shadergraphHeatBarMaterial을 새롭게 제작했다.

전용 셰이더에서는 다음과 같은 값을 사용했다.

  • _MainTex: Heat Fill 이미지
  • _Fill: 현재 Heat의 채움 비율
  • _Skew: 게이지의 기울기 조정
  • _Softness: Fill 경계의 부드러움 조정

Heat UI에서 사용하는 머티리얼은 각 UI 인스턴스가 독립적인 값을 사용할 수 있도록 복제해서 사용했다.

1
2
3
4
5
6
7
8
9
10
private Material materialInstance;

private void Awake()
{
    if (heatFill == null)
        return;

    materialInstance = Instantiate(heatFill.material);
    heatFill.material = materialInstance;
}

공유 머티리얼의 _Fill 값을 직접 수정하면 같은 머티리얼을 사용하는 다른 UI까지 동시에 영향을 받을 수 있다.

이를 방지하기 위해 Instantiate()를 이용해 별도의 머티리얼 인스턴스를 생성하고, 현재 Heat UI에서만 해당 값을 변경하도록 했다.

현재 Heat 값은 셰이더의 _Fill 속성으로 전달했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void SetHeat(float current, bool isHighHeat)
{
    current = Mathf.Clamp(current, 0f, 100f);

    if (materialInstance != null)
        materialInstance.SetFloat(
            "_Fill",
            current / 100f
        );

    if (!isOverHeat)
    {
        heatFill.color =
            isHighHeat ? warningColor : normalColor;
    }

    if (heatText != null)
        heatText.text = $"HEAT_{current:0}%";
}

Heat 값은 0~100 사이로 제한한 뒤, 100으로 나누어 셰이더에서 사용할 수 있는 0~1 범위의 값으로 변환했다.

텍스트도 기존의 단순한 50% 표기에서 HEAT_50% 형식으로 변경했다.

이는 HUD가 일반적인 상태창보다는 게임 세계 안의 시스템 인터페이스처럼 보이도록 하기 위한 디자인 선택이었다.

High Heat 상태에서는 Fill의 색상을 일반 색상에서 경고 색상으로 바꾸었다.

다만 OverHeat 상태에서는 별도의 점멸 코루틴이 색상을 제어하기 때문에, SetHeat()에서 해당 색상을 다시 덮어쓰지 않도록 isOverHeat 조건을 추가했다.

[캡처 3 삽입 — HeatBar Shader Graph와 실제 적용 화면]

기울어진 Heat 게이지 디자인에 맞춰 전용 Shader Graph를 제작했다. 코드에서 현재 Heat 비율을 _Fill 값으로 전달해 게이지가 실시간으로 채워지도록 구성했다.

High Heat와 OverHeat 시각 효과

High Heat 상태에서는 게이지가 경고 색상으로 변화하고, OverHeat 상태에서는 Heat Fill이 반복적으로 점멸하도록 만들었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void SetOverHeat(bool active)
{
    if (isOverHeat == active)
        return;

    isOverHeat = active;

    if (active)
    {
        blinkRoutine =
            StartCoroutine(OverHeatBlink());
    }
    else
    {
        if (blinkRoutine != null)
        {
            StopCoroutine(blinkRoutine);
            blinkRoutine = null;
        }

        heatFill.color = normalColor;
    }
}

이미 OverHeat 상태라면 동일한 코루틴이 다시 실행되지 않도록 현재 상태를 먼저 비교했다.

OverHeat 상태에서 벗어나면 실행 중인 점멸 코루틴을 중지하고, Heat Fill의 색상을 다시 기본 상태로 돌려놓았다.

점멸 패턴은 2주차에 구현했던 Low HP 경고와 비슷하게, 짧은 점멸과 대기 시간을 조합하는 형태로 만들었다.

1
2
3
4
5
6
7
8
9
10
11
IEnumerator OverHeatBlink()
{
    while (true)
    {
        yield return Blink(0.16f);
        yield return new WaitForSeconds(0.6f);

        yield return Blink(0.16f);
        yield return new WaitForSeconds(0.16f);
    }
}

이렇게 일반 Heat, High Heat, OverHeat를 각각 시각적으로 구분함으로써, 플레이어가 Heat 숫자를 계속 확인하지 않아도 현재 위험도가 어느 정도인지 색상과 점멸만으로 파악할 수 있도록 만들었다.

HP 배경 이미지와 폰트 개선

HP UI는 전체 구조를 새롭게 만드는 대신, 2주차에 구현해둔 HP Bar와 HP 감소 파티클 구조를 유지하면서 가독성을 개선하는 방향으로 작업했다.

기존 HP 배경 이미지를 수정해 HP Fill과 텍스트가 보다 잘 보이도록 만들었고, 기본 폰트를 픽셀 스타일의 PixelOperatorSC-Bold로 교체했다.

폰트 변경은 HP UI만을 위한 작업이 아니라, HUD 전체의 시각적인 인상을 통일하기 위한 작업이었다.

  • HP 수치
  • Heat 수치
  • Core 이름
  • Skill 키 표시
  • 사망 화면 텍스트

이러한 텍스트 요소에 동일한 픽셀 스타일을 적용하여, HUD가 게임 화면 위에 별도로 얹힌 일반적인 UI처럼 보이지 않고 『ERROR-CODE-H』 세계관 속의 기계식 인터페이스처럼 느껴지도록 했다.

다만 HP와 Core UI 전체를 완전히 새로 디자인하는 작업은 예상보다 작업량이 많았다.

따라서 이번 주에는 배경과 폰트, 전체 HUD 배치를 먼저 개선하고, 세부적인 리메이크는 이후 작업으로 남겨두었다.

[캡처 4 삽입 — HP 배경과 픽셀 폰트 적용 전후]

HP 바의 배경 이미지를 수정하고 HUD 폰트를 픽셀 스타일로 교체했다. 어두운 인게임 배경에서도 HP 수치와 게이지가 잘 구분되도록 가독성을 보완했다.

Core 옆에 Skill UI 추가

이번 주에는 기존 Core UI 옆에 현재 사용할 수 있는 Skill을 표시하는 기능도 추가했다.

HUD 프리팹 안에 Skill_UI 그룹을 만들고, 세 개의 Skill 슬롯을 배치했다.

각 슬롯은 다음 요소를 가지고 있다.

  • Skill 키 또는 이름을 표시하는 텍스트
  • Skill 아이콘 이미지

초기 SkillDrawer에는 세 개의 슬롯을 표시하기 위한 참조만 준비했다.

1
2
3
4
5
6
7
8
9
[System.Serializable]
public class SkillSlotUI
{
    public TMP_Text skillText;
    public Image skillImage;
}

[SerializeField]
private SkillSlotUI[] skillSlots;

처음 Skill UI를 추가했을 당시에는 실제 스킬 관련 플레이어 코드가 아직 완성되지 않은 상태였기 때문에, 실제 사용 이벤트와 바로 연결할 수는 없었다.

당시 작업 기록에도 다음과 같이 남겼다.

스킬 아이콘과 스킬 관련 베이스 코드를 추가했습니다. 아직 작동하지 않으며, 스킬 관련 플레이어 코드가 완성되면 그 후에 연결하겠습니다.

따라서 7월 23일의 첫 구현에서는 아이콘, 슬롯, 기본적인 UI 구조부터 먼저 제작했다.

이후 Skill 시스템에서 사용할 수 있는 데이터와 이벤트가 준비되면 실제 동작을 연결하는 방식으로 작업을 나눈 것이다.

Sword Core Skill과 UI 연결

7월 23일 오후에는 팀원이 Sword Core의 두 가지 Skill을 추가했다.

  • UpperSlash
  • DashSlash

이제 실제 Skill 사용을 UI에 전달할 수 있었기 때문에, SwordCoreSkill에 Skill 종류와 이벤트를 추가했다.

1
2
3
4
5
6
7
public enum SkillType
{
    UpperSlash,
    DashSlash
}

public event Action<SkillType> OnSkillUsed;

각 Skill이 실제로 시작되는 시점에 OnSkillUsed 이벤트가 발생하도록 구성했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void TryStartUpperSlash()
{
    if (CanStartUpperSlash())
    {
        upperSlashReadyTime =
            Time.time + upperSlashCooldown;

        heatManager?.AddHeat(upperSlashHeat);

        OnSkillUsed?.Invoke(
            SkillType.UpperSlash
        );

        StartCoroutine(UpperSlashRoutine());
    }
}

DashSlash에도 동일한 방식으로 이벤트를 추가했다.

여기서 중요한 점은 Skill 키가 단순히 입력되었을 때 이벤트가 발생하는 것이 아니라, 쿨타임 등의 실행 조건을 통과하고 실제 Skill이 시작되는 시점에 이벤트가 발생한다는 점이었다.

따라서 Skill이 실제로 실행되지 않았다면 UI 효과 역시 발생하지 않는다.

팀원이 담당하던 Skill 스크립트를 수정한 부분에는 UI 연결을 위해 추가한 코드라는 주석을 남겼고, 디스코드에도 어떤 파일을 수정했는지 따로 공유했다.

SkillRefManager로 게임 로직과 UI 사이 연결하기

Sword Core의 SkillType을 UI에서 그대로 사용하면, UI가 특정 Core의 내부 구현 구조에 직접 의존하게 된다.

이를 조금이라도 줄이기 위해 SkillRefManager라는 중간 연결 클래스를 만들었다.

1
2
3
4
5
6
7
8
public enum SkillType
{
    Skill1,
    Skill2,
    Skill3
}

public event Action<SkillType> OnSkillUsed;

SkillRefManager는 Sword Core에서 발생한 Skill 이벤트를 받아, HUD가 사용하는 공통 Skill 슬롯 번호로 변환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private void HandleSkillUsed(
    SwordCoreSkill.SkillType skill
)
{
    switch (skill)
    {
        case SwordCoreSkill.SkillType.UpperSlash:
            OnSkillUsed?.Invoke(
                SkillType.Skill1
            );
            break;

        case SwordCoreSkill.SkillType.DashSlash:
            OnSkillUsed?.Invoke(
                SkillType.Skill2
            );
            break;
    }
}

게임 로직의 UpperSlash는 UI의 첫 번째 슬롯으로, DashSlash는 두 번째 슬롯으로 변환했다.

전체 흐름을 정리하면 다음과 같다.

Sword Core Skill 실행SwordCoreSkill.OnSkillUsed 발생SkillRefManager가 Skill 종류 수신UI용 Skill1 또는 Skill2로 변환SkillRefManager.OnSkillUsed 발생UIManager가 이벤트 수신SkillDrawer에서 해당 아이콘 애니메이션 실행

UIManagerSkillRefManager의 이벤트를 구독하도록 했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void OnEnable()
{
    if (_skillRefManager != null)
    {
        _skillRefManager.OnSkillUsed
            += HandleSkillUsed;
    }
}

private void OnDisable()
{
    if (_skillRefManager != null)
    {
        _skillRefManager.OnSkillUsed
            -= HandleSkillUsed;
    }
}

Skill 이벤트를 받으면 해당 슬롯 정보를 SkillDrawer로 전달한다.

1
2
3
4
5
6
private void HandleSkillUsed(
    SkillRefManager.SkillType skill
)
{
    _skillDrawer.SetSkill(skill);
}

이를 통해 실제 공격 로직과 UI 애니메이션을 직접 연결하지 않고, 중간 계층을 통해 서로 분리할 수 있었다.

Skill 사용 시 아이콘 확대 효과

Skill 입력이 실제로 처리되었는지를 플레이어가 즉시 확인할 수 있도록, Skill을 사용하면 해당 아이콘이 잠시 커졌다가 원래 크기로 돌아오는 효과를 추가했다.

1
2
3
4
5
[SerializeField]
private float popScale = 1.2f;

[SerializeField]
private float popDuration = 0.1f;

기본 설정에서는 Skill 아이콘이 원래 크기의 1.2배까지 확대되고, 0.1초 동안 커진 뒤 다시 0.1초 동안 원래 크기로 돌아온다.

Skill 종류를 배열 인덱스로 변환한 뒤, 해당하는 아이콘을 찾아 애니메이션을 실행했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void SetSkill(
    SkillRefManager.SkillType skill
)
{
    int index = (int)skill;
    Image image = skillSlots[index].skillImage;

    if (image == null)
        return;

    StartCoroutine(
        PopSkillIcon(image)
    );
}

실제 확대와 축소는 코루틴과 Vector3.Lerp()를 이용했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
private IEnumerator PopSkillIcon(Image image)
{
    RectTransform rect = image.rectTransform;

    Vector3 originalScale = rect.localScale;
    Vector3 targetScale =
        originalScale * popScale;

    float time = 0f;

    while (time < popDuration)
    {
        time += Time.deltaTime;

        rect.localScale = Vector3.Lerp(
            originalScale,
            targetScale,
            time / popDuration
        );

        yield return null;
    }

    time = 0f;

    while (time < popDuration)
    {
        time += Time.deltaTime;

        rect.localScale = Vector3.Lerp(
            targetScale,
            originalScale,
            time / popDuration
        );

        yield return null;
    }

    rect.localScale = originalScale;
}

Skill을 사용하면 해당 아이콘이 빠르게 확대되었다가 다시 원래 크기로 돌아온다.

이를 통해 별도의 텍스트 메시지를 띄우지 않더라도, Skill 입력이 실제로 처리되었다는 사실을 HUD에서 바로 확인할 수 있게 했다.

[캡처 5 삽입 — Skill 사용 전과 아이콘 확대 순간 비교]

Sword Core Skill을 사용하면 해당 Skill 아이콘이 잠시 1.2배로 확대된 뒤 원래 크기로 돌아온다. Skill 입력이 실제로 처리되었다는 사실을 HUD에서 확인할 수 있도록 시각적 피드백을 추가했다.

이 기능을 정상적으로 확인하려면 Test_PlayerController 씬에서 Canvas - SkillRefManager의 Sword Core Skill 참조를 연결해야 했다.

당시 디스코드에도 다음과 같이 공유했다.

Skill 사용 시 해당하는 Skill 아이콘이 잠시 커졌다 작아지는 효과를 구현했습니다. 작동 확인을 위해서는 Test_PlayerController Scene에서 Canvas - SkillRefManager에 Sword Core Skill을 연결해 줘야 합니다.

아직 연결하지 못한 Skill 기능

3주차에 구현한 Skill UI는 Sword Core의 Skill 사용 이벤트를 HUD에 표시하는 단계까지 완성했다.

하지만 당시의 시스템 구조에서는 아직 필요한 데이터나 이벤트를 가져올 수 없었던 기능들이 있었다.

  • Skill 쿨타임 표시
  • Skill 아이콘 자동 로딩
  • Skill 사용 가능 여부 표시
  • 다른 Core의 Skill 이벤트 연결
  • 현재 Core에 따른 Skill 슬롯 교체
  • 세 번째 Skill의 실제 연결

당시 기록에도 다음과 같이 남겼다.

쿨타임이나 Skill 아이콘 자체는 현재 코드에서 불러오는 방법이 없어서 약간의 수정이 더 필요할 수도 있을 것 같습니다. 해당 부분은 다른 Core 쪽 스크립트가 완성되면 진행하겠습니다.

SkillRefManager 역시 Sword Core의 참조만 실제로 구현되어 있었고, Core 2와 Core 3의 참조 영역은 주석 상태로 남아 있었다.

1
2
3
4
5
6
[Header("Core 1 Skill References")]
[SerializeField]
private SwordCoreSkill _swordCoreSkill;

//[Header("Core 2 Skill References")]
//[Header("Core 3 Skill References")]

따라서 3주차의 결과를 “전체 Core의 Skill UI를 완성했다”고 표현하는 것은 정확하지 않다.

이번 주에 완료한 범위는 다음과 같다.

완료

  • Skill UI 슬롯 및 아이콘 배치
  • Sword Core Skill 이벤트 연결
  • UpperSlash와 첫 번째 Skill 슬롯 연결
  • DashSlash와 두 번째 Skill 슬롯 연결
  • Skill 사용 시 해당 아이콘 확대 효과

후속 작업

  • 다른 Core의 Skill UI 연결
  • Skill 쿨타임 표시
  • Core별 Skill 아이콘 자동 교체
  • 세 번째 Skill 연결

현재 시스템에서 사용할 수 있는 부분까지만 구현하고, 아직 데이터가 준비되지 않은 기능은 임의로 가정하지 않고 남겨두었다.

플레이어 사망 연출 구현

2주차에는 사망 UI에 사용할 에셋이 아직 제작 중이었기 때문에 사망 연출을 후속 작업으로 남겨두었다.

3주차에는 DeathDrawer를 새롭게 추가하고, 플레이어가 사망했을 때 기존 HUD를 숨긴 뒤 별도의 사망 화면을 보여주는 연출을 구현했다.

HP 변경 이벤트를 처리하면서 PlayerHealth.IsDead를 확인하고, 사망 상태라면 사망 UI를 실행하도록 했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private void HandleHPChanged(
    int currentHP,
    int maxHP
)
{
    _hpDrawer.SetHP(currentHP, maxHP);

    bool isLowHP =
        (float)currentHP / maxHP
        <= lowHPThreshold;

    _hpDrawer.SetLowHP(isLowHP);

    if (_playerHealth.IsDead &&
        _deathDrawer != null)
    {
        _deathDrawer.ShowDeathUI();
    }
}

사망 UI가 시작되면 기존 HUD를 먼저 숨기고, 반투명한 배경을 활성화한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void ShowDeathUI()
{
    if (_hud != null)
        _hud.SetActive(false);

    if (_deathBackground != null)
    {
        _background.color =
            new Color(
                69 / 255f,
                69 / 255f,
                69 / 255f,
                0f
            );

        _deathBackground.SetActive(true);
        StartCoroutine(FadeIn());
    }
}

처음에는 배경의 알파값을 0으로 두고, 0.5초 동안 점차 불투명해지도록 만들었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private IEnumerator FadeIn()
{
    Color start =
        new Color(
            69 / 255f,
            69 / 255f,
            69 / 255f,
            0f
        );

    Color end =
        new Color(
            69 / 255f,
            69 / 255f,
            69 / 255f,
            186 / 255f
        );

    float duration = 0.5f;
    float t = 0f;

    while (t < duration)
    {
        t += Time.deltaTime;

        _background.color =
            Color.Lerp(
                start,
                end,
                t / duration
            );

        yield return null;
    }

    _background.color = end;
    _deathTextGroup.SetActive(true);

    yield return StartCoroutine(
        ErrorCodeAnimation()
    );
}

배경이 나타난 뒤에는 ERROR CODE 뒤에 붙는 알파벳이 빠르게 바뀌는 글리치 연출을 재생한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for (int i = 0; i < 20; i++)
{
    char c =
        (char)Random.Range('A', 'Z' + 1);

    _deathMainText.text =
        $"ERROR CODE: {c}";

    yield return
        new WaitForSeconds(0.03f);
}

yield return new WaitForSeconds(0.5f);

_deathMainText.color = Color.red;
_deathMainText.text = "ERROR CODE: H";

무작위 알파벳을 20번 빠르게 표시한 뒤, 마지막에는 붉은색 ERROR CODE: H가 나타나도록 했다.

그 아래에는 미리 준비한 다섯 문장 가운데 하나를 무작위로 표시하도록 구성해, 플레이어가 사망할 때마다 완전히 같은 문장만 반복해서 보이지 않도록 했다.

전체적인 사망 연출의 흐름은 다음과 같다.

플레이어 HP가 0이 됨PlayerHealth.IsDead 확인기존 HUD 숨김어두운 배경 Fade InERROR CODE 알파벳 글리치붉은색 ERROR CODE: H 표시무작위 서브 텍스트 표시

[캡처 6 삽입 — 사망 연출 진행 단계]

플레이어가 사망하면 기존 HUD가 사라지고 어두운 배경이 나타난다. 무작위 알파벳이 빠르게 바뀐 뒤 최종적으로 붉은색 ERROR CODE: H와 서브 텍스트가 표시된다.

단순한 GAME OVER 문구를 띄우기보다, 프로젝트 이름인 『ERROR-CODE-H』 자체를 사망 연출의 일부로 사용해 게임의 분위기와 연결하고자 했다.

HUD 프리팹 위치 정리

3주차에는 다른 팀원이 UI 프리팹을 보다 쉽게 찾아 사용할 수 있도록 HUD 프리팹의 위치도 정리했다.

기존 경로는 다음과 같았다.

Assets/jhkim/UITest/HUD.prefab

이를 다음 경로로 이동했다.

Assets/jhkim/HUD.prefab

테스트용 폴더 안에 있던 프리팹을 Assets/jhkim 폴더 바로 아래로 옮겨, 필요한 씬에서 비교적 쉽게 찾아 사용할 수 있도록 했다.

당시 디스코드에도 다음과 같이 공유했다.

UI용 Prefab을 Assets/jhkim 폴더 바로 안에 넣어두었습니다. 필요한 경우 바로 사용 가능합니다.

초기 UI 테스트를 위한 임시 구조와 실제 프로젝트에서 재사용할 HUD 프리팹의 위치를 구분하고, 팀원이 찾기 쉬운 경로로 정리한 작업이다.

[캡처 7 삽입 — Project 창의 HUD.prefab 위치와 HUD Hierarchy]

테스트 폴더 안에 있던 HUD 프리팹을 Assets/jhkim 폴더 바로 아래로 이동했다. 팀원이 다른 씬에서도 HUD를 쉽게 찾아 사용할 수 있도록 경로를 정리했다.

GitHub 작업 기록

3주차에 내가 작업한 주요 커밋은 다음과 같다.

ad61f4dSkill Icon 추가, Death 연출 추가, Heat 게이지 및 상태 연출 리메이크

작업일: 2026.07.23 오전 6시 09분

  • Heat 게이지 디자인 리메이크
  • Heat Frame 및 Fill 이미지 추가
  • Heat 전용 Shader Graph 제작
  • Heat 전용 Material 제작
  • High Heat 색상 변화 추가
  • OverHeat 점멸 효과 추가
  • 픽셀 스타일 폰트 추가
  • HP 배경 이미지 가독성 개선
  • Skill UI와 세 개의 Skill 슬롯 추가
  • SkillDrawer 기본 구조 추가
  • DeathDrawer 추가
  • 플레이어 사망 시 HUD 숨김
  • 사망 화면 Fade In 구현
  • ERROR CODE: H 글리치 연출 구현
  • HUD 프리팹 구조 수정

스킬 시스템 관련 팀 커밋

작업일: 2026.07.23 오후

다른 팀원이 Sword Core의 두 가지 Skill을 구현했다.

  • d34d345코어1 스킬 2개 생성
  • d9622a2 — Sword Core Skill 작업 병합

해당 기능이 프로젝트에 추가된 뒤 Skill UI 이벤트를 실제 스킬 사용과 연결할 수 있었다.

8bbd827Refactor UI system

작업일: 2026.07.24 오전 1시 25분

  • SkillDrawer 구조 개선
  • SkillRefManager 추가
  • Sword Core Skill 이벤트 연결
  • Skill 사용 시 해당 아이콘 확대 효과 구현
  • UIManager와 Skill 이벤트 연결
  • SwordCoreSkill에 UI용 이벤트 추가
  • HUD 프리팹 구조 정리
  • HUD 프리팹을 Assets/jhkim/HUD.prefab으로 이동
  • Death UI 일부 구조 정리

15ab621 — UI 시스템 작업 병합

작업일: 2026.07.24 오전 1시 27분

  • UI 리팩터링 브랜치를 메인 작업 흐름에 병합

3주차 작업 흐름 정리

이번 주의 작업 흐름을 정리하면 다음과 같다.

  1. 기존 HP·Heat·Core HUD의 디자인 방향을 다시 검토했다.
  2. 사이버펑크 분위기에 맞는 Heat Frame과 Fill 이미지를 제작했다.
  3. Heat 게이지 전용 Shader Graph와 Material을 만들었다.
  4. Heat 수치를 Shader의 _Fill 값과 연결했다.
  5. High Heat와 OverHeat의 시각적인 상태를 분리했다.
  6. OverHeat 상태에 점멸 효과를 추가했다.
  7. HP 배경 이미지의 가독성을 보완했다.
  8. HUD 전체에 사용할 픽셀 스타일 폰트를 추가했다.
  9. Core 옆에 세 개의 Skill 슬롯을 배치했다.
  10. Skill 시스템이 완성되기 전에 UI의 기본 구조부터 먼저 제작했다.
  11. Sword Core Skill이 추가된 뒤 Skill 사용 이벤트를 연결했다.
  12. Skill 사용 시 해당 아이콘이 확대되었다가 복귀하도록 했다.
  13. 플레이어 사망 시 실행되는 Fade In 및 글리치 연출을 구현했다.
  14. HUD 프리팹을 팀원이 찾기 쉬운 경로로 이동했다.
  15. 아직 구현하지 못한 Skill 쿨타임과 다른 Core 연동 항목을 팀에 공유했다.

이번 주에도 모든 시스템이 완성된 뒤 UI를 만드는 방식으로 진행하지는 않았다.

먼저 독립적으로 만들 수 있는 UI와 연출을 제작하고, 다른 시스템이 추가되면 이벤트를 연결하는 방식으로 개발을 이어갔다.

3주차 결과

3주차에는 기능 위주였던 HUD를 『ERROR-CODE-H』의 분위기에 어울리는 인터페이스로 발전시켰다.

완료한 항목은 다음과 같다.

  • Heat 게이지 사이버펑크 디자인 리메이크
  • Heat Frame 및 Fill 리소스 제작
  • Heat 게이지 전용 Shader Graph 적용
  • Heat 비율과 Shader _Fill 값 연동
  • High Heat 경고 색상
  • OverHeat 점멸 효과
  • HP 배경 이미지 가독성 개선
  • HUD 픽셀 폰트 적용
  • Core 옆 Skill 슬롯과 아이콘 추가
  • Sword Core의 두 Skill과 UI 연결
  • Skill 사용 시 아이콘 확대·축소 효과
  • 플레이어 사망 시 기존 HUD 숨김
  • 사망 화면 Fade In
  • ERROR CODE: H 글리치 연출
  • 사망 화면 무작위 서브 텍스트
  • HUD 프리팹 위치 및 구조 정리

반면 이번 주에 부분적으로만 진행했거나, 후속 작업으로 남긴 항목은 다음과 같다.

  • HP UI 전체 디자인 리메이크
  • Core UI 전체 디자인 리메이크
  • 다른 Core의 Skill 이벤트 연결
  • Core별 Skill 아이콘 자동 변경
  • Skill 쿨타임 표시
  • 세 번째 Skill 연결

3주차를 마치며

3주차에는 이전 주차보다 UI의 기능뿐 아니라 게임의 분위기와 플레이어가 느끼는 피드백까지 함께 고려하는 작업이 많았다.

Heat 게이지에는 전용 Shader Graph를 적용하고, Heat 상태를 일반·High Heat·OverHeat로 나누었다.

플레이어가 숫자를 계속 확인하지 않아도, 색상과 점멸만으로 현재 Heat가 위험한 수준에 도달했는지를 인식할 수 있도록 만들고자 했다.

Skill UI 역시 처음부터 완성된 시스템에 연결한 것은 아니었다.

먼저 아이콘과 슬롯을 제작한 뒤, 팀원이 Sword Core Skill을 구현하자 이벤트를 추가해 실제 Skill 사용과 연결했다. 아직 모든 Core와 쿨타임 정보를 표시할 수 있는 단계는 아니었지만, 적어도 Skill을 실제로 사용했을 때 HUD가 반응하는 기본 구조는 만들 수 있었다.

2주차에 미뤄두었던 사망 연출도 이번 주에 구현했다.

기존 HUD를 숨기고 화면을 어둡게 만든 뒤, 무작위 알파벳이 빠르게 바뀌다가 최종적으로 ERROR CODE: H로 수렴하는 글리치 연출을 추가했다.

단순히 게임오버 문구 하나를 띄우는 것이 아니라, 프로젝트 제목과 세계관을 사망 화면에도 녹여내고 싶었다.

또한 이번 주에는 UI 담당자가 다른 시스템의 개발 상황에 맞추어 작업 순서를 조정하는 경험도 계속 이어졌다.

Skill 시스템이 아직 없을 때는 UI 슬롯과 디자인부터 먼저 제작했고, 시스템이 추가된 뒤 이벤트를 연결했다. 반대로 쿨타임이나 다른 Core Skill처럼 아직 필요한 정보가 제공되지 않는 부분은 무리하게 구현하지 않고 후속 작업으로 남겨두었다.

1주차에는 시스템의 정보를 화면에 표시하는 구조를 만들었고, 2주차에는 피해와 위험 상태에 대한 피드백을 추가했다.

그리고 3주차에는 그 위에 『ERROR-CODE-H』만의 분위기와 연출을 조금씩 입히기 시작했다.

기능과 디자인, 애니메이션, 그리고 다른 팀원이 만든 시스템과의 연결을 함께 다루면서, HUD는 단순한 정보 표시창이 아니라 게임의 분위기와 조작 피드백을 전달하는 또 하나의 게임 요소라는 점을 조금씩 체감할 수 있었다.

この投稿は投稿者によって CC BY 4.0 の下でライセンスされています。