技能指示器
如果你的游戲有戰(zhàn)斗系統(tǒng),那極有可能會做成技能系統(tǒng),如果你的游戲有技能系統(tǒng),那極有可能需要提示當前技能的攻擊范圍,以便玩家預判命中或者閃避這次攻擊。
具體的形式如這樣的:

image
這樣的:

image
還有這樣的:

image
矩形(箭頭也算是矩形的)和圓形比較好弄,可以繪制好貼圖用一個面片搞定。大小通過縮放面片實現(xiàn)。麻煩的是扇形。因為技能肯定不單一,扇形的角度就會有變化。不可能每種角度的扇形都做個特效,這樣游戲資源會變多而且策劃不能隨意調整角度。所以,這個時候程序員們就得解決這個問題,讓這樣的范圍指示器自動生成,避免繁重的美術制作。
網(wǎng)絡上常見的方式是生成面片,這種方式的優(yōu)點是頂點高度可以通過地形改變,在有高度的地形中顯示比較自然,缺點是計算復雜,想要產(chǎn)生更平滑的效果需要更多的頂點。網(wǎng)上有不少這種生成面片的文章,大家搜來看看。而我今天要說的這種是通過shader來繪制扇形。
Shader實現(xiàn)版
先來看看最終的效果:

image
從左到右分別是純色版,帶透明度漸變版和實用貼圖版。
下面說說制作步驟:
- 創(chuàng)建一個Plane
- 創(chuàng)建一個Material
- 創(chuàng)建一個Shader,內容如下:
Shader "Custom/Indicator" {
Properties {
_MainTex("Main Texture", 2D) = "white" {}
_Color ("Color", Color) = (0.17,0.36,0.81,0.0)
_Angle ("Angle", Range(0, 360)) = 60
_Gradient ("Gradient", Range(0, 1)) = 0
}
SubShader {
Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }
Pass {
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _Color;
float _Angle;
float _Gradient;
struct fragmentInput {
float4 pos : SV_POSITION;
float2 uv : TEXTCOORD0;
};
fragmentInput vert (appdata_base v)
{
fragmentInput o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
fixed4 frag(fragmentInput i) : SV_Target {
// 離中心點的距離
float distance = sqrt(pow(i.uv.x - 0.5, 2) + pow(i.uv.y - 0.5, 2));
// 在圓外
if(distance > 0.5f){
discard;
}
// 根據(jù)距離計算透明度漸變
float grediant = (1 - distance - 0.5 * _Gradient) / 0.5;
// 正常顯示的結果
fixed4 result = tex2D(_MainTex, i.uv) * _Color * fixed4(1,1,1, grediant);
float x = i.uv.x;
float y = i.uv.y;
float deg2rad = 0.017453; // 角度轉弧度
// 根據(jù)角度剔除掉不需要顯示的部分
// 大于180度
if(_Angle > 180){
if(y > 0.5 && abs(0.5 - y) >= abs(0.5 - x) / tan((180 - _Angle / 2) * deg2rad))
discard;// 剔除
}
else // 180度以內
{
if(y > 0.5 || abs(0.5 -y) < abs(0.5 - x) / tan(_Angle / 2 * deg2rad))
discard;
}
return result;
}
ENDCG
}
}
FallBack "Diffuse"
}
- 將Shader賦予Material,將Material賦予Plane
- Done
簡單吧?
Shader的內容并不復雜,簡單來說就是通過UV坐標進行剔除操作。代碼注釋應該也比較清楚了,大家玩玩看吧。本次依然放出示例工程到我的 Github ,歡迎大家圍觀。