关于Unity实现自定义多边形图片效果

Posted 魔卡先生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于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.效果图如下:

      

 

以上是关于关于Unity实现自定义多边形图片效果的主要内容,如果未能解决你的问题,请参考以下文章

关于Unity中UGUI图片Image实现仿视频播放窗口的四角缩放功能

利用伪元素before实现自定义checkbox样式

Unity自定义组件之序列帧播放组件

Flutter 自定义 View 介绍

带有并排选项卡的 Unity 自定义窗口

自定义view----六边形战斗力图表