
表现:受击是会产生一个受击波纹向四周扩散
shader:
Shader "Unlit/NewUnlitShader"{Properties{_ShieldColor ("Shield Color", Color) = (0.5,0.5,0.5,0)_BaseTex ("Base Texture", 2D) = "white" {}_HitMaskTex ("Hit Mask Tex", 2D) = "white" {}_HitU ("Hit U", Range(0, 1)) = 0.5_HitV ("Hit V", Range(0, 1)) = 0.5_HitOffset ("Hit Offset", Range(0, 2)) = 0.5_HitU2 ("Hit U2", Range(0, 1)) = 0.5_HitV2 ("Hit V2", Range(0, 1)) = 0.5_HitOffset2 ("Hit Offset2", Range(0, 2)) = 0.5}SubShader{Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }Blend SrcAlpha OneCull Off Lighting Off ZWrite OffLOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"fixed4 _ShieldColor;sampler2D _BaseTex;float4 _BaseTex_ST;sampler2D _HitMaskTex;float4 _HitMaskTex_ST;fixed _HitU;fixed _HitV;fixed _HitOffset;fixed _HitU2;fixed _HitV2;fixed _HitOffset2;fixed luminance(fixed3 color) {return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;}struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float4 vertex : SV_POSITION;float2 baseuv : TEXCOORD0;};v2f vert (appdata v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.baseuv = TRANSFORM_TEX(v.uv, _BaseTex);return o;}fixed4 frag (v2f i) : SV_Target{fixed lum = luminance(tex2D(_BaseTex, i.baseuv));fixed3 baseCol = _ShieldColor * lum;fixed dis = distance(fixed2(_HitU, _HitV), i.baseuv);dis = abs(dis - _HitOffset);dis = luminance(tex2D(_HitMaskTex, dis));fixed3 hitCol = _ShieldColor * dis;dis = distance(fixed2(_HitU2, _HitV2), i.baseuv);dis = abs(dis - _HitOffset2);dis = luminance(tex2D(_HitMaskTex, dis));fixed3 hitCol2 = _ShieldColor * dis;return fixed4(baseCol + hitCol + hitCol2, lum);}ENDCG}}}
C#
using UnityEngine;using System.Collections;public class HitShieldTest : MonoBehaviour{Material ShieldMaterial;Vector3 oriPos;Vector3 extents;float hitTime;float hitTime2;void Awake(){ShieldMaterial = GetComponent<MeshRenderer>().material;Collider collider = GetComponent<Collider>();extents = collider.bounds.extents;oriPos = transform.position + extents;ShieldMaterial.SetFloat("_HitOffset", 2);ShieldMaterial.SetFloat("_HitOffset2", 2);hitTime = float.MinValue;hitTime2 = float.MinValue;}// Update is called once per framevoid Update(){if (ShieldMaterial == null){return;}if (Input.GetKeyDown(KeyCode.Mouse0)){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if (Physics.Raycast(ray, out hit)){Vector3 dis = oriPos - hit.point;dis = dis / (2 * extents.x); //方形if (Time.time - hitTime > 0.5f){hitTime = Time.time;ShieldMaterial.SetFloat("_HitU", dis.x);ShieldMaterial.SetFloat("_HitV", dis.y);}else if (Time.time - hitTime2 > 0.5f){hitTime2 = Time.time;ShieldMaterial.SetFloat("_HitU2", dis.x);ShieldMaterial.SetFloat("_HitV2", dis.y);}}}if (Time.time - hitTime <= 2){ShieldMaterial.SetFloat("_HitOffset", Time.time - hitTime);}if (Time.time - hitTime2 <= 2){ShieldMaterial.SetFloat("_HitOffset2", Time.time - hitTime2);}}}
优化一下 支持帧动画,实际表现也不是很好
再优化的话,考虑在程序中吧受击点定位到最相近的格子的中心点,动画的叠加表现就会很好

Shader "Unlit/NewUnlitShader"{Properties{_ShieldColor ("Shield Color", Color) = (0.5,0.5,0.5,0)_BaseTex ("Base Texture", 2D) = "white" {}//圆形用渐变贴图的方式_HitMaskTex ("Hit Mask Tex", 2D) = "white" {}//帧动画的方式_HitAniTex ("Hit Animation Tex", 2D) = "white" {}_HitAniHorAmount ("Horizontal Amount", float) = 1_HitAniVerAmount ("Vertical Amount", float) = 1//受击点信息_HitU ("Hit U", Range(0, 1)) = 0.5_HitV ("Hit V", Range(0, 1)) = 0.5_HitOffset ("Hit Offset", Range(0, 2)) = 0.5_HitU2 ("Hit U2", Range(0, 1)) = 0.5_HitV2 ("Hit V2", Range(0, 1)) = 0.5_HitOffset2 ("Hit Offset2", Range(0, 2)) = 0.5}SubShader{Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }Blend SrcAlpha OneCull Off Lighting Off ZWrite OffLOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"fixed4 _ShieldColor;sampler2D _BaseTex;float4 _BaseTex_ST;sampler2D _HitMaskTex;float4 _HitMaskTex_ST;sampler2D _HitAniTex;float4 _HitAniTex_ST;fixed _HitAniHorAmount;fixed _HitAniVerAmount;fixed _HitU;fixed _HitV;fixed _HitOffset;fixed _HitU2;fixed _HitV2;fixed _HitOffset2;fixed luminance(fixed3 color) {return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;}struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float4 vertex : SV_POSITION;float2 baseuv : TEXCOORD0;};v2f vert (appdata v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.baseuv = TRANSFORM_TEX(v.uv, _BaseTex);return o;}fixed4 frag (v2f i) : SV_Target{fixed lum = luminance(tex2D(_BaseTex, i.baseuv));fixed3 baseCol = _ShieldColor * lum;fixed dis = distance(fixed2(_HitU, _HitV), i.baseuv);dis = abs(dis - _HitOffset);dis = luminance(tex2D(_HitMaskTex, dis));fixed3 hitCol = _ShieldColor * dis;dis = distance(fixed2(_HitU2, _HitV2), i.baseuv);dis = abs(dis - _HitOffset2);dis = luminance(tex2D(_HitMaskTex, dis));fixed3 hitCol2 = _ShieldColor * dis;//return fixed4(baseCol + hitCol + hitCol2, lum);//帧动画受击//单帧的uv值half2 aniuv = i.baseuv + half2(0.5 - _HitU, 0.5 - _HitV);aniuv = 2 * (aniuv - half2(0.5, 0.5)) + half2(0.5, 0.5);aniuv.x = saturate(aniuv.x);aniuv.y = saturate(aniuv.y);//单帧位置(行列)float idx = floor(_Time.y * _HitAniHorAmount * _HitAniVerAmount);idx = idx % (_HitAniHorAmount * _HitAniVerAmount);float row = floor(idx / _HitAniHorAmount);float col = idx - row * _HitAniHorAmount;//转化为全图的uv值aniuv = aniuv + half2(col, _HitAniVerAmount - 1 - row);aniuv.x /= _HitAniHorAmount;aniuv.y /= _HitAniVerAmount;fixed4 aniCol = tex2D(_HitAniTex, aniuv);aniCol.rgb = luminance(aniCol) * _ShieldColor;aniCol.rgb *= aniCol.a;return fixed4(baseCol + aniCol, lum);}ENDCG}}}