当前位置:网站首页>Unity ugui source code graphic

Unity ugui source code graphic

2022-07-05 04:57:00 OldMan_ sjc

Graphic

How does it bring us UI Displayed on the screen

Post a simple example

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyGraphic : MonoBehaviour
{
    public Texture texture;

    // Start is called before the first frame update
    void Start()
    {
        Mesh mesh = new Mesh();
        mesh.Clear();
        mesh.SetVertices(new List<Vector3>() { new Vector3(0, 0), new Vector3(0, 100), new Vector3(100, 100), new Vector3(100, 0) });
        mesh.SetUVs(0, new List<Vector2>() { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) });
        mesh.SetTriangles(new List<int>() { 0, 1, 2, 2, 3, 0 }, 0);
        mesh.RecalculateBounds();
        CanvasRenderer canvasRenderer = gameObject.AddComponent<CanvasRenderer>();
        canvasRenderer.SetMesh(mesh);
        canvasRenderer.materialCount = 1;
        canvasRenderer.SetMaterial(Canvas.GetDefaultCanvasMaterial(), 0);
        canvasRenderer.SetTexture(texture);
    }
}

The effect is as follows :
 Insert picture description here
We used CanvasRenderer, Simple setup Mesh,Material,Texture The picture is displayed .

CanvasRenderer : A component that will render to the screen after all normal rendering has completed when attached to a Canvas. Designed for GUI application.

Graphic It is through CanvasRenderer take UI Displayed on the screen , Specifically Graphic Where is it set up Mesh,Material,Texture You can see the following code .

Graphic Code logic

First of all Graphic Of OnEnable

protected override void OnEnable()
{
    base.OnEnable();
    //  find parent first active And enabled Of canvas
    CacheCanvas();
    // GraphicRegistry take Graphic and canvas Stored in the Dictionary<Canvas, IndexedSet<Graphic>> m_Graphics in 
    GraphicRegistry.RegisterGraphicForCanvas(canvas, this);

#if UNITY_EDITOR
    GraphicRebuildTracker.TrackGraphic(this);
#endif
    if (s_WhiteTexture == null)
        s_WhiteTexture = Texture2D.whiteTexture;
    //  take Layout, Vertices, Materials Set to dirty state 
    SetAllDirty();
}

OnEnable Simply do some initialization , And then we did SetAllDirty, This function will Layout, Vertices, Materials Set to dirty state , Here we mainly look at the right Vertices, Materials To deal with , Both call

// CanvasUpdateRegistry Responsible for graphic Add entry IndexedSet<ICanvasElement> m_GraphicRebuildQueue In the list 
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);

In this step ,CanvasUpdateRegistry Instantiate and execute in the constructor

// Event that is called just before Canvas rendering happens.
// This allows you to delay processing / updating of canvas based elements until just before they are rendered.
Canvas.willRenderCanvases += PerformUpdate;

PerformUpdate The function will be used every time Canvas Before rendering .

private void PerformUpdate()
{
	......
	m_PerformingGraphicUpdate = true;
    for (var i = (int)CanvasUpdate.PreRender; i < (int)CanvasUpdate.MaxUpdateValue; i++)
    {
        for (var k = 0; k < m_GraphicRebuildQueue.Count; k++)
        {
            try
            {
                var element = m_GraphicRebuildQueue[k];
                if (ObjectValidForUpdate(element))
                    element.Rebuild((CanvasUpdate)i);
            }
            catch (Exception e)
            {
                Debug.LogException(e, m_GraphicRebuildQueue[k].transform);
            }
        }
    }

    for (int i = 0; i < m_GraphicRebuildQueue.Count; ++i)
        m_GraphicRebuildQueue[i].GraphicUpdateComplete();

    m_GraphicRebuildQueue.Clear();
    m_PerformingGraphicUpdate = false;
  	......
}

This function traverses m_GraphicRebuildQueue, And execute Rebuild Method ,GraphicUpdateComplete Method .

//  whenever Vertices, Materials by dirty state , Go to UpdateGeometry,UpdateMaterial
public virtual void Rebuild(CanvasUpdate update)
 {
     if (canvasRenderer == null || canvasRenderer.cull)
         return;

     switch (update)
     {
         case CanvasUpdate.PreRender:
             if (m_VertsDirty)
             {
                 UpdateGeometry();
                 m_VertsDirty = false;
             }
             if (m_MaterialDirty)
             {
                 UpdateMaterial();
                 m_MaterialDirty = false;
             }
             break;
     }
 }
 
 // UpdateGeometry The function will eventually call DoMeshGeneration
  private void DoMeshGeneration()
 {
     if (rectTransform != null && rectTransform.rect.width >= 0 && rectTransform.rect.height >= 0)
         OnPopulateMesh(s_VertexHelper);
     else
         s_VertexHelper.Clear(); // clear the vertex helper so invalid graphics dont draw.

     var components = ListPool<Component>.Get();
     GetComponents(typeof(IMeshModifier), components);

     for (var i = 0; i < components.Count; i++)
         ((IMeshModifier)components[i]).ModifyMesh(s_VertexHelper);

     ListPool<Component>.Release(components);

     s_VertexHelper.FillMesh(workerMesh);
     canvasRenderer.SetMesh(workerMesh);
 }
 
 protected virtual void UpdateMaterial()
 {
     if (!IsActive())
         return;

     canvasRenderer.materialCount = 1;
     canvasRenderer.SetMaterial(materialForRendering, 0);
     canvasRenderer.SetTexture(mainTexture);
 }

You can see in the UpdateMaterial When Graphic Meeting SetMaterial and SetTexture, stay DoMeshGeneration Meeting SetMesh.
Through the above process ,Graphic will mainTexture It's on the screen .

原网站

版权声明
本文为[OldMan_ sjc]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140625030198.html