之前做过一个流光效果(http://www.cnblogs.com/jietian331/p/4748644.html)。

现将其改进一下,与NGUI结合起来,提供一个具有流光效果的组件:UIWalkLightSprite。

效果如图:

 NGUI具有流光效果的UISprite

 

首先是此组件的源码,如下:

  1 using System;
  2 using UnityEngine;
  3 
  4 /// <summary>
  5 /// 具有流光效果的 UISprite。
  6 /// 注意:
  7 /// 1. 流光图片需命名为"Special_WalkLight"(待改善)
  8 /// 2. 流光的 UISprite 暂不支持 UIPanel 剪裁(待改善)
  9 /// 3. 设置 UISprite 的 color 将无效
 10 /// </summary>
 11 public class UIWalkLightSprite : UISprite
 12 {
 13     const string WalkLightShaderName = "Bleach/Walk Light Colored";
 14 
 15     float m_duration = 2f;
 16     float m_widthLight2Sprite;
 17     float m_timer;
 18     float m_t1;
 19     bool m_initedMat = true;
 20     Vector2 m_lightURange;
 21 
 22     void Awake()
 23     {
 24         // replace shader
 25         if (base.atlas.spriteMaterial.shader.name != WalkLightShaderName)
 26         {
 27             string tempAtlasName = string.Format("[WalkLightTempAtlas_{0}]", atlas.name);
 28             Transform t = transform.Find(tempAtlasName);
 29             if (t == null)
 30                 t = ((GameObject)GameObject.Instantiate(atlas.gameObject)).transform;
 31 
 32             t.gameObject.SetActive(false);
 33             t.name = tempAtlasName;
 34             t.parent = transform;
 35 
 36             var tempAtlas = t.GetComponent<UIAtlas>();
 37             if (tempAtlas.spriteMaterial.name != WalkLightShaderName)
 38             {
 39                 Material mat = (Material)GameObject.Instantiate(atlas.spriteMaterial);
 40                 mat.shader = Shader.Find(WalkLightShaderName);
 41                 tempAtlas.spriteMaterial = mat;
 42             }
 43 
 44             base.atlas = tempAtlas;
 45         }
 46     }
 47 
 48     public override void OnFill(BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
 49     {
 50         base.OnFill(verts, uvs, cols);
 51 
 52         // set uv2 to vertex
 53         var lightSprite = atlas.GetSprite("Special_WalkLight");
 54         Rect lightOuter = new Rect(lightSprite.x, lightSprite.y, lightSprite.width, lightSprite.height);
 55         lightOuter = NGUIMath.ConvertToTexCoords(lightOuter, mainTexture.width, mainTexture.height);
 56 
 57         // 用 color 把流光图片的 uv 地址传到 shader 中,故会导致设置 color 无效
 58         cols.Clear();
 59         cols.Add(new Color(lightOuter.xMin, lightOuter.yMin, 0));
 60         cols.Add(new Color(lightOuter.xMin, lightOuter.yMax, 0));
 61         cols.Add(new Color(lightOuter.xMax, lightOuter.yMax, 0));
 62         cols.Add(new Color(lightOuter.xMax, lightOuter.yMin, 0));
 63 
 64         // data set to shader
 65         m_initedMat = false;
 66         m_lightURange = new Vector2(lightOuter.xMin, lightOuter.xMax);
 67 
 68         Rect spriteOuter = new Rect(mSprite.x, mSprite.y, mSprite.width, mSprite.height);
 69         spriteOuter = NGUIMath.ConvertToTexCoords(spriteOuter, mainTexture.width, mainTexture.height);
 70         m_widthLight2Sprite = (lightOuter.width * spriteOuter.height) / (lightOuter.height * spriteOuter.width);
 71         m_t1 = (1 - m_widthLight2Sprite) * m_duration;
 72     }
 73 
 74     protected override void OnUpdate()
 75     {
 76         base.OnUpdate();
 77 
 78         if (RendererMat != null)
 79         {
 80             if (!m_initedMat)
 81             {
 82                 m_initedMat = true;
 83 
 84                 // init
 85                 RendererMat.SetFloat("_LightWidthToMain", m_widthLight2Sprite);
 86                 RendererMat.SetVector("_LightURange", m_lightURange);
 87             }
 88 
 89             // 驱动流光动画
 90             RendererMat.SetFloat("_TimeRate", m_timer / m_duration);
 91 
 92             m_timer += Time.deltaTime;
 93 
 94             if (m_timer > m_duration)
 95                 m_timer = 0;
 96             else if (m_timer > m_t1)
 97                 RendererMat.SetFloat("_ReachBoundary", 1);
 98             else
 99                 RendererMat.SetFloat("_ReachBoundary", -1);
100         }
101     }
102 
103     Material RendererMat
104     {
105         get { return base.Renderer != null ? base.Renderer.sharedMaterial : null; }
106     }
107 
108     public float Duration
109     {
110         set
111         {
112             if (value <= 0)
113                 throw new ArgumentException("value <= 0");
114 
115             m_duration = value;
116             m_t1 = (1 - m_widthLight2Sprite) * m_duration;
117         }
118     }
119 }
UISprite

相关文章:

  • 2022-12-23
  • 2021-10-03
  • 2021-11-30
  • 2021-11-30
  • 2021-06-04
  • 2021-05-18
  • 2022-12-23
  • 2021-10-02
猜你喜欢
  • 2021-09-10
  • 2022-12-23
  • 2021-08-29
  • 2022-12-23
  • 2021-11-30
  • 2021-11-30
  • 2021-08-20
相关资源
相似解决方案