Unity——來個可變角度的扇形技能指示器

技能指示器

如果你的游戲有戰(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

從左到右分別是純色版,帶透明度漸變版和實用貼圖版。

下面說說制作步驟:

  1. 創(chuàng)建一個Plane
  2. 創(chuàng)建一個Material
  3. 創(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"
}
  1. 將Shader賦予Material,將Material賦予Plane
  2. Done

簡單吧?

Shader的內容并不復雜,簡單來說就是通過UV坐標進行剔除操作。代碼注釋應該也比較清楚了,大家玩玩看吧。本次依然放出示例工程到我的 Github ,歡迎大家圍觀。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容