스킬 장판 시각화: 보스 광역 패턴 지면 표시 가이드선 셰이더
보스의 광역 공격을 예고하는 스킬 장판을 지면에 안정적으로 표시하는 방법을 정리합니다. 원형 범위, 진행도 링, 방향 가이드선, 지형 대응과 성능 점검까지 셰이더 중심으로 살펴봅니다.

스킬 장판은 정보 전달 장치다
보스의 광역 공격을 피할 수 있으려면 플레이어가 공격 범위와 발동 시점을 빠르게 읽어야 한다. 스킬 장판은 단순히 바닥을 칠하는 효과가 아니라 위험 영역과 남은 시간을 전달하는 게임플레이 UI에 가깝다.
특히 카메라 각도가 자주 바뀌는 3D 게임에서는 캐릭터 발밑의 원형 범위만으로 방향성과 진행 상황을 충분히 알리기 어렵다. 이 글에서는 지면에 투영하는 메시에 원형 마스크, 진행도 링, 방향 가이드선을 조합하는 방식을 다룬다.
구성 요소와 좌표계
가장 다루기 쉬운 출발점은 스킬 중심에 배치한 얇은 원형 메시다. 메시의 로컬 XZ 평면을 장판 좌표로 사용하고 UV를 0~1 범위로 펼친다. 셰이더에서는 UV 중심을 원점으로 옮긴 뒤 반지름과 각도를 계산한다.
flowchart LR
A[스킬 데이터\n중심·반지름·시간·방향] --> B[장판 메시 Transform]
A --> C[머티리얼 파라미터]
B --> D[정점 단계\n지면 높이 반영]
C --> E[프래그먼트 단계\n원·링·가이드선 합성]
D --> E
E --> F[투명 장판 렌더링]
게임 코드가 매 프레임 넘길 값은 가능한 한 작게 유지하는 편이 좋다. 보통은 지속 시간 대비 진행도인 0~1 값, 반지름, 공격 방향 벡터, 색상 정도면 충분하다. 장판마다 별도 머티리얼을 복제하면 배치 수가 늘어날수록 관리와 드로우콜 측면에서 불리해질 수 있으므로 Unity에서는 MaterialPropertyBlock을 우선 고려할 만하다.

원형 범위와 진행도 링 만들기
UV 중심을 기준으로 한 거리 r은 원형 마스크와 링을 만드는 핵심 값이다. smoothstep을 사용하면 가장자리를 부드럽게 처리할 수 있고 해상도에 따라 경계가 심하게 흔들리는 현상도 줄일 수 있다.
다음은 URP의 커스텀 HLSL 함수나 일반적인 셰이더 코드에 옮겨 쓸 수 있는 핵심 로직이다. 예제는 UV가 장판 전체에 0~1로 매핑되어 있다고 가정한다.
float2 p = input.uv - 0.5;
float r = length(p) * 2.0;
float outerRadius = 1.0;
float edgeSoftness = 0.015;
// 원 내부는 1, 바깥은 0
float area = 1.0 - smoothstep(
outerRadius - edgeSoftness,
outerRadius + edgeSoftness,
r
);
float ringCenter = 0.82;
float ringWidth = 0.035;
float ring = 1.0 - smoothstep(
ringWidth,
ringWidth + edgeSoftness,
abs(r - ringCenter)
);
area는 반투명한 위험 영역에 ring은 외곽선이나 카운트다운 표시에 사용할 수 있다. 원의 외곽을 너무 두껍게 만들면 실제 판정 범위보다 크게 느껴질 수 있다. 반대로 너무 얇으면 카메라가 멀어졌을 때 읽기 어렵다. 공격 판정의 가장자리와 시각적 가장자리가 어느 정도 일치하는지 실제 전투 카메라에서 확인해야 한다.
각도 기반 진행도와 방향 가이드선
진행도 링은 현재 각도와 진행 각도를 비교해 잘라낼 수 있다. atan2의 결과는 보통 음수를 포함하므로 0~1 범위로 정규화한 뒤 사용한다. 시작 방향이 화면 위쪽이 되도록 하려면 각도에 보정값을 더한다.
float PI = 3.14159265;
float angle01 = atan2(p.y, p.x) / (2.0 * PI) + 0.5;
// 12시 방향에서 시작하도록 회전 보정
angle01 = frac(angle01 + 0.25);
float progress = saturate(_Progress);
float progressRing = ring * step(angle01, progress);
이 표현은 시간이 지날수록 링이 차오르는 방식이다. 공격이 임박할수록 남은 안전 시간을 강조하고 싶다면 step(progress, angle01)처럼 반대 영역을 표시하거나 진행도에 따라 색을 바꾸는 편이 직관적이다.
방향성 공격에는 중심에서 목표 방향으로 뻗는 선이 유용하다. 공격 방향을 정규화한 2D 벡터로 전달하고 점과 선 사이의 거리를 구하면 된다. 선분 길이를 제한해야 원 밖까지 선이 불필요하게 이어지지 않는다.
float2 dir = normalize(_DirectionXZ);
float lineLength = 0.92;
float lineHalfWidth = 0.018;
float along = dot(p * 2.0, dir);
float sideways = abs(dot(p * 2.0, float2(-dir.y, dir.x)));
float forwardMask = step(0.0, along) * step(along, lineLength);
float guideLine = forwardMask * (
1.0 - smoothstep(lineHalfWidth, lineHalfWidth + 0.01, sideways)
);
이 선은 부채꼴 공격의 중심축, 돌진 방향, 여러 개의 안전 구역 중 기준 방향을 보여 주는 데 적합하다. 선만으로 피격 영역을 정의하면 오해하기 쉬우므로 부채꼴이나 직사각형 마스크와 함께 사용해야 한다.

최종 색상 합성
마스크를 모두 구한 뒤에는 각 요소의 역할에 맞춰 색과 알파를 합성한다. 위험 영역이 바닥 텍스처를 완전히 덮지 않도록 낮은 알파를 사용하고 외곽선과 가이드선은 대비를 높이는 편이 좋다.
float3 fillColor = _DangerColor.rgb;
float3 lineColor = _GuideColor.rgb;
float fillAlpha = area * _FillOpacity;
float lineMask = saturate(ring + progressRing + guideLine);
float3 color = lerp(fillColor, lineColor, lineMask);
float alpha = max(fillAlpha, lineMask * _LineOpacity);
return float4(color, alpha);
색상만으로 상태를 구분하지 않는 것도 중요하다. 색각 이상이 있는 플레이어에게 빨간색과 초록색의 차이는 충분한 신호가 아닐 수 있다. 위험 단계는 링의 속도, 선의 점멸, 테두리 두께, 패턴의 움직임처럼 색 이외의 변화도 함께 제공하는 편이 안전하다. 다만 빠른 점멸은 피로감을 주거나 광과민성 문제를 유발할 수 있으므로 강도와 빈도를 보수적으로 설정한다.
지형과 겹침 문제
평면 메시를 지형 위에 띄우면 경사진 곳에서 장판이 공중에 뜨거나 땅속으로 파고든다. 해결 방식은 프로젝트의 지형 특성과 장판 수에 따라 선택한다.
- 평탄한 전투장에서는 장판 메시를 지면에서 아주 조금 띄운다. 깊이 충돌을 피하기 쉽고 비용이 낮다.
- 높낮이가 있는 지형에서는 정점 단계에서 아래 방향 레이캐스트 결과를 반영하거나 지형 높이 텍스처를 샘플링해 메시 정점을 변형한다.
- 복잡한 메시 지형에서는 데칼 시스템을 사용할 수 있다. 다만 투영 범위, 깊이 버퍼, 노멀 처리 방식에 따라 벽면까지 표시될 수 있으므로 마스크 조건을 추가해야 한다.
Z-fighting을 피하려고 장판을 지나치게 높이면 캐릭터와 분리되어 보인다. 보통 렌더링 순서와 깊이 설정을 먼저 점검하고 필요한 최소 높이만 오프셋으로 준다. 투명 오브젝트는 정렬 문제가 발생하기 쉬우므로 장판끼리 겹치는 보스전에서는 색상 혼합 규칙도 의도적으로 설계해야 한다.
성능과 검증 체크리스트
장판 셰이더는 화면을 넓게 덮는 투명 효과가 되기 쉽다. 복잡한 노이즈나 다중 텍스처 샘플링보다 먼저 오버드로우를 확인하는 이유다. 특히 여러 보스 패턴이 겹치는 상황과 카메라가 지면에 가까운 상황에서 GPU 프레임 시간을 측정한다.
구현 전 확인할 점
- 게임 판정 반지름과 표시 반지름의 기준을 문서로 고정한다.
- 장판 중심이 이동할 때 공격 방향과 가이드선이 같은 기준 좌표를 사용하는지 확인한다.
- 준비, 발동 직전, 발동, 종료 상태에서 색상과 진행도 규칙이 일관적인지 점검한다.
- 밝은 지면, 어두운 지면, 복잡한 바닥 텍스처에서 모두 경계가 읽히는지 확인한다.
- 여러 장판이 겹쳤을 때 안전 구역과 위험 구역을 오인하지 않는지 플레이 테스트한다.
좋은 장판은 화려한 효과보다 예측 가능성이 먼저다. 원형 마스크와 진행도 링, 방향 가이드선처럼 읽기 쉬운 기본 요소를 정확한 판정 정보와 연결한 뒤 게임의 아트 스타일에 맞는 질감과 애니메이션을 얹는 순서가 유지보수와 접근성 모두에 유리하다.



