目录:
- 如何绘制
- 如何响应点击 -事件系统
- 如何重绘ReBuild
1. 如何绘制
将顶点数据填充到Mesh,再将Mesh设置到Mesh filter。
-
基础组件:
- Mesh filter 网格
- Mesh Render 渲染
-
核心概念
-
Mesh-网格: 决定物体的形状
var mesh = new Mesh(); m_VertexHelper.AddVert(new Vector2(0, 0),color, new Vector2(0, 0.5f)); m_VertexHelper.AddVert(new Vector2(0, 1),color, new Vector2(0, 1)); m_VertexHelper.AddVert(new Vector2(1, 1),color, new Vector2(1, 1)); m_VertexHelper.AddVert(new Vector2(1, 0),color, new Vector2(1, 0)); m_VertexHelper.AddTriangle(0, 1, 2); m_VertexHelper.AddTriangle(3,0, 2); m_VertexHelper.FillMesh(mesh);
-
Vertext-顶点: 组成Mesh的元素
m_VertexHelper.AddVert(new Vector2(0, 0),color, new Vector2(0, 0.5f)); m_VertexHelper.AddVert(new Vector2(0, 1),color, new Vector2(0, 1)); m_VertexHelper.AddVert(new Vector2(1, 1),color, new Vector2(1, 1)); m_VertexHelper.AddVert(new Vector2(1, 0),color, new Vector2(1, 0));
-
Triangle-三角形: 决定顶点的顺序
m_VertexHelper.AddTriangle(0, 1, 2); m_VertexHelper.AddTriangle(3,0, 2);
-
UV-纹理坐标
m_MeshRenderer.material.color = color; m_MeshRenderer.material.mainTexture = texture2D;
-
-
与组件结合使用
m_MeshFilter.mesh = mesh; m_MeshRenderer.material.color = color; m_MeshRenderer.material.mainTexture = texture2D;
2. 如何响应点击
2.1 获取点中的UI元素: GraphicRaycaster
在GraphicRaycaster中调用Raycast:
Perform a raycast into the screen and collect all graphics underneath it.
- 获取当前canvas下的所有Graphic :
var foundGraphics = GraphicRegistry.GetGraphicsForCanvas(canvas);
- 遍历Graphic,判断Graphic 的raycastTarget,是否可以响应点击
- 判断触摸点是否在Graphic的范围内(推测RectangleContainsScreenPoint函数中使用射线检测):
RectTransformUtility.RectangleContainsScreenPoint(graphic.rectTransform, pointerPosition, eventCamera)
注意事项:不需要响应点击的Graphic 不勾选
Raycast Target
,提高性能
private static void Raycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, List<Graphic> results)
{
// Necessary for the event system
var foundGraphics = GraphicRegistry.GetGraphicsForCanvas(canvas);
for (int i = 0; i < foundGraphics.Count; ++i)
{
Graphic graphic = foundGraphics[i];
// -1 means it hasn't been processed by the canvas, which means it isn't actually drawn
if (graphic.depth == -1 || !graphic.raycastTarget)
continue;
if (!RectTransformUtility.RectangleContainsScreenPoint(graphic.rectTransform, pointerPosition, eventCamera))
continue;
if (graphic.Raycast(pointerPosition, eventCamera))
{
s_SortedGraphics.Add(graphic);
}
}
...
}
2.2 事件触发过程
ExecuteEvents:Execute、EventFunction
3. 如何重绘
- UI发生变动时,会将发生变动的元素加入渲染队列(CanvasUpdateRegistry)
- 注册Canvas.WillRenderCanvases事件,UI发生变动,该事件触发。
在CanvasUpdateRegistry内部,需要关注的方法是PerformUpdate。当Canvas组件触发WillRenderCanvases事件时都会调用这个方法。这个事件每一帧都会执行一次。
- 该事件从渲染队列中获取元素,分别调用ReBuild方法
- ReBuild方法中完成网格、材质等更新