UGUI

孙广东   2015.8.10     基于Unity5.2版本

1、UIButton 单独可使用        这个脚本可以 提供外部监听按下/点击/释放的3个事件(参数附带着数据)。  源官方Button只有 点击事件

[csharp]  view plain  copy
 print ?
  1. using UnityEngine.Events;  
  2. using UnityEngine.EventSystems;  
  3.   
  4. namespace UnityEngine.UI.Extensions  
  5. {  
  6.     /// <summary>  
  7.     /// UIButton  
  8.     /// </summary>  
  9.     [AddComponentMenu("UI/Extensions/UI Button")]  
  10.     public class UIButton : Button, IPointerDownHandler, IPointerUpHandler  
  11.     {  
  12.         #region Sub-Classes  
  13.         [System.Serializable]  
  14.         public class UIButtonEvent : UnityEvent<PointerEventData.InputButton> { }  
  15.         #endregion  
  16.  
  17.         #region Events  
  18.         public UIButtonEvent OnButtonClick;  
  19.         public UIButtonEvent OnButtonPress;  
  20.         public UIButtonEvent OnButtonRelease;  
  21.         #endregion  
  22.   
  23.         public override void OnPointerClick(PointerEventData eventData)  
  24.         {  
  25.             base.OnSubmit(eventData);  
  26.   
  27.             if (OnButtonClick != null)  
  28.             {  
  29.                 OnButtonClick.Invoke(eventData.button);  
  30.             }  
  31.         }  
  32.   
  33.   
  34.         void IPointerDownHandler.OnPointerDown(PointerEventData eventData)  
  35.         {  
  36.             DoStateTransition(SelectionState.Pressed, false);  
  37.   
  38.             if (OnButtonPress != null)  
  39.             {  
  40.                 OnButtonPress.Invoke(eventData.button);  
  41.             }  
  42.         }  
  43.   
  44.   
  45.         void IPointerUpHandler.OnPointerUp(PointerEventData eventData)  
  46.         {  
  47.             DoStateTransition(SelectionState.Normal, false);  
  48.   
  49.             if (OnButtonRelease != null)  
  50.             {  
  51.                 OnButtonRelease.Invoke(eventData.button);  
  52.             }  
  53.         }  
  54.     }  
  55. }  

2、UIFlippable  单独可使用  我需要一些时间现在翻转精灵和使用scale解决方案被证明是一个糟糕的主意,当使用布局网格等,所以试着写一个小脚本来翻转顶点相反。它目前做这份工作对我来说,我想分享它所以它在这儿......
     这种翻转还有两种实现方式: 设置 Rotation x/y =>180,    Scale x/y =>-1;

[csharp]  view plain  copy
 print ?
  1. using System.Collections.Generic;  
  2.   
  3. namespace UnityEngine.UI.Extensions  
  4. {  
  5.     [RequireComponent(typeof(RectTransform), typeof(Graphic)), DisallowMultipleComponent]  
  6.     [AddComponentMenu("UI/Effects/Extensions/Flippable")]  
  7.     public class UIFlippable : MonoBehaviour, IMeshModifier  
  8.     {       
  9.         [SerializeField] private bool m_Horizontal = false;  
  10.         [SerializeField] private bool m_Veritical = false;  
  11.        
  12.         /// <summary>  
  13.         /// 获取或设置一个值,该值指示是否应水平翻转  
  14.         /// </summary>  
  15.         /// <value><c>true</c> if horizontal; otherwise, <c>false</c>.</value>  
  16.         public bool horizontal  
  17.         {  
  18.             get { return this.m_Horizontal; }  
  19.             set { this.m_Horizontal = value; }  
  20.         }  
  21.        
  22.         /// <summary>  
  23.         /// 获取或设置一个值,该值指示是否应垂直翻转  
  24.         /// </summary>  
  25.         /// <value><c>true</c> if vertical; otherwise, <c>false</c>.</value>  
  26.         public bool vertical  
  27.         {  
  28.             get { return this.m_Veritical; }  
  29.             set { this.m_Veritical = value; }  
  30.         }  
  31.        
  32.         protected void OnValidate()  
  33.         {  
  34.             this.GetComponent<Graphic>().SetVerticesDirty();  
  35.         }  
  36.        
  37.         // 从mesh 得到 顶点集  
  38.         public void ModifyMesh(/*List<UIVertex> verts*/ Mesh mesh)  
  39.         {  
  40.             List<UIVertex> verts = new List<UIVertex> ();  
  41.             using (VertexHelper vertexHelper = new VertexHelper (mesh))  
  42.             {  
  43.                 vertexHelper.GetUIVertexStream (verts);  
  44.             }  
  45.   
  46.             RectTransform rt = this.transform as RectTransform;  
  47.            
  48.             for (int i = 0; i < verts.Count; ++i)  
  49.             {  
  50.                 UIVertex v = verts[i];  
  51.                
  52.                 // Modify positions  
  53.                 v.position = new Vector3(  
  54.                     (this.m_Horizontal ? (v.position.x + (rt.rect.center.x - v.position.x) * 2) : v.position.x),  
  55.                     (this.m_Veritical ?  (v.position.y + (rt.rect.center.y - v.position.y) * 2) : v.position.y),  
  56.                     v.position.z  
  57.                 );  
  58.                
  59.                 // Apply  
  60.                 verts[i] = v;  
  61.             }  
  62.   
  63.             // 在合成mesh  
  64.             using (VertexHelper vertexHelper2 = new VertexHelper ())  
  65.             {  
  66.                 vertexHelper2.AddUIVertexTriangleStream (verts);  
  67.                 vertexHelper2.FillMesh (mesh);  
  68.             }  
  69.         }  
  70.     }  
  71. }  


3、uGUITools   单独可使用        // 让你更了解 锚点、RectTransform等,   Editor脚本

[csharp]  view plain  copy
 print ?
  1. using UnityEditor;  
  2. namespace UnityEngine.UI.Extensions  
  3. {  
  4.     public class uGUITools : MonoBehaviour  
  5.     {  
  6.         [MenuItem("uGUI/Anchors to Corners %[")]  
  7.         static void AnchorsToCorners()  
  8.         {  
  9.             foreach (Transform transform in Selection.transforms)  
  10.             {  
  11.                 RectTransform t = transform as RectTransform;  
  12.                 RectTransform pt = Selection.activeTransform.parent as RectTransform;  
  13.   
  14.                 if (t == null || pt == nullreturn;  
  15.   
  16.                 Vector2 newAnchorsMin = new Vector2(t.anchorMin.x + t.offsetMin.x / pt.rect.width,  
  17.                                                     t.anchorMin.y + t.offsetMin.y / pt.rect.height);  
  18.                 Vector2 newAnchorsMax = new Vector2(t.anchorMax.x + t.offsetMax.x / pt.rect.width,  
  19.                                                     t.anchorMax.y + t.offsetMax.y / pt.rect.height);  
  20.   
  21.                 t.anchorMin = newAnchorsMin;  
  22.                 t.anchorMax = newAnchorsMax;  
  23.                 t.offsetMin = t.offsetMax = new Vector2(0, 0);  
  24.             }  
  25.         }  
  26.   
  27.         [MenuItem("uGUI/Corners to Anchors %]")]  
  28.         static void CornersToAnchors()  
  29.         {  
  30.             foreach (Transform transform in Selection.transforms)  
  31.             {  
  32.                 RectTransform t = transform as RectTransform;  
  33.   
  34.                 if (t == nullreturn;  
  35.   
  36.                 t.offsetMin = t.offsetMax = new Vector2(0, 0);  
  37.             }  
  38.         }  
  39.   
  40.         [MenuItem("uGUI/Mirror Horizontally Around Anchors %;")]  
  41.         static void MirrorHorizontallyAnchors()  
  42.         {  
  43.             MirrorHorizontally(false);  
  44.         }  
  45.   
  46.         [MenuItem("uGUI/Mirror Horizontally Around Parent Center %:")]  
  47.         static void MirrorHorizontallyParent()  
  48.         {  
  49.             MirrorHorizontally(true);  
  50.         }  
  51.   
  52.         static void MirrorHorizontally(bool mirrorAnchors)  
  53.         {  
  54.             foreach (Transform transform in Selection.transforms)  
  55.             {  
  56.                 RectTransform t = transform as RectTransform;  
  57.                 RectTransform pt = Selection.activeTransform.parent as RectTransform;  
  58.   
  59.                 if (t == null || pt == nullreturn;  
  60.   
  61.                 if (mirrorAnchors)  
  62.                 {  
  63.                     Vector2 oldAnchorMin = t.anchorMin;  
  64.                     t.anchorMin = new Vector2(1 - t.anchorMax.x, t.anchorMin.y);  
  65.                     t.anchorMax = new Vector2(1 - oldAnchorMin.x, t.anchorMax.y);  
  66.                 }  
  67.   
  68.                 Vector2 oldOffsetMin = t.offsetMin;  
  69.                 t.offsetMin = new Vector2(-t.offsetMax.x, t.offsetMin.y);  
  70.                 t.offsetMax = new Vector2(-oldOffsetMin.x, t.offsetMax.y);  
  71.   
  72.                 t.localScale = new Vector3(-t.localScale.x, t.localScale.y, t.localScale.z);  
  73.             }  
  74.         }  
  75.   
  76.         [MenuItem("uGUI/Mirror Vertically Around Anchors %'")]  
  77.         static void MirrorVerticallyAnchors()  
  78.         {  
  79.             MirrorVertically(false);  
  80.         }  
  81.   
  82.         [MenuItem("uGUI/Mirror Vertically Around Parent Center %\"")]  
  83.         static void MirrorVerticallyParent()  
  84.         {  
  85.             MirrorVertically(true);  
  86.         }  
  87.   
  88.         static void MirrorVertically(bool mirrorAnchors)  
  89.         {  
  90.             foreach (Transform transform in Selection.transforms)  
  91.             {  
  92.                 RectTransform t = transform as RectTransform;  
  93.                 RectTransform pt = Selection.activeTransform.parent as RectTransform;  
  94.   
  95.                 if (t == null || pt == nullreturn;  
  96.   
  97.                 if (mirrorAnchors)  
  98.                 {  
  99.                     Vector2 oldAnchorMin = t.anchorMin;  
  100.                     t.anchorMin = new Vector2(t.anchorMin.x, 1 - t.anchorMax.y);  
  101.                     t.anchorMax = new Vector2(t.anchorMax.x, 1 - oldAnchorMin.y);  
  102.                 }  
  103.   
  104.                 Vector2 oldOffsetMin = t.offsetMin;  
  105.                 t.offsetMin = new Vector2(t.offsetMin.x, -t.offsetMax.y);  
  106.                 t.offsetMax = new Vector2(t.offsetMax.x, -oldOffsetMin.y);  
  107.   
  108.                 t.localScale = new Vector3(t.localScale.x, -t.localScale.y, t.localScale.z);  
  109.             }  
  110.         }  
  111.     }  
  112. }  

4、ToolTip 【需要外部调用函数显示和隐藏内容】请注意--目前情况下仅适用于Screenspace Camera的画布设置,要包括Screenspace and Worldspace需要更新

[csharp]  view plain  copy
 print ?
  1. namespace UnityEngine.UI.Extensions  
  2. {  
  3.     [RequireComponent(typeof(RectTransform))]  
  4.     [AddComponentMenu("UI/Extensions/Tooltip")]  
  5.     public class ToolTip : MonoBehaviour  
  6.     {  
  7.         //text of the tooltip  
  8.         private Text _text;  
  9.         private RectTransform _rectTransform;  
  10.   
  11.         //if the tooltip is inside a UI element  
  12.         private bool _inside;  
  13.   
  14.         private bool _xShifted, _yShifted = false;  
  15.   
  16.         private float width, height, canvasWidth, canvasHeight;  
  17.   
  18.         private int screenWidth, screenHeight;  
  19.   
  20.         private float YShift,xShift;  
  21.   
  22.         private RenderMode _guiMode;  
  23.   
  24.         private Camera _guiCamera;  
  25.   
  26.         // Use this for initialization  
  27.         public void Awake()  
  28.         {  
  29.             var _canvas = GetComponentInParent<Canvas>();  
  30.             _guiCamera = _canvas.worldCamera;  
  31.             _guiMode = _canvas.renderMode;  
  32.             _rectTransform = GetComponent<RectTransform>();  
  33.   
  34.             _text = GetComponentInChildren<Text>();  
  35.   
  36.             _inside = false;  
  37.   
  38.             //size of the screen  
  39.             screenWidth = Screen.width;  
  40.             screenHeight = Screen.height;  
  41.   
  42.             xShift = 0f;  
  43.             YShift = -30f;  
  44.   
  45.             _xShifted = _yShifted = false;  
  46.   
  47.   
  48.             this.gameObject.SetActive(false);  
  49.   
  50.         }  
  51.   
  52.         //Call this function externally to set the text of the template and activate the tooltip  
  53.         public void SetTooltip(string ttext)  
  54.         {  
  55.   
  56.             if (_guiMode == RenderMode.ScreenSpaceCamera)  
  57.             {  
  58.                 //set the text and fit the tooltip panel to the text size  
  59.                 _text.text = ttext;  
  60.   
  61.                 _rectTransform.sizeDelta = new Vector2(_text.preferredWidth + 40f, _text.preferredHeight + 25f);  
  62.   
  63.                 OnScreenSpaceCamera();  
  64.   
  65.             }  
  66.         }  
  67.   
  68.         //call this function on mouse exit to deactivate the template  
  69.         public void HideTooltip()  
  70.         {  
  71.             if (_guiMode == RenderMode.ScreenSpaceCamera)  
  72.             {  
  73.                 this.gameObject.SetActive(false);  
  74.                 _inside = false;  
  75.             }  
  76.         }  
  77.   
  78.         // Update is called once per frame  
  79.         void FixedUpdate()  
  80.         {  
  81.             if (_inside)  
  82.             {  
  83.                 if (_guiMode == RenderMode.ScreenSpaceCamera)  
  84.                 {  
  85.                     OnScreenSpaceCamera();  
  86.                 }  
  87.             }  
  88.         }  
  89.   
  90.         //main tooltip edge of screen guard and movement  
  91.         public void OnScreenSpaceCamera()  
  92.         {  
  93.             Vector3 newPos = _guiCamera.ScreenToViewportPoint(Input.mousePosition - new Vector3(xShift, YShift, 0f));  
  94.             Vector3 newPosWVP = _guiCamera.ViewportToWorldPoint(newPos);  
  95.   
  96.             width = _rectTransform.sizeDelta[0];  
  97.             height = _rectTransform.sizeDelta[1];  
  98.   
  99.             // check and solve problems for the tooltip that goes out of the screen on the horizontal axis  
  100.             float val;  
  101.   
  102.             Vector3 lowerLeft = _guiCamera.ViewportToWorldPoint(new Vector3(0.0f, 0.0f, 0.0f));  
  103.             Vector3 upperRight = _guiCamera.ViewportToWorldPoint(new Vector3(1.0f, 1.0f, 0.0f));  
  104.   
  105.             //check for right edge of screen  
  106.             val = (newPosWVP.x + width / 2);  
  107.             if (val > upperRight.x)  
  108.             {  
  109.                 Vector3 shifter = new Vector3(val - upperRight.x, 0f, 0f);  
  110.                 Vector3 newWorldPos = new Vector3(newPosWVP.x - shifter.x, newPos.y, 0f);  
  111.                 newPos.x = _guiCamera.WorldToViewportPoint(newWorldPos).x;  
  112.             }  
  113.             //check for left edge of screen  
  114.             val = (newPosWVP.x - width / 2);  
  115.             if (val < lowerLeft.x)  
  116.             {  
  117.                 Vector3 shifter = new Vector3(lowerLeft.x - val, 0f, 0f);  
  118.                 Vector3 newWorldPos = new Vector3(newPosWVP.x + shifter.x, newPos.y, 0f);  
  119.                 newPos.x = _guiCamera.WorldToViewportPoint(newWorldPos).x;  
  120.             }  
  121.   
  122.             // check and solve problems for the tooltip that goes out of the screen on the vertical axis  
  123.   
  124.             //check for upper edge of the screen  
  125.             val = (newPosWVP.y + height / 2);  
  126.             if (val > upperRight.y)  
  127.             {  
  128.                 Vector3 shifter = new Vector3(0f, 35f + height / 2, 0f);  
  129.                 Vector3 newWorldPos = new Vector3(newPos.x, newPosWVP.y - shifter.y, 0f);  
  130.                 newPos.y = _guiCamera.WorldToViewportPoint(newWorldPos).y;  
  131.             }  
  132.   
  133.             //check for lower edge of the screen (if the shifts of the tooltip are kept as in this code, no need for this as the tooltip always appears above the mouse bu default)  
  134.             val = (newPosWVP.y - height / 2);  
  135.             if (val < lowerLeft.y)  
  136.             {  
  137.                 Vector3 shifter = new Vector3(0f, 35f + height / 2, 0f);  
  138.                 Vector3 newWorldPos = new Vector3(newPos.x, newPosWVP.y + shifter.y, 0f);  
  139.                 newPos.y = _guiCamera.WorldToViewportPoint(newWorldPos).y;  
  140.             }  
  141.   
  142.             this.transform.position = new Vector3(newPosWVP.x, newPosWVP.y, 0f);  
  143.             this.gameObject.SetActive(true);  
  144.             _inside = true;  
  145.         }  
  146.     }  
  147. }  

5、 ReturnKeyTriggersButton     首先肯定是要配合 InputField 组件使用,是处理回车键, 【刚刚试了试 InputField 组件 很强大的哦】

[csharp]  view plain  copy
 print ?
  1. using UnityEngine.EventSystems;  
  2. namespace UnityEngine.UI  
  3. {  
  4.     [RequireComponent(typeof(InputField))]  
  5.     [AddComponentMenu("UI/Extensions/Return Key Trigger")]  
  6.     public class ReturnKeyTriggersButton : MonoBehaviour, ISubmitHandler  
  7.     {  
  8.         private EventSystem _system;  
  9.   
  10.         public Button button;  
  11.         private bool highlight = true;  
  12.         public float highlightDuration = 0.2f;  
  13.           
  14.         void Start()  
  15.         {  
  16.             _system = EventSystem.current;  
  17.         }  
  18.   
  19.         void RemoveHighlight()  
  20.         {  
  21.             button.OnPointerExit(new PointerEventData(_system));  
  22.         }  
  23.   
  24.         public void OnSubmit(BaseEventData eventData)  
  25.         {  
  26.             if (highlight) button.OnPointerEnter(new PointerEventData(_system));  
  27.             button.OnPointerClick(new PointerEventData(_system));  
  28.   
  29.             if (highlight) Invoke("RemoveHighlight", highlightDuration);  
  30.         }  
  31.     }  
  32. }  

6、 NicerOutline   和系统的 Outline效果上没有区别,但是实现方式不同可以好好研究一下

[csharp]  view plain  copy
 print ?
  1. using System.Collections.Generic;  
  2. namespace UnityEngine.UI.Extensions  
  3. {  
  4.     //An outline that looks a bit nicer than the default one. It has less "holes" in the outline by drawing more copies of the effect  
  5.     [AddComponentMenu("UI/Effects/Extensions/Nicer Outline")]  
  6.     public class NicerOutline : BaseMeshEffect  
  7.     {  
  8.         [SerializeField]  
  9.         private Color m_EffectColor = new Color (0f, 0f, 0f, 0.5f);  
  10.           
  11.         [SerializeField]  
  12.         private Vector2 m_EffectDistance = new Vector2 (1f, -1f);  
  13.           
  14.         [SerializeField]  
  15.         private bool m_UseGraphicAlpha = true;  
  16.         //  
  17.         // Properties  
  18.         //  
  19.         public Color effectColor  
  20.         {  
  21.             get  
  22.             {  
  23.                 return this.m_EffectColor;  
  24.             }  
  25.             set  
  26.             {  
  27.                 this.m_EffectColor = value;  
  28.                 if (base.graphic != null)  
  29.                 {  
  30.                     base.graphic.SetVerticesDirty ();  
  31.                 }  
  32.             }  
  33.         }  
  34.           
  35.         public Vector2 effectDistance  
  36.         {  
  37.             get  
  38.             {  
  39.                 return this.m_EffectDistance;  
  40.             }  
  41.             set  
  42.             {  
  43.                 if (value.x > 600f)  
  44.                 {  
  45.                     value.x = 600f;  
  46.                 }  
  47.                 if (value.x < -600f)  
  48.                 {  
  49.                     value.x = -600f;  
  50.                 }  
  51.                 if (value.y > 600f)  
  52.                 {  
  53.                     value.y = 600f;  
  54.                 }  
  55.                 if (value.y < -600f)  
  56.                 {  
  57.                     value.y = -600f;  
  58.                 }  
  59.                 if (this.m_EffectDistance == value)  
  60.                 {  
  61.                     return;  
  62.                 }  
  63.                 this.m_EffectDistance = value;  
  64.                 if (base.graphic != null)  
  65.                 {  
  66.                     base.graphic.SetVerticesDirty ();  
  67.                 }  
  68.             }  
  69.         }  
  70.           
  71.         public bool useGraphicAlpha  
  72.         {  
  73.             get  
  74.             {  
  75.                 return this.m_UseGraphicAlpha;  
  76.             }  
  77.             set  
  78.             {  
  79.                 this.m_UseGraphicAlpha = value;  
  80.                 if (base.graphic != null)  
  81.                 {  
  82.                     base.graphic.SetVerticesDirty ();  
  83.                 }  
  84.             }  
  85.         }  
  86.           
  87.   
  88.         //  
  89.         // Methods  
  90.         //  
  91.         protected void ApplyShadow (List<UIVertex> verts, Color32 color, int start, int end, float x, float y)  
  92.         {  
  93.             //Debug.Log("verts count: "+verts.Count);  
  94.             int num = verts.Count * 2;  
  95.             if (verts.Capacity < num)  
  96.             {  
  97.                 verts.Capacity = num;  
  98.             }  
  99.             for (int i = start; i < end; i++)  
  100.             {  
  101.                 UIVertex uIVertex = verts [i];  
  102.                 verts.Add (uIVertex);  
  103.   
  104.                 Vector3 position = uIVertex.position;  
  105.                 //Debug.Log("vertex pos: "+position);  
  106.                 position.x += x;  
  107.                 position.y += y;  
  108.                 uIVertex.position = position;  
  109.                 Color32 color2 = color;  
  110.                 if (this.m_UseGraphicAlpha)  
  111.                 {  
  112.                     color2.a = (byte)(color2.a * verts [i].color.a / 255);  
  113.                 }  
  114.                 uIVertex.color = color2;  
  115.                 //uIVertex.color = (Color32)Color.blue;  
  116.                 verts [i] = uIVertex;  
  117.             }  
  118.         }  
  119.           
  120.         public override void ModifyMesh (/*List<UIVertex> verts*/ Mesh mesh)  
  121.         {  
  122.             if (!this.IsActive ())  
  123.             {  
  124.                 return;  
  125.             }  
  126.             // 从mesh 得到 顶点集  
  127.             List<UIVertex> verts = new List<UIVertex> ();  
  128.             using (VertexHelper vertexHelper = new VertexHelper (mesh))  
  129.             {  
  130.                 vertexHelper.GetUIVertexStream (verts);  
  131.             }  
  132.   
  133.             Text foundtext = GetComponent<Text>();  
  134.               
  135.             float best_fit_adjustment = 1f;  
  136.               
  137.             if (foundtext && foundtext.resizeTextForBestFit)    
  138.             {  
  139.                 best_fit_adjustment = (float)foundtext.cachedTextGenerator.fontSizeUsedForBestFit / (foundtext.resizeTextMaxSize-1); //max size seems to be exclusive   
  140.   
  141.             }  
  142.   
  143.             float distanceX = this.effectDistance.x * best_fit_adjustment;  
  144.             float distanceY = this.effectDistance.y * best_fit_adjustment;  
  145.   
  146.             int start = 0;  
  147.             int count = verts.Count;  
  148.             this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, distanceY);  
  149.             start = count;  
  150.             count = verts.Count;  
  151.             this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, -distanceY);  
  152.             start = count;  
  153.             count = verts.Count;  
  154.             this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, distanceY);  
  155.             start = count;  
  156.             count = verts.Count;  
  157.             this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, -distanceY);  
  158.   
  159.             start = count;  
  160.             count = verts.Count;  
  161.             this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, 0);  
  162.             start = count;  
  163.             count = verts.Count;  
  164.             this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, 0);  
  165.   
  166.             start = count;  
  167.             count = verts.Count;  
  168.             this.ApplyShadow (verts, this.effectColor, start, verts.Count, 0, distanceY);  
  169.             start = count;  
  170.             count = verts.Count;  
  171.             this.ApplyShadow (verts, this.effectColor, start, verts.Count, 0, -distanceY);  
  172.   
  173.             // 在合成mesh  
  174.             using (VertexHelper vertexHelper2 = new VertexHelper ())  
  175.             {  
  176.                 vertexHelper2.AddUIVertexTriangleStream (verts);  
  177.                 vertexHelper2.FillMesh (mesh);  
  178.             }  
  179.         }  
  180.           
  181.         protected override void OnValidate ()  
  182.         {  
  183.             this.effectDistance = this.m_EffectDistance;  
  184.             base.OnValidate ();  
  185.         }  
  186.     }  
  187. }  

7、 LetterSpacing  单独使用 每个字符间可以设置间距了!【uGUI Text 组件支持行间距,但不是字符间距。 问题是-text layout 引擎不是开源的的一部分,你无法拿到合适的 API,一种解决办法是,只需修改现有的字体,每个字符添加额外的空间。这是那样难以管理,它的声音,和我到其中有很多的不同间隔标题工作不切实际的最近的设计。我需要为每个不同的间距不同的字体。    我最好的解决办法是,只需修改现有的字体fonts ,每个字符添加额外的空间。这样难以管理,我到其中有很多的不同间隔标题工作不切实际的设计。我需要为每个不同的间距不同的字体。     然后偶然看了看Shadow 效果,使用 BaseVertexEffect 来修改绘制的源对象的几何形状的顶点列表。和这个技术相同,文本 间距(虽然它不会产生任何额外的verts)。将组件添加到 UI 文本字段,调整间距值,完成工作。但它不能很好与rich text或自动换行的文本工作】

[csharp]  view plain  copy
 print ?
  1. using System.Collections.Generic;  
  2.   
  3. namespace UnityEngine.UI.Extensions  
  4. {  
  5.     [AddComponentMenu("UI/Effects/Extensions/Letter Spacing")]  
  6.     public class LetterSpacing : BaseMeshEffect  
  7.     {  
  8.         [SerializeField]  
  9.         private float m_spacing = 0f;  
  10.           
  11.         protected LetterSpacing() { }  
  12.          
  13.         #if UNITY_EDITOR  
  14.         protected override void OnValidate()  
  15.         {  
  16.             spacing = m_spacing;  
  17.             base.OnValidate();  
  18.         }  
  19.         #endif  
  20.           
  21.         public float spacing  
  22.         {  
  23.             get { return m_spacing; }  
  24.             set  
  25.             {  
  26.                 if (m_spacing == value) return;  
  27.                 m_spacing = value;  
  28.                 if (graphic != null) graphic.SetVerticesDirty();  
  29.             }  
  30.         }  
  31.           
  32.         public override void ModifyMesh(/*List<UIVertex> verts*/Mesh mesh)  
  33.         {  
  34.             if (! IsActive()) return;  
  35.   
  36.             // 从mesh 得到 顶点集  
  37.             List<UIVertex> verts = new List<UIVertex> ();  
  38.             using (VertexHelper vertexHelper = new VertexHelper (mesh))  
  39.             {  
  40.                 vertexHelper.GetUIVertexStream (verts);  
  41.             }  
  42.               
  43.             Text text = GetComponent<Text>();  
  44.             if (text == null)  
  45.             {  
  46.                 Debug.LogWarning("LetterSpacing: Missing Text component");  
  47.                 return;  
  48.             }  
  49.               
  50.             string[] lines = text.text.Split('\n');  
  51.             Vector3  pos;  
  52.             float    letterOffset    = spacing * (float)text.fontSize / 100f;  
  53.             float    alignmentFactor = 0;  
  54.             int      glyphIdx        = 0;  
  55.               
  56.             switch (text.alignment)  
  57.             {  
  58.             case TextAnchor.LowerLeft:  
  59.             case TextAnchor.MiddleLeft:  
  60.             case TextAnchor.UpperLeft:  
  61.                 alignmentFactor = 0f;  
  62.                 break;  
  63.                   
  64.             case TextAnchor.LowerCenter:  
  65.             case TextAnchor.MiddleCenter:  
  66.             case TextAnchor.UpperCenter:  
  67.                 alignmentFactor = 0.5f;  
  68.                 break;  
  69.                   
  70.             case TextAnchor.LowerRight:  
  71.             case TextAnchor.MiddleRight:  
  72.             case TextAnchor.UpperRight:  
  73.                 alignmentFactor = 1f;  
  74.                 break;  
  75.             }  
  76.               
  77.             for (int lineIdx=0; lineIdx < lines.Length; lineIdx++)  
  78.             {  
  79.                 string line = lines[lineIdx];  
  80.                 float lineOffset = (line.Length -1) * letterOffset * alignmentFactor;  
  81.                   
  82.                 for (int charIdx = 0; charIdx < line.Length; charIdx++)  
  83.                 {  
  84.                     int idx1 = glyphIdx * 4 + 0;  
  85.                     int idx2 = glyphIdx * 4 + 1;  
  86.                     int idx3 = glyphIdx * 4 + 2;  
  87.                     int idx4 = glyphIdx * 4 + 3;  
  88.                       
  89.                     // Check for truncated text (doesn't generate verts for all characters)  
  90.                     if (idx4 > verts.Count - 1) return;  
  91.                       
  92.                     UIVertex vert1 = verts[idx1];  
  93.                     UIVertex vert2 = verts[idx2];  
  94.                     UIVertex vert3 = verts[idx3];  
  95.                     UIVertex vert4 = verts[idx4];  
  96.                       
  97.                     pos = Vector3.right * (letterOffset * charIdx - lineOffset);  
  98.                       
  99.                     vert1.position += pos;  
  100.                     vert2.position += pos;  
  101.                     vert3.position += pos;  
  102.                     vert4.position += pos;  
  103.                       
  104.                     verts[idx1] = vert1;  
  105.                     verts[idx2] = vert2;  
  106.                     verts[idx3] = vert3;  
  107.                     verts[idx4] = vert4;  
  108.                       
  109.                     glyphIdx++;  
  110.                 }  
  111.                   
  112.                 // Offset for carriage return character that still generates verts  
  113.                 glyphIdx++;  
  114.             }  
  115.   
  116.             // 在合成mesh  
  117.             using (VertexHelper vertexHelper2 = new VertexHelper ())  
  118.             {  
  119.                 vertexHelper2.AddUIVertexTriangleStream (verts);  
  120.                 vertexHelper2.FillMesh (mesh);  
  121.             }  
  122.         }  
  123.     }  
  124. }  

8、 Gradient     和之前发表的blog差不多吧,这个是可以对Text文本内容的而且有global/local模式,选项更多了【可以研究源码】

[csharp]  view plain  copy
 print ?
  1. using System.Collections.Generic;  
  2.   
  3. namespace UnityEngine.UI.Extensions  
  4. {  
  5.     // [RequireComponent(typeof(Text), typeof(RectTransform))]  
  6.     [AddComponentMenu("UI/Effects/Extensions/Gradient")]  
  7.     public class Gradient : BaseMeshEffect  
  8.     {  
  9.         public GradientMode gradientMode = GradientMode.Global;  
  10.         public GradientDir gradientDir = GradientDir.Vertical;  
  11.         public bool overwriteAllColor = false;  
  12.         public Color vertex1 = Color.white;  
  13.         public Color vertex2 = Color.black;  
  14.         private Graphic targetGraphic;  
  15.   
  16.         protected override void Start()  
  17.         {  
  18.             targetGraphic = GetComponent<Graphic>();  
  19.         }  
  20.   
  21.         public override void ModifyMesh(/*List<UIVertex> vertexList*/ Mesh mesh)  
  22.         {  
  23.             // 从mesh 得到 顶点集  
  24.             List<UIVertex> vertexList = new List<UIVertex> ();  
  25.             using (VertexHelper vertexHelper = new VertexHelper (mesh))  
  26.             {  
  27.                 vertexHelper.GetUIVertexStream (vertexList);  
  28.             }  
  29.   
  30.             if (!IsActive() || vertexList.Count == 0)  
  31.             {  
  32.                 return;  
  33.             }  
  34.             int count = vertexList.Count;  
  35.             UIVertex uiVertex = vertexList[0];  
  36.             if (gradientMode == GradientMode.Global)  
  37.             {  
  38.                 if (gradientDir == GradientDir.DiagonalLeftToRight || gradientDir == GradientDir.DiagonalRightToLeft)  
  39.                 {  
  40. #if UNITY_EDITOR  
  41.                     Debug.LogWarning("Diagonal dir is not supported in Global mode");  
  42. #endif  
  43.                     gradientDir = GradientDir.Vertical;  
  44.                 }  
  45.                 float bottomY = gradientDir == GradientDir.Vertical ? vertexList[vertexList.Count - 1].position.y : vertexList[vertexList.Count - 1].position.x;  
  46.                 float topY = gradientDir == GradientDir.Vertical ? vertexList[0].position.y : vertexList[0].position.x;  
  47.   
  48.                 float uiElementHeight = topY - bottomY;  
  49.   
  50.                 for (int i = 0; i < count; i++)  
  51.                 {  
  52.                     uiVertex = vertexList[i];  
  53.                     if (!overwriteAllColor && uiVertex.color != targetGraphic.color)  
  54.                         continue;  
  55.                     uiVertex.color *= Color.Lerp(vertex2, vertex1, ((gradientDir == GradientDir.Vertical ? uiVertex.position.y : uiVertex.position.x) - bottomY) / uiElementHeight);  
  56.                     vertexList[i] = uiVertex;  
  57.                 }  
  58.             }  
  59.             else  
  60.             {  
  61.                 for (int i = 0; i < count; i++)  
  62.                 {  
  63.                     uiVertex = vertexList[i];  
  64.                     if (!overwriteAllColor && !CompareCarefully(uiVertex.color, targetGraphic.color))  
  65.                         continue;  
  66.                     switch (gradientDir)  
  67.                     {  
  68.                         case GradientDir.Vertical:  
  69.                             uiVertex.color *= (i % 4 == 0 || (i - 1) % 4 == 0) ? vertex1 : vertex2;  
  70.                             break;  
  71.                         case GradientDir.Horizontal:  
  72.                             uiVertex.color *= (i % 4 == 0 || (i - 3) % 4 == 0) ? vertex1 : vertex2;  
  73.                             break;  
  74.                         case GradientDir.DiagonalLeftToRight:  
  75.                             uiVertex.color *= (i % 4 == 0) ? vertex1 : ((i - 2) % 4 == 0 ? vertex2 : Color.Lerp(vertex2, vertex1, 0.5f));  
  76.                             break;  
  77.                         case GradientDir.DiagonalRightToLeft:  
  78.                             uiVertex.color *= ((i - 1) % 4 == 0) ? vertex1 : ((i - 3) % 4 == 0 ? vertex2 : Color.Lerp(vertex2, vertex1, 0.5f));  
  79.                             break;  
  80.   
  81.                     }  
  82.                     vertexList[i] = uiVertex;  
  83.                 }  
  84.             }  
  85.   
  86.             // 在合成mesh  
  87.             using (VertexHelper vertexHelper2 = new VertexHelper ())  
  88.             {  
  89.                 vertexHelper2.AddUIVertexTriangleStream (vertexList);  
  90.                 vertexHelper2.FillMesh (mesh);  
  91.             }  
  92.         }  
  93.         private bool CompareCarefully(Color col1, Color col2)  
  94.         {  
  95.             if (Mathf.Abs(col1.r - col2.r) < 0.003f && Mathf.Abs(col1.g - col2.g) < 0.003f && Mathf.Abs(col1.b - col2.b) < 0.003f && Mathf.Abs(col1.a - col2.a) < 0.003f)  
  96.                 return true;  
  97.             return false;  
  98.         }  
  99.     }  
  100.   
  101.     public enum GradientMode  
  102.     {  
  103.         Global,  
  104.         Local  
  105.     }  
  106.   
  107.     public enum GradientDir  
  108.     {  
  109.         Vertical,  
  110.         Horizontal,  
  111.         DiagonalLeftToRight,  
  112.         DiagonalRightToLeft  
  113.         //Free  
  114.     }  
  115.     //enum color mode Additive, Multiply, Overwrite  
  116. }  


9、UIWindowBase      挂上之后, 可以拖动UI元素

[csharp]  view plain  copy
 print ?
  1. using System;  
  2. using UnityEngine.EventSystems;  
  3.   
  4. namespace UnityEngine.UI.Extensions  
  5. {  
  6.     /// <summary>  
  7.     /// Includes a few fixes of my own, mainly to tidy up duplicates, remove unneeded stuff and testing. (nothing major, all the crew above did the hard work!)  
  8.     /// </summary>  
  9.     [RequireComponent(typeof(RectTransform))]  
  10.     [AddComponentMenu("UI/Extensions/UI Window Base")]  
  11.     public class UIWindowBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler  
  12.     {  
  13.         RectTransform m_transform = null;  
  14.         private bool _isDragging = false;  
  15.         public static bool ResetCoords = false;  
  16.         private Vector3 m_originalCoods = Vector3.zero;  
  17.         private Canvas m_canvas;  
  18.         private RectTransform m_canvasRectTransform;  
  19.         public int KeepWindowInCanvas = 5;            // # of pixels of the window that must stay inside the canvas view.  
  20.   
  21.         // Use this for initialization  
  22.         void Start()  
  23.         {  
  24.             m_transform = GetComponent<RectTransform>();  
  25.             m_originalCoods = m_transform.position;  
  26.             m_canvas = GetComponentInParent<Canvas>();  
  27.             m_canvasRectTransform = m_canvas.GetComponent<RectTransform>();  
  28.         }  
  29.   
  30.         void Update()  
  31.         {  
  32.             if (ResetCoords)  
  33.                 resetCoordinatePosition();  
  34.         }  
  35.   
  36.         public void OnDrag(PointerEventData eventData)  
  37.         {  
  38.             if (_isDragging)  
  39.             {  
  40.                 var delta = ScreenToCanvas(eventData.position) - ScreenToCanvas(eventData.position - eventData.delta);  
  41.                 m_transform.localPosition += delta;  
  42.             }  
  43.         }  
  44.   
  45.         //Note, the begin drag and end drag aren't actually needed to control the drag.  However, I'd recommend keeping it in case you want to do somethind else when draggging starts and stops  
  46.         public void OnBeginDrag(PointerEventData eventData)  
  47.         {  
  48.   
  49.             if (eventData.pointerCurrentRaycast.gameObject == null)  
  50.                 return;  
  51.   
  52.             if (eventData.pointerCurrentRaycast.gameObject.name == name)  
  53.             {  
  54.                 _isDragging = true;  
  55.             }  
  56.         }  
  57.   
  58.         public void OnEndDrag(PointerEventData eventData)  
  59.         {  
  60.             _isDragging = false;  
  61.         }  
  62.   
  63.         void resetCoordinatePosition()  
  64.         {  
  65.             m_transform.position = m_originalCoods;  
  66.             ResetCoords = false;  
  67.         }  
  68.   
  69.         private Vector3 ScreenToCanvas(Vector3 screenPosition)  
  70.         {  
  71.             Vector3 localPosition;  
  72.             Vector2 min;  
  73.             Vector2 max;  
  74.             var canvasSize = m_canvasRectTransform.sizeDelta;  
  75.   
  76.             if (m_canvas.renderMode == RenderMode.ScreenSpaceOverlay || (m_canvas.renderMode == RenderMode.ScreenSpaceCamera && m_canvas.worldCamera == null))  
  77.             {  
  78.                 localPosition = screenPosition;  
  79.   
  80.                 min = Vector2.zero;  
  81.                 max = canvasSize;  
  82.             }  
  83.             else  
  84.             {  
  85.                 var ray = m_canvas.worldCamera.ScreenPointToRay(screenPosition);  
  86.                 var plane = new Plane(m_canvasRectTransform.forward, m_canvasRectTransform.position);  
  87.   
  88.                 float distance;  
  89.                 if (plane.Raycast(ray, out distance) == false)  
  90.                 {  
  91.                     throw new Exception("Is it practically possible?");  
  92.                 };  
  93.                 var worldPosition = ray.origin + ray.direction * distance;  
  94.                 localPosition = m_canvasRectTransform.InverseTransformPoint(worldPosition);  
  95.   
  96.                 min = -Vector2.Scale(canvasSize, m_canvasRectTransform.pivot);  
  97.                 max = Vector2.Scale(canvasSize, Vector2.one - m_canvasRectTransform.pivot);  
  98.             }  
  99.   
  100.             // keep window inside canvas  
  101.             localPosition.x = Mathf.Clamp(localPosition.x, min.x + KeepWindowInCanvas, max.x - KeepWindowInCanvas);  
  102.             localPosition.y = Mathf.Clamp(localPosition.y, min.y + KeepWindowInCanvas, max.y - KeepWindowInCanvas);  
  103.   
  104.             return localPosition;  
  105.         }  
  106.     }  
  107. }  


10、FlowLayoutGroup      一种布局组件

[csharp]  view plain  copy
 print ?
  1. using System.Collections.Generic;  
  2.   
  3. namespace UnityEngine.UI.Extensions  
  4. {  
  5.     /// <summary>  
  6.     /// Layout Group controller that arranges children in rows, fitting as many on a line until total width exceeds parent bounds  
  7.     /// </summary>  
  8.     [AddComponentMenu("Layout/Extensions/Flow Layout Group")]  
  9.     public class FlowLayoutGroup : LayoutGroup  
  10.     {  
  11.         public float Spacing = 0f;  
  12.   
  13.         public bool ChildForceExpandWidth = false;  
  14.         public bool ChildForceExpandHeight = false;  
  15.   
  16.         private float _layoutHeight;  
  17.   
  18.         public override void CalculateLayoutInputHorizontal()  
  19.         {  
  20.   
  21.             base.CalculateLayoutInputHorizontal();  
  22.   
  23.             var minWidth = GetGreatestMinimumChildWidth() + padding.left + padding.right;  
  24.   
  25.             SetLayoutInputForAxis(minWidth, -1, -1, 0);  
  26.   
  27.         }  
  28.   
  29.         public override void SetLayoutHorizontal()  
  30.         {  
  31.             SetLayout(rectTransform.rect.width, 0, false);  
  32.         }  
  33.   
  34.         public override void SetLayoutVertical()  
  35.         {  
  36.             SetLayout(rectTransform.rect.width, 1, false);  
  37.         }  
  38.   
  39.         public override void CalculateLayoutInputVertical()  
  40.         {  
  41.             _layoutHeight = SetLayout(rectTransform.rect.width, 1, true);  
  42.         }  
  43.   
  44.         protected bool IsCenterAlign  
  45.         {  
  46.             get  
  47.             {  
  48.                 return childAlignment == TextAnchor.LowerCenter || childAlignment == TextAnchor.MiddleCenter ||  
  49.                        childAlignment == TextAnchor.UpperCenter;  
  50.             }  
  51.         }  
  52.   
  53.         protected bool IsRightAlign  
  54.         {  
  55.             get  
  56.             {  
  57.                 return childAlignment == TextAnchor.LowerRight || childAlignment == TextAnchor.MiddleRight ||  
  58.                        childAlignment == TextAnchor.UpperRight;  
  59.             }  
  60.         }  
  61.   
  62.         protected bool IsMiddleAlign  
  63.         {  
  64.             get  
  65.             {  
  66.                 return childAlignment == TextAnchor.MiddleLeft || childAlignment == TextAnchor.MiddleRight ||  
  67.                        childAlignment == TextAnchor.MiddleCenter;  
  68.             }  
  69.         }  
  70.   
  71.         protected bool IsLowerAlign  
  72.         {  
  73.             get  
  74.             {  
  75.                 return childAlignment == TextAnchor.LowerLeft || childAlignment == TextAnchor.LowerRight ||  
  76.                        childAlignment == TextAnchor.LowerCenter;  
  77.             }  
  78.         }  
  79.   
  80.         /// <summary>  
  81.         /// Holds the rects that will make up the current row being processed  
  82.         /// </summary>  
  83.         private readonly IList<RectTransform> _rowList = new List<RectTransform>();   
  84.   
  85.         /// <summary>  
  86.         /// Main layout method  
  87.         /// </summary>  
  88.         /// <param name="width">Width to calculate the layout with</param>  
  89.         /// <param name="axis">0 for horizontal axis, 1 for vertical</param>  
  90.         /// <param name="layoutInput">If true, sets the layout input for the axis. If false, sets child position for axis</param>  
  91.         public float SetLayout(float width, int axis, bool layoutInput)  
  92.         {  
  93.             var groupHeight = rectTransform.rect.height;  
  94.   
  95.             // Width that is available after padding is subtracted  
  96.             var workingWidth = rectTransform.rect.width - padding.left - padding.right;  
  97.   
  98.             // Accumulates the total height of the rows, including spacing and padding.  
  99.             var yOffset = IsLowerAlign ? (float)padding.bottom : (float)padding.top;  
  100.   
  101.             var currentRowWidth = 0f;  
  102.             var currentRowHeight = 0f;  
  103.   
  104.             for (var i = 0; i < rectChildren.Count; i++) {  
  105.   
  106.                 // LowerAlign works from back to front  
  107.                 var index = IsLowerAlign ? rectChildren.Count - 1 - i : i;  
  108.   
  109.                 var child = rectChildren[index];  
  110.   
  111.                 var childWidth = LayoutUtility.GetPreferredSize(child, 0);  
  112.                 var childHeight = LayoutUtility.GetPreferredSize(child, 1);  
  113.   
  114.                 // Max child width is layout group with - padding  
  115.                 childWidth = Mathf.Min(childWidth, workingWidth);  
  116.   
  117.                 // If adding this element would exceed the bounds of the row,  
  118.                 // go to a new line after processing the current row  
  119.                 if (currentRowWidth + childWidth > workingWidth) {  
  120.   
  121.                     currentRowWidth -= Spacing;  
  122.   
  123.                     // Process current row elements positioning  
  124.                     if (!layoutInput) {  
  125.   
  126.                         var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);  
  127.                         LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);  
  128.   
  129.                     }  
  130.   
  131.                     // Clear existing row  
  132.                     _rowList.Clear();  
  133.   
  134.                     // Add the current row height to total height accumulator, and reset to 0 for the next row  
  135.                     yOffset += currentRowHeight;  
  136.                     yOffset += Spacing;  
  137.   
  138.                     currentRowHeight = 0;  
  139.                     currentRowWidth = 0;  
  140.   
  141.                 }  
  142.   
  143.                 currentRowWidth += childWidth;  
  144.                 _rowList.Add(child);  
  145.   
  146.                 // We need the largest element height to determine the starting position of the next line  
  147.                 if (childHeight > currentRowHeight) {  
  148.                     currentRowHeight = childHeight;  
  149.                 }  
  150.   
  151.                 currentRowWidth += Spacing;  
  152.             }  
  153.   
  154.             if (!layoutInput) {  
  155.                 var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);  
  156.   
  157.                 // Layout the final row  
  158.                 LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);  
  159.             }  
  160.   
  161.             _rowList.Clear();  
  162.   
  163.             // Add the last rows height to the height accumulator  
  164.             yOffset += currentRowHeight;  
  165.             yOffset += IsLowerAlign ? padding.top : padding.bottom;  
  166.   
  167.             if (layoutInput) {  
  168.   
  169.                 if(axis == 1)  
  170.                     SetLayoutInputForAxis(yOffset, yOffset, -1, axis);  
  171.   
  172.             }  
  173.   
  174.             return yOffset;  
  175.         }  
  176.   
  177.         private float CalculateRowVerticalOffset(float groupHeight, float yOffset, float currentRowHeight)  
  178.         {  
  179.             float h;  
  180.   
  181.             if (IsLowerAlign) {  
  182.                 h = groupHeight - yOffset - currentRowHeight;  
  183.             } else if (IsMiddleAlign) {  
  184.                 h = groupHeight*0.5f - _layoutHeight * 0.5f + yOffset;  
  185.             } else {  
  186.                 h = yOffset;  
  187.             }  
  188.             return h;  
  189.         }  
  190.   
  191.         protected void LayoutRow(IList<RectTransform> contents, float rowWidth, float rowHeight, float maxWidth, float xOffset, float yOffset, int axis)  
  192.         {  
  193.             var xPos = xOffset;  
  194.   
  195.             if (!ChildForceExpandWidth && IsCenterAlign)  
  196.                 xPos += (maxWidth - rowWidth) * 0.5f;  
  197.             else if (!ChildForceExpandWidth && IsRightAlign)  
  198.                 xPos += (maxWidth - rowWidth);  
  199.   
  200.             var extraWidth = 0f;  
  201.   
  202.             if (ChildForceExpandWidth) {  
  203.                 extraWidth = (maxWidth - rowWidth)/_rowList.Count;  
  204.             }  
  205.   
  206.             for (var j = 0; j < _rowList.Count; j++) {  
  207.   
  208.                 var index = IsLowerAlign ? _rowList.Count - 1 - j : j;  
  209.   
  210.                 var rowChild = _rowList[index];  
  211.   
  212.                 var rowChildWidth = LayoutUtility.GetPreferredSize(rowChild, 0) + extraWidth;  
  213.                 var rowChildHeight = LayoutUtility.GetPreferredSize(rowChild, 1);  
  214.   
  215.                 if (ChildForceExpandHeight)  
  216.                     rowChildHeight = rowHeight;  
  217.   
  218.                 rowChildWidth = Mathf.Min(rowChildWidth, maxWidth);  
  219.   
  220.                 var yPos = yOffset;  
  221.   
  222.                 if (IsMiddleAlign)  
  223.                     yPos += (rowHeight - rowChildHeight) * 0.5f;  
  224.                 else if (IsLowerAlign)  
  225.                     yPos += (rowHeight - rowChildHeight);  
  226.   
  227.                 if (axis == 0)  
  228.                     SetChildAlongAxis(rowChild, 0, xPos, rowChildWidth);  
  229.                 else  
  230.                     SetChildAlongAxis(rowChild, 1, yPos, rowChildHeight);  
  231.   
  232.                 xPos += rowChildWidth + Spacing;  
  233.             }  
  234.         }  
  235.   
  236.         public float GetGreatestMinimumChildWidth()  
  237.         {  
  238.             var max = 0f;  
  239.   
  240.             for (var i = 0; i < rectChildren.Count; i++) {  
  241.                 var w = LayoutUtility.GetMinWidth(rectChildren[i]);  
  242.   
  243.                 max = Mathf.Max(w, max);  
  244.             }  
  245.   
  246.             return max;  
  247.         }  
  248.     }  
  249. }  



11、CurvedText             让文本按照曲线进行显示   

[csharp]  view plain  copy
 print ?
  1. using System.Collections.Generic;  
  2.   
  3. namespace UnityEngine.UI.Extensions  
  4. {  
  5.     /// <summary>  
  6.     /// Curved text.让文本按照曲线进行显示 【注意对Image的变形 也是可以的】  
  7.     /// 说明: 对Text的操作就和 shadow 和 outline 组件类似。  
  8.     /// </summary>  
  9.     // [RequireComponent(typeof(Text), typeof(RectTransform))]  
  10.     [AddComponentMenu("UI/Effects/Extensions/Curved Text")]  
  11.     public class CurvedText : BaseMeshEffect  
  12.     {  
  13.         // 曲线类型  
  14.         public AnimationCurve curveForText = AnimationCurve.Linear(0, 0, 1, 10);   
  15.         // 曲线程度  
  16.         public float curveMultiplier = 1;           
  17.         private RectTransform rectTrans;  
  18.  
  19.  
  20. #if UNITY_EDITOR  
  21.         protected override void OnValidate()  
  22.         {  
  23.             base.OnValidate();  
  24.             if (curveForText[0].time != 0)  
  25.             {  
  26.                 var tmpRect = curveForText[0];  
  27.                 tmpRect.time = 0;  
  28.                 curveForText.MoveKey(0, tmpRect);  
  29.             }  
  30.             if (rectTrans == null)  
  31.                 rectTrans = GetComponent<RectTransform>();  
  32.             if (curveForText[curveForText.length - 1].time != rectTrans.rect.width)  
  33.                 OnRectTransformDimensionsChange();  
  34.         }  
  35. #endif  
  36.         protected override void Awake()  
  37.         {  
  38.             base.Awake();  
  39.             rectTrans = GetComponent<RectTransform>();  
  40.             OnRectTransformDimensionsChange();  
  41.         }  
  42.         protected override void OnEnable()  
  43.         {  
  44.             base.OnEnable();  
  45.             rectTrans = GetComponent<RectTransform>();  
  46.             OnRectTransformDimensionsChange();  
  47.         }  
  48.         /// <summary>  
  49.         /// Modifies the mesh. 最重要的重载函数  
  50.         /// </summary>  
  51.         /// <param name="mesh">Mesh.</param>  
  52.         public override void ModifyMesh(/*List<UIVertex> verts*/Mesh mesh)  
  53.         {  
  54.             if (!IsActive())  
  55.                 return;  
  56.   
  57.             // 从mesh 得到 顶点集  
  58.             List<UIVertex> verts = new List<UIVertex> ();  
  59.             using (VertexHelper vertexHelper = new VertexHelper (mesh))  
  60.             {  
  61.                 vertexHelper.GetUIVertexStream (verts);  
  62.             }  
  63.   
  64.             // 顶点的 y值按曲线变换  
  65.             for (int index = 0; index < verts.Count; index++)  
  66.             {  
  67.                 var uiVertex = verts[index];  
  68.                 //Debug.Log ();  
  69.                 uiVertex.position.y += curveForText.Evaluate(rectTrans.rect.width * rectTrans.pivot.x + uiVertex.position.x) * curveMultiplier;  
  70.                 verts[index] = uiVertex;  
  71.             }  
  72.   
  73.             // 在合成mesh  
  74.             using (VertexHelper vertexHelper2 = new VertexHelper ())  
  75.             {  
  76.                 vertexHelper2.AddUIVertexTriangleStream (verts);  
  77.                 vertexHelper2.FillMesh (mesh);  
  78.             }  
  79.         }  
  80.         protected override void OnRectTransformDimensionsChange()  
  81.         {  
  82.             var tmpRect = curveForText[curveForText.length - 1];  
  83.             tmpRect.time = rectTrans.rect.width;  
  84.             curveForText.MoveKey(curveForText.length - 1, tmpRect);  
  85.         }  
  86.     }  
  87. }  


12、CanvasGroupActivator

Canvas Groups Activator 激活编辑器窗口,显示和隐藏CanvasGroup

[csharp]  view plain  copy
 print ?
  1. using UnityEditor;  
  2.   
  3. namespace UnityEngine.UI.Extensions  
  4. {  
  5.     public class CanvasGroupActivator : EditorWindow  
  6.     {  
  7.         [MenuItem("Window/UI/Extensions/Canvas Groups Activator")]  
  8.         public static void InitWindow()  
  9.         {  
  10.             EditorWindow.GetWindow<CanvasGroupActivator>();  
  11.         }  
  12.   
  13.         CanvasGroup[] canvasGroups;  
  14.   
  15.         void OnEnable()  
  16.         {  
  17.             ObtainCanvasGroups();  
  18.         }  
  19.   
  20.         void OnFocus()  
  21.         {  
  22.             ObtainCanvasGroups();  
  23.         }  
  24.   
  25.         void ObtainCanvasGroups()  
  26.         {  
  27.             canvasGroups = GameObject.FindObjectsOfType<CanvasGroup>();  
  28.         }  
  29.   
  30.         void OnGUI()  
  31.         {  
  32.             if (canvasGroups == null)  
  33.             {  
  34.                 return;  
  35.             }  
  36.   
  37.             GUILayout.Space(10f);  
  38.             GUILayout.Label("Canvas Groups");  
  39.   
  40.             for (int i = 0; i < canvasGroups.Length; i++)  
  41.             {  
  42.                 if (canvasGroups[i] == null) { continue; }  
  43.   
  44.                 bool initialActive = false;  
  45.                 if (canvasGroups[i].alpha == 1.0f)  
  46.                     initialActive = true;  
  47.   
  48.                 bool active = EditorGUILayout.Toggle(canvasGroups[i].name, initialActive);  
  49.                 if (active != initialActive)  
  50.                 {  
  51.                     //If deactivated and initially active  
  52.                     if (!active && initialActive)  
  53.                     {  
  54.                         //Deactivate this  
  55.                         canvasGroups[i].alpha = 0f;  
  56.                         canvasGroups[i].interactable = false;  
  57.                         canvasGroups[i].blocksRaycasts = false;  
  58.                     }  
  59.                     //If activated and initially deactive  
  60.                     else if (active && !initialActive)  
  61.                     {  
  62.                         //Deactivate all others and activate this  
  63.                         HideAllGroups();  
  64.   
  65.                         canvasGroups[i].alpha = 1.0f;  
  66.                         canvasGroups[i].interactable = true;  
  67.                         canvasGroups[i].blocksRaycasts = true;  
  68.                     }  
  69.                 }  
  70.             }  
  71.   
  72.             GUILayout.Space(5f);  
  73.   
  74.             if (GUILayout.Button("Show All"))  
  75.             {  
  76.                 ShowAllGroups();  
  77.             }  
  78.   
  79.             if (GUILayout.Button("Hide All"))  
  80.             {  
  81.                 HideAllGroups();  
  82.             }  
  83.         }  
  84.   
  85.         void ShowAllGroups()  
  86.         {  
  87.             foreach (var group in canvasGroups)  
  88.             {  
  89.                 if (group != null)  
  90.                 {  
  91.                     group.alpha = 1.0f;  
  92.                     group.interactable = true;  
  93.                     group.blocksRaycasts = true;  
  94.                 }  
  95.             }  
  96.         }  
  97.   
  98.         void HideAllGroups()  
  99.         {  
  100.             foreach (var group in canvasGroups)  
  101.             {  
  102.                 if (group != null)  
  103.                 {  
  104.                     group.alpha = 0;  
  105.                     group.interactable = false;  
  106.                     group.blocksRaycasts = false;  
  107.                 }  
  108.             }  
  109.         }  
  110.     }  
  111. }  


13、BestFitOutline   跟 Outline功能相似

[csharp]  view plain  copy
 print ?
  1. using System.Collections.Generic;  
  2. namespace UnityEngine.UI.Extensions  
  3. {  
  4.     [AddComponentMenu("UI/Effects/Extensions/BestFit Outline")]  
  5.     public class BestFitOutline : Shadow  
  6.     {  
  7.         protected BestFitOutline ()  
  8.         {  
  9.         }  
  10.         public override void ModifyMesh (/*List<UIVertex> verts*/Mesh mesh)  
  11.         {  
  12.             if (!this.IsActive ())  
  13.             {  
  14.                 return;  
  15.             }  
  16.             // 从mesh 得到 顶点集  
  17.             List<UIVertex> verts = new List<UIVertex> ();  
  18.             using (VertexHelper vertexHelper = new VertexHelper (mesh))  
  19.             {  
  20.                 vertexHelper.GetUIVertexStream (verts);  
  21.             }  
  22.   
  23.             Text foundtext = GetComponent<Text>();  
  24.   
  25.             float best_fit_adjustment = 1f;  
  26.   
  27.             if (foundtext && foundtext.resizeTextForBestFit)    
  28.             {  
  29.                 best_fit_adjustment = (float)foundtext.cachedTextGenerator.fontSizeUsedForBestFit / (foundtext.resizeTextMaxSize-1); //max size seems to be exclusive   
  30.             }  
  31.               
  32.             int start = 0;  
  33.             int count = verts.Count;  
  34.             base.ApplyShadow (verts, base.effectColor, start, verts.Count, base.effectDistance.x*best_fit_adjustment, base.effectDistance.y*best_fit_adjustment);  
  35.             start = count;  
  36.             count = verts.Count;  
  37.             base.ApplyShadow (verts, base.effectColor, start, verts.Count, base.effectDistance.x*best_fit_adjustment, -base.effectDistance.y*best_fit_adjustment);  
  38.             start = count;  
  39.             count = verts.Count;  
  40.             base.ApplyShadow (verts, base.effectColor, start, verts.Count, -base.effectDistance.x*best_fit_adjustment, base.effectDistance.y*best_fit_adjustment);  
  41.             start = count;  
  42.             count = verts.Count;  
  43.             base.ApplyShadow (verts, base.effectColor, start, verts.Count, -base.effectDistance.x*best_fit_adjustment, -base.effectDistance.y*best_fit_adjustment);  
  44.   
  45.             // 在合成mesh  
  46.             using (VertexHelper vertexHelper2 = new VertexHelper ())  
  47.             {  
  48.                 vertexHelper2.AddUIVertexTriangleStream (verts);  
  49.                 vertexHelper2.FillMesh (mesh);  
  50.             }  
  51.         }  
  52.     }  
  53. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值