UI射线源码简析
Graphic Raycaster在UGUI中最主要的射线发生组件。其源码中最主要的方法就是Raycast
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110namespace UnityEngine.UI{ [AddComponentMenu("Event/Graphic Raycaster")] [RequireComponent(typeof(Canvas))] /// <summary> /// A derived BaseRaycaster to raycast against Graphic elements. // ...
网格重建
重建UGUI的网格重建包含两部分内容:
Rebatch:合批部分的重建,Canvas将合批后的物体重建Mesh。
ReBuild:针对单个UI物体的UI重建。主要方法是Canvas.BuildBench
重建过程在上一节说过,重建的主要逻辑都在CanvasUpdateRegistry.PerformUpdate里:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263private void PerformUpdate(){ //精简代码,删掉了Profiler的部分 CleanInvalidItems();//处理掉空的UI或已经销毁的UI m_PerformingLayoutUpdate = true; m_LayoutRebuildQueue.Sort(s_SortLayoutFunction);//将UI按照深度进行排序 //这里表示遍历CanvasUpd ...
基础知识与源码简析
基础知识在UGUI中,每个UI都是Mesh组成的。将scene窗口的Shading Mode改为“WireFrame”,就能查看到UI的网格。
每个UI都开启了模板测试,都在透明物体的渲染队列中渲染。可以把Shading Mode改为“Overdraw”,查看UI的“是否有较多的overdraw”
Drawcall:CPU准备好了所有的顶点、贴图等信息,把这些信息放在GPU可以读取的地方,并向GPU发送一次绘制请求的过程叫做一次Drawcall。
填充率(Fill Rate):显卡每帧或者说每秒能够渲染的像素数。如果overdraw过多,显卡压力就会过大。
批处理(Batching):UGUI做一次Mesh合并的过程。在UGUI中材质和贴图相同并且相邻的UI元素才可以合批。
基础源码简析Canvas类UI绘制的底层类,是一个封装在Unity底层的c++类,在Canvas类中有一个很重要的事件willRenderCanvases,这是所有UI在进行过滤、合批后最终要注册的事件。
123456789101112131415namespace UnityEngine{ [Na ...
滚动列表
普通滚动列表新建Scene命名为LoopList,在Scripts文件夹内新建同名文件夹。
一般情况下,新建一个滚动视图,需要添加“UI——Scroll View”,然后再将各种UI的prefab放在“Scroll View——View Port——Content”下面。然后再给Content挂载“Vertical Layout Group”,并勾选“Control Child Size”(如果是垂直列表就勾选width,反之勾选height)关闭“Child Force Expand”,再挂载“Content Size Fitter”,将“Vertical Fit”改为“Preferred Size”。
并不推荐这样做的原因是,Vertical Layout Group很消耗性能,并且使用了这些组件会让Content变得很大(如果下面的子物体item很多的话),消耗许多内存。
LoopList在LoopList文件夹内新建LoopList、LoopListItem、LoopListItemModel三个脚本,其中LoopList负责MVC架构中C(控制器)的职责,里面负责Item生成 ...
雷达图
新建Scene命名为RadarChart,在Scripts文件夹内新建同名文件夹,并在其中新建RadarChart脚本。
生成背景标记点每一个背景标记点都是一个GameObject,我们将这些点称为Point,修改RadarChart脚本
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class RadarChart : Image{ [SerializeField] private int mPointCount; [SerializeField] private List<RectTransform> mPoints; public void In ...
3D轮转图
不使用3D摄像机和Render Texture,而是直接自定义一个可以实现3D轮转的组件。
新建Scene命名为RotationDiagram,在Scripts文件夹内新建同名文件夹,并在其中新建RotationDiagram2D脚本。
我们的思路是,在代码中创建item的模板(而不是使用prefab加载),控制item模板的轮转来实现效果,所以还要再在RotationDiagram文件夹内新建RotationDiagramItem脚本。
创建Item模板123456789101112131415161718192021222324using UnityEngine;using UnityEngine.UI;public class RotationDiagramItem : MonoBehaviour{ private Image mImage; private Image MyImage//如果在Start里面GetComponent<Image>();可能会出现加载不出来的情况,所以写在属性里。 { get ...
不规则图形点击
实现不规则图形点击区域。
新建Scene命名为IrregularShapeClick,在Scripts文件夹内新建同名文件夹。
Image组件提供的点击过滤方式(不推荐)如果我们想让一个UI的Image组件响应不规则点击,即只有不透明部分响应点击,透明部分不响应点击,可以这样设置:
1GetComponent<Image>().alphtHitTestMinimumThreshold = 0.1f;
alphtHitTestMinimumThreshold属性的意思是,当前UI的图片的透明部分只有大于0.1f时才会响应。
但是这种方法想要生效,就必须打开UI图片导入设置中的:Advanced——Read/Write,这会导致图片的内存使用量增大一倍。所以不推荐这种做法。
自定义不规则图形精确点击使用自定义Image组件配合Polygon Collider 2D组件来实现精确点击。
在IrregularShapeClick文件夹内新建CustomImage脚本
12345678910111213141516171819202122232425using Unity ...
圆形图片组件2
优化一下之前的代码,封装成几个API
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293using UnityEngine;using UnityEngine.Sprites;using UnityEngine.UI;public class CircleImage : Image{ /// <summary> /// 三角面个数 /// </summary> [SerializeField] private int segments = 100; [SerializeField] private float showPercent = 1; private readonly Color32 GRAY_COLOR = ...
圆形图片组件
Unity想要实现圆形图片,需要使用Mask,不是基于Mesh实现的,这里我们自己写一个基于Mesh的圆形图片组件。
新建Scene,命名为“CircleImage”,在Scripts文件夹内新建“CircleImage”文件夹。
Mask圆形遮罩
缺点:锯齿感强,增加DrawCall
CircleImage在“CircleImage”文件夹内新建同名脚本文件
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657using UnityEngine;using UnityEngine.Sprites;using UnityEngine.UI;public class CircleImage : Image{ /// <summary> /// 三角面个数 /// </summary> [SerializeField] private int segments = 100; ...