글에 사용된 모든 셰이더, 예시 UI, 구조는 직접 개발하고 프로젝트에서 구현한 사례입니다.
2D 게임에서 특정 대상(예: 아이템, 적, 미션 목표)을 화면 중앙의 플레이어 기준으로 "어디에 있는지" 알려주는 방향 지시 화살표를*Built-in Render Pipeline에서도 PostProcessing 없이** 셰이더만으로 구현한 방향 지시 UI를 정리하기 위함.
Transform.LookAt
또는 벡터 연산으로 타겟 방향 계산MaterialPropertyBlock
으로 셰이더에 전달해 방향 회전Shader "Sprites/DetectCircleWithArrow"
{
/*
* 여기서 원 반지름의 크기, 화살표의 크기 등을 설정가능하게 노출
*/
Properties
{
_MainTex("Sprite Texture", 2D) = "white" {}
_Color("Color", Color) = (1, 0, 0, 1)
_Radius("Radius", Float) = 0.4
_Thickness("Thickness", Float) = 0.05
_ArrowAngle("Arrow Angle (Deg)", Range(0,360)) = 0
_ArrowSize("Arrow Size", Float) = 0.08
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
LOD 100
Cull Off
Lighting Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// 생략: vert, CenteredUV, arrowShape 등
fixed4 frag(v2f i) : SV_Target
{
float2 uv = CenteredUV(i.uv);
float len = length(uv);
float ring = smoothstep(_Radius, _Radius - _Thickness, len)
* (1.0 - smoothstep(_Radius + _Thickness, _Radius, len));
float rad = radians(_ArrowAngle);
float2 dir = float2(cos(rad), sin(rad));
float arrow = arrowShape(uv, dir, _ArrowSize);
float alpha = max(ring, arrow);
return fixed4(_Color.rgb, _Color.a * alpha);
}
ENDCG
}
}
}
void TowardObject(GameObject obj)
{
detectCircleObj.SetActive(true);
Vector3 dir = (obj.transform.position - transform.position).normalized;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
detectCircleObj.transform.rotation = Quaternion.Euler(0, 0, angle);
}
ArrowSize
와 _Thickness
를 애니메이션 매개변수로 연동하면, 거리나 중요도에 따라 강조 UI로 연출도 가능Unity에서 URP나 별도 플러그인 없이도 충분히 실용적인 방향지시 UI를 만들 수 있습니다. 비용 효율적인 셰이더 구조를 기반으로 하여, 다양한 장르의 2D 게임에서도 가볍고 유연하게 활용할 수 있습니다.