关于Unity实现自定义多边形图片效果
关于Unity实现自定义多边形图片效果
1.创建RawImageEditor编辑器拓展脚本(放在工程中Editor文件夹下,没有则创建)
1 /************************************************* 2 * 项目名称:动态更改图片显示边数 3 * 脚本创建人:魔卡 4 * 脚本创建时间:2018.01.27 5 * 脚本功能:RawImageEditor编辑器功能重写 6 * ***********************************************/ 7 using System.Collections; 8 using System.Collections.Generic; 9 using UnityEngine; 10 using UnityEditor; 11 using UnityEditor.UI; 12 13 [CustomEditor(typeof(UICircle), true)] 14 [CanEditMultipleObjects] 15 public class UICircleInspector : RawImageEditor 16 { 17 18 public override void OnInspectorGUI() 19 { 20 base.OnInspectorGUI(); 21 UICircle circle = target as UICircle; 22 circle.segments = Mathf.Clamp(EditorGUILayout.IntField("UICircle多边形", circle.segments), 3, 360);//设置边数的最小于最大值(3-360) 23 } 24 25 }
2.创建RawImage重新绘制脚本
1 /************************************************* 2 * 项目名称:动态更改图片显示边数 3 * 脚本创建人:魔卡 4 * 脚本创建时间:2018.01.27 5 * 脚本功能:RawImage重新绘制脚本 6 * ***********************************************/ 7 using System; 8 using UnityEngine; 9 using UnityEngine.UI; 10 11 public class UICircle : RawImage 12 { 13 const int FILL_PERCENT = 100; 14 float thickness = 5; 15 16 [SerializeField] 17 [Range(3, 360)] 18 int _segments = 36; 19 20 public int segments 21 { 22 get { return _segments; } 23 set 24 { 25 if (_segments != value) 26 { 27 _segments = value; 28 SetVerticesDirty(); 29 #if UNITY_EDITOR 30 UnityEditor.EditorUtility.SetDirty(transform); 31 #endif 32 } 33 } 34 } 35 36 37 protected override void OnRectTransformDimensionsChange() 38 { 39 base.OnRectTransformDimensionsChange(); 40 this.thickness = (float)Mathf.Clamp(this.thickness, 0, rectTransform.rect.width / 2); 41 } 42 43 protected override void OnPopulateMesh(VertexHelper vh) 44 { 45 float outer = -rectTransform.pivot.x * rectTransform.rect.width; 46 float inner = -rectTransform.pivot.x * rectTransform.rect.width + this.thickness; 47 48 vh.Clear(); 49 50 Vector2 prevX = Vector2.zero; 51 Vector2 prevY = Vector2.zero; 52 Vector2 uv0 = new Vector2(0, 0); 53 Vector2 uv1 = new Vector2(0, 1); 54 Vector2 uv2 = new Vector2(1, 1); 55 Vector2 uv3 = new Vector2(1, 0); 56 Vector2 pos0; 57 Vector2 pos1; 58 Vector2 pos2; 59 Vector2 pos3; 60 61 float tw = rectTransform.rect.width; 62 float th = rectTransform.rect.height; 63 64 float angleByStep = (FILL_PERCENT / 100f * (Mathf.PI * 2f)) / segments; 65 float currentAngle = 0f; 66 for (int i = 0; i < segments + 1; i++) 67 { 68 69 float c = Mathf.Cos(currentAngle); 70 float s = Mathf.Sin(currentAngle); 71 72 StepThroughPointsAndFill(outer, inner, ref prevX, ref prevY, out pos0, out pos1, out pos2, out pos3, c, s); 73 74 uv0 = new Vector2(pos0.x / tw + 0.5f, pos0.y / th + 0.5f); 75 uv1 = new Vector2(pos1.x / tw + 0.5f, pos1.y / th + 0.5f); 76 uv2 = new Vector2(pos2.x / tw + 0.5f, pos2.y / th + 0.5f); 77 uv3 = new Vector2(pos3.x / tw + 0.5f, pos3.y / th + 0.5f); 78 79 vh.AddUIVertexQuad(SetVbo(new[] { pos0, pos1, pos2, pos3 }, new[] { uv0, uv1, uv2, uv3 })); 80 81 currentAngle += angleByStep; 82 } 83 } 84 85 private void StepThroughPointsAndFill(float outer, float inner, ref Vector2 prevX, ref Vector2 prevY, out Vector2 pos0, out Vector2 pos1, out Vector2 pos2, out Vector2 pos3, float c, float s) 86 { 87 pos0 = prevX; 88 pos1 = new Vector2(outer * c, outer * s); 89 90 pos2 = Vector2.zero; 91 pos3 = Vector2.zero; 92 93 prevX = pos1; 94 prevY = pos2; 95 } 96 97 protected UIVertex[] SetVbo(Vector2[] vertices, Vector2[] uvs) 98 { 99 UIVertex[] vbo = new UIVertex[4]; 100 for (int i = 0; i < vertices.Length; i++) 101 { 102 var vert = UIVertex.simpleVert; 103 vert.color = color; 104 vert.position = vertices[i]; 105 vert.uv0 = uvs[i]; 106 vbo[i] = vert; 107 } 108 return vbo; 109 } 110 111 }
3.找一个Canvas下的空物体,将UICircle脚本挂载上,将所需显示的图片拖动到Texture下,根据需要更改图片边数
4.效果图如下:
但行好事,莫问前程!