Unity中UGUI源码剖析之最本质的UI实现原理

一直以来都对Unity中的UGUI比较感兴趣,之前我学过点Android,Android中最让我惊喜就是其中的View 也就是呈现的界面UI,有太多的人发挥着自己的想象力创造了一个又一个酷炫的UI组件;现在学习着Unity中的UGUI,也是希望能造属于自己的轮子,所以了解UGUI源码是必要的,知道这其中最本质UI实现原理也是开始~~

大概的原理

在Unity的世界中,UI的基本组成就是界面和事件,像我们的按钮,有构成按钮的外观以及响应的事件,至此才说得上是个UI。

界面的构成

这里的界面不仅仅只是指2D,同样3D在Unity中也是相同的原理。我们能够在Unity中看到物体其实多亏了下面的这两个

MeshRender以及MeshFilter,有了它们才能让我们看到物体的样子,具体的细节我就不细说,大体就是一个物体模型构成需要网格以及UV贴图(这还是我学建模的时候接触到的,当然远不止这些),这样在导入Unity配合上面两个组件和灯光就能够让我们看到了。

界面的事件

说到事件究其本质应该是射线监测外加行为判断才有的,这让我想起了用Unity做的第一个项目,那时我用的就是射线来处理很多物体的交互,现在想来还是经验不够,完全可以通过委托事件来弄,会简化好多。

自己的UI自己造

说了那么多,其实只要有个像样的例子也就能理解了

首先上代码,也就这一个代码

MyUI.cs

    using UnityEngine;
    using UnityEngine.UI;
    
    public class MyUI : MonoBehaviour {

        //这是个帮助类,具体可以查看官方文档
        VertexHelper vh = new VertexHelper();
        private Mesh mesh;
        public Color color;
        public Texture2D texture2D;
        private MeshFilter meshFilter;
        private MeshRenderer meshRender;
        private MeshCollider meshCollider;
        public Camera cam;
    
        private MeshFilter MeshFilter{
            get{
                if (meshFilter == null)
                    meshFilter = GetComponent<MeshFilter>();
                return meshFilter;
            }
        }
    
        private MeshRenderer MeshRenderer
        {
            get
            {
                if (meshRender == null)
                    meshRender = GetComponent<MeshRenderer>();
                return meshRender;
            }
        }
    
        private MeshCollider MeshCollider
        {
            get
            {
                if (meshCollider == null)
                    meshCollider = GetComponent<MeshCollider>();
                return meshCollider;
            }
        }
        // Use this for initialization
        void Start () {
            //初始化Mesh
            InitMesh();
        }
        
        // Update is called once per frame
        void Update () {
            //通过屏幕鼠标点击点发射射线
            var ray = cam.ScreenPointToRay(Input.mousePosition);
            RaycastHit hitInfo;
            Physics.Raycast(ray, out hitInfo);
            if (hitInfo.collider != null && hitInfo.collider.gameObject != null)
            {
                //被射线射中且鼠标左键单击了产生单击事件
                if (Input.GetMouseButtonDown(0))
                {
                    Debug.Log("鼠标点击了");
                }
            }
            //将颜色传入MeshRender,给UI增添颜色的变化
            MeshRenderer.material.color = color;
            //将UI图片放入UI的MeshRender中
            MeshRenderer.material.mainTexture = texture2D;
        }
    
        void InitMesh()
        {
            //创建一个Mesh
            mesh = new Mesh();
            vh.Clear();
            //对UI界面进行描绘,主要设置顶点和UV,这里是Vector2 当然也可以Vector3
            vh.AddVert(new Vector2(0, 0), color, new Vector2(0, 0));
            vh.AddVert(new Vector2(0, 1), color, new Vector2(0, 1));
            vh.AddVert(new Vector2(1, 1), color, new Vector2(1, 1));
            vh.AddVert(new Vector2(1, 0), color, new Vector2(1, 0));
            //对顶点进行分序连接成三角形
            vh.AddTriangle(0,1,2);
            vh.AddTriangle(2,3,0);
            //将顶点设置填充到mesh中
            vh.FillMesh(mesh);
            //将mesh填充进MeshFilter
            MeshFilter.mesh = mesh;
            //因为需要射线射中这里需要添加碰撞器,且把mesh传入
            MeshCollider.sharedMesh = mesh;
        }
    }

代码挂载到一个空物体上,具体像下面这样

MyUI.png

具体的解释已经在代码中给出了,对了如果对其中的顶点设置有疑问的话可以移步 这里

当然也可以参看原文 here

还有一点我要说的是这并非我原创,我只是把理解写出来而已,详细可以参看 这里

基本实现以及原理说的差不多了,接下来就需要自己去源码中寻找更多的东西,或者之后的某一天我可以写出不同效果的UI出来,那会儿对UGUI的使用才能算熟~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容