zoukankan      html  css  js  c++  java
  • Unity 绘制多边形

      最近工程需要用到一个多边形用来查看角色属性,于是就研究了下Mesh用网格做了一个。遗憾的的 UGUI 渲染不了 3D 物体,然后又用了一段时间研究了下UGUI的网格绘制。

    不过终于还是完成了,虽然有些瑕疵…… 好吧 有很大的问题 UV 需要自己计算。(如果有朋友精通这一块,希望能帮忙改进一下)

    下边是5.2以下版本使用 的

    5.2(包括)以上的 请点击这个连接 

     在Unity中一个Mesh使用3个顶点就能画出来,但是UGUI需要使用四个顶点才行,所以在画一些特殊模型的时候就会产生一些废点(对图形没影响但是必须存在)。

    下面要开始了。额……再等等,先让我借用几张图

    Ok 先上使用教

    先添加个这个

    添加

    然后在这下边创建个空物体

    然后添加这个脚本

    然后就可以编辑这个脚本的属性 实现不同的多边形啦

    使用polygon脚本 可以实现很多种形状 比如这些:

    a

    a

    1

    2

    6

    a

    注意:上边这些都是UGUI,并不是模型网格;

    5.2的UGUIAPI改动比较大所以不能想想兼容,我是在原作者的代码基础上改的。(希望原作者不会介意……额 我还是发个邮件说一下吧!!!!!!)

    使用步骤和上边一样,这两个具有相同的问题就是UV的贴的时候没有贴好(原谅我这个数学渣渣),在原基础上增加了顶点网格的设置,其余的没有更改。

     5.2(包涵)以上版本的 在上边的连接可以下载到 ,下边是5.2以下版本的。

     

    //*********************************************************************
    //
    //                       ScriptName     : UIPolygonPast
    //                          
    //                              筱程       
    //                                   
    //*********************************************************************
    
    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections.Generic;
    public class UIPolygonPast : MaskableGraphic
    {
    
        List<Vector2> pointPosition = new List<Vector2>();
        List<Vector2> Vertex = new List<Vector2>();
        List<Vector2> UV     = new List<Vector2>();
        // 是否使用顶点画  默认是不使用
        // 使用需要用户自己传入顶点位置 
        // 否则会根据顶点数目 以零点位置自动计算圆形顶点位置
        [SerializeField]
        Texture m_Textrue;
    
        public bool usingVertex;
    
        // 是否中空
        public bool fill = true;
    
        // 顶点数目
        [Range(3, 360)]
        public int sides = 3;
        // 选择角度
        [Range(0, 360)]
        public float Rotation = 90;
        // 边缘厚度
        [Range(0, 500)]
        public float Thickness = 5;
        // 顶点距离
        [Range(0, 1)]
        public float[] VerticesDistances = new float[3];
    
        private float size = 1f;
        public override Texture mainTexture {
            get {
                return m_Textrue == null ? s_WhiteTexture : m_Textrue;
            }
        }
        public Texture texture {
            get {
                return m_Textrue;
            }
            set {
                if (m_Textrue == value)
                    return;
                m_Textrue = value;
                SetVerticesDirty();
                SetMaterialDirty();
            }
        }
        /// <summary>
        /// 设置图片顶点
        /// </summary>
        /// <param name="_Vertex"></param>
        public void DrwaPolyonVertex(List<Vector2> _Vertex) {
            DrwaPolyonVertex(_Vertex, null);
        }
        /// <summary>
        ///  设置图片顶点
        /// </summary>
        /// <param name="_Vertex">顶点</param>
        /// /// <param name="_UV">UI</param>
        public void DrwaPolyonVertex(List<Vector2> _Vertex,List<Vector2> _UV) {
            Vertex      = _Vertex;
            UV          = _UV;
            usingVertex = true;
        }
        /// <summary>
        /// 设置顶点数目
        /// </summary>
        /// <param name="_sides"></param>
        public void DrwaPolygon(int _sides) {
            DrwaPolygon(_sides, null);
        }
        /// <summary>
        /// 设置顶点数目
        /// </summary>
        /// <param name="_sides"></param>
        /// <param name="_VerticesDistances">顶点距离信息</param>
        public void DrwaPolygon(int _sides, float[] _VerticesDistances) {
            DrwaPolygon(_sides, _VerticesDistances, 90);
        }
        /// <summary>
        /// 设置顶点数目
        /// </summary>
        /// <param name="_sides"></param>
        /// <param name="_VerTicesDstances">顶点距离信息</param>
        /// <param name="_Rotation">顶点旋转</param>
        public void DrwaPolygon(int _sides, float[] _VerTicesDstances,float _Rotation) {
            sides = _sides;
            if (_VerTicesDstances != null)
            VerticesDistances = _VerTicesDstances;
            Rotation = _Rotation;
            usingVertex = false;
        }
        private Vector2 CalculatedPosition(Vector2 p1, Vector2 p2, Rect rect) {
            p1.x *= rect.width;
            p1.y *= rect.height;
            return p1;
        }
    
        // UI网格都是四边形,所以需要四个顶点
        // 但是我们只需要三个顶点,所以就需要添加一个废点
        // 否则不能组成网格
        // 最后所有点数的总和应该是4的倍数
        protected override void OnFillVBO(List<UIVertex> vbo) {
            vbo.Clear();
    
            if (usingVertex) {
                VerterxDrwa(ref vbo);
            } else {
                VerterxNumberDrwa(ref vbo);
            }
        }
        // 用顶点画
        private void VerterxDrwa(ref List<UIVertex> vbo) {
            Vector2 pos1 = Vector2.zero;
            Vector2 pos2 = Vector2.zero;
            Vector2 pos3 = Vector2.zero;
            Vector2 pos4 = Vector2.zero;
            if (Vertex.Count == 0) {
                pointPosition.Clear();
                pointPosition.Add(new Vector2(0, -1) / 2f);
                pointPosition.Add(new Vector2(-1, -0.5f) / 2f);
    
                pointPosition.Add(new Vector2(-1, 0.5f) / 2f);
                pointPosition.Add(new Vector2(0, 1) / 2f);
                pointPosition.Add(new Vector2(1, 0.5f) / 2f);
                pointPosition.Add(new Vector2(1, -0.5f) / 2f);
            } else {
                pointPosition.Clear();
                pointPosition = Vertex;
            }
    
            for (int i = 0; i < pointPosition.Count; i++) {
                Vector2 pos      = pointPosition[i];
                pointPosition[i] = CalculatedPosition(pos, rectTransform.pivot, rectTransform.rect);
            }
            int count   = pointPosition.Count;
            Vector2 uv1 = new Vector2(0, 0);
            Vector2 uv2 = new Vector2(0, 1);
            Vector2 uv3 = new Vector2(1, 1);
            Vector2 uv4 = new Vector2(1, 0);
            for (int i  = 0; i < count - 1; i++) {
    
                pos1 = pointPosition[i];
                pos2 = pointPosition[i] + ( pointPosition[i] - Vector2.zero ) * -0.2f;
                pos3 = Vector2.zero;
                pos4 = pointPosition[i + 1];
                if (UV != null && count==UV.Count) {
                    uv3 = new Vector2(0.5f, 0.5f);
                    uv1 = UV[i];
                    uv4 = UV[i + 1];
                    uv2 = uv1 + ( uv1 - uv3 ) * -0.2f;
                }
                AddUIVerterx(ref vbo, new Vector2[] { pos1, pos2, pos3, pos4 }, new Vector2[] { uv1, uv2, uv3, uv4 });
            }
    
            pos1 = pointPosition[count - 1];
            pos2 = pointPosition[count - 1] + ( pointPosition[count - 1] - Vector2.zero ) * -0.2f;
            pos3 = Vector2.zero;
            pos4 = pointPosition[0];
            if (UV != null && count == UV.Count) {
                uv1 = UV[count - 1];
                uv4 = UV[0];
                uv2 = uv1 + ( uv1 - uv3 ) * -0.2f;
            }
            AddUIVerterx(ref vbo, new Vector2[] { pos1, pos2, pos3, pos4 }, new Vector2[] { uv1, uv2, uv3, uv4 });
        }
        //  用顶点数画多边形
        private void VerterxNumberDrwa(ref List<UIVertex> vbo) {
    
            float degrees = 360f / sides;
    
             size = rectTransform.rect.width > rectTransform.rect.height ? rectTransform.rect.height : rectTransform.rect.width;
            Thickness = Mathf.Clamp(Thickness, 0, size / 2);
    
            if (VerticesDistances == null || VerticesDistances.Length != sides + 1) {
                VerticesDistances = new float[sides + 1];
                for (int i = 0; i < sides; i++)
                    VerticesDistances[i] = 1;
            }
            VerticesDistances[sides] = VerticesDistances[0];
            Vector2 pos1 ;
            Vector2 pos2 ;
            Vector2 pos3 ;
            Vector2 pos4 ;
            Vector2 lastPosx = Vector2.zero;
            Vector2 lastPosy = Vector2.zero;
            Vector2 uv1 = new Vector2(0, 0);
            Vector2 uv2 = new Vector2(0, 1);
            Vector2 uv3 = new Vector2(1, 1);
            Vector2 uv4 = new Vector2(1, 0);
            //Vector2 lastuv = new Vector2(0.5f, 0.5f);
            for (int i  = 0; i <= sides; i++) {
    
                float outer = -rectTransform.pivot.x * size * VerticesDistances[i];
                float inner = -rectTransform.pivot.x * size * VerticesDistances[i] + Thickness;
                float rad   = Mathf.Deg2Rad * ( i * degrees + Rotation );
                float c     = Mathf.Cos(rad);
                float s     = Mathf.Sin(rad);
                pos1        = lastPosx;
                pos2        = new Vector2(outer * c, outer * s);
    
                if (fill) {
                    pos3 = Vector2.zero;
                    pos4 = Vector2.zero;
                } else {
                    pos3 = new Vector2(inner * c, inner * s);
                    pos4 = lastPosy;
                }
                #region
                //int x = (int) (pos1.x < 0 ? pos1.x * -1 : pos1.x * 2);
                //int y = (int)( pos1.y < 0 ? pos1.y * -1 : pos1.y * 2 );
    
                //float uvx = 0;
                //float uvy = 0;
                //    if (x != 0) {
                //        uvx =x / size;
                //    }
                //    if (y != 0) {
                //        uvy =y / size;
                //    }
              
                //uv2 = new Vector2(uvx, uvy);  
                //uv1 = lastuv;    
                //lastuv = uv2;
                #endregion
                lastPosx = pos2;
                lastPosy = pos3;
                AddUIVerterx(ref vbo, new Vector2[] { pos1, pos2, pos3, pos4 }, new Vector2[] { uv1, uv2, uv3, uv4 });
            }
        }
        private void AddUIVerterx(ref List<UIVertex> vbo, Vector2[] pos, Vector2[] uv = null) {
            UIVertex vert = UIVertex.simpleVert;
            for (int i = 0; i < pos.Length; i++) {
                vert.position = pos[i];
                vert.color = color;
                if (uv != null && uv.Length == pos.Length)
                    vert.uv0 = uv[i];
                vbo.Add(vert);
            }
        }
    }

  • 相关阅读:
    c#中的构造方法
    c# Dictionary拓展2个key得到1个value
    虚拟主机的提权两个小技巧
    teamviewer提权
    域渗透:mstsc连接记录清理
    linux之 vim 常用命令
    Linux之 find 命令学习
    域渗透:MS14-068
    学习:脱壳之Anti Dump和修复PE
    学习:KiUserExceptionDispatcher之寻找OEP
  • 原文地址:https://www.cnblogs.com/mdrs/p/5067734.html
Copyright © 2011-2022 走看看