UGUI学習手記-graphic


ソースコードについて


ソースコードについては、このブログを参照してダウンロードまたはデバッグできます.

Graphic


概要

  • は、UIBehaviour(UIまたはUnityEngineからのイベントの受信を担当するUnityEditorコンポーネントのすべてのベースクラス)
  • から継承する.
  • は、ICanvasElement(Canvasで再レンダリングされたイベントを受信)
  • を継承する.
  • UGUIのコアコンポーネントは、画像
  • の表示を担当する.
  • 抽象クラス
  • MaskableGraphicはこのクラスから継承され、MaskableGraphicはマスク可能な画像(RawImageImageTextのベースクラス)のベースクラスである.
  • は、MaskableGraphicおよびそのサブクラスに共通の継承可能な方法
  • を提供する.

    とくせい

    [DisallowMultipleComponent]  
    [RequireComponent(typeof(CanvasRenderer))]  
    [RequireComponent(typeof(RectTransform))]  
    [ExecuteInEditMode]  
    DisallowMultipleComponent:1つのオブジェクトに同じコンポーネントが2つあることは許されません.すなわち、マスク可能な画像が2つあることはできません.(eg.ImageまたはRawImageおよびText).RequireComponent:CanvasRenderer(キャンバスレンダラー)とRectTransform(長方形変換)の2つのコンポーネントに依存します.ExecuteInEditMode:編集モードで実行します.

    UIBehaviourのトリガポイントを利用したロジック

  • OnEnable:親オブジェクトのCacheCanvasコンポーネントをCanvasメソッドで取得します.GraphicRegistryに登録されている(Canvasのレンダリング管理センターと見なすことができ、指定されたCanvasに含まれるGraphicなどの情報を取得することができる).s_WhiteTextureを変更します(対応するプロパティMainTexture).最後のSetAllDirty(LayoutVerticesMaterialDirtyに設定されている).
  • OnDisable:GraphicRegistryCanvasUpdateRegistryの2つの管理センターからログアウトし、CanvasRendererをクリーンアップし、完了したらLayoutRebuilderにレイアウトの再構築を通知します.
  • OnRectTransformDimensionsChange:RectTransform次元が変更された場合、LayoutVerticesDirtyに設定します.
  • OnBeforeTransformParentChanged:親が変更される前にGraphicRegistryからログアウトし、LayoutRebuilderにレイアウトの再構築を通知します.
  • OnTransformParentChanged:親が変更されると、親のCanvasが再取得され、GraphicRegistryに再登録され、SetAllDirtyが再登録されます.
  • OnDidApplyAnimationProperties:アニメーションのプロパティが適用されると、SetAllDirtyが呼び出されます.
  • OnCanvasHierarchyChanged:キャンバス階層が変更された場合、Canvasが変更された場合、GraphicRegistryに再登録されます.

  • SetAllDirty詳細コード

    SetLayoutDirtyには、LayoutRebuilderレイアウトの再構築が必要であることが通知されます.SetVerticesDirtySetMaterialDirtyにはCanvasUpdateRegistryが登録され、Canvasの再構築を待つとGraphicが再構築されます.いずれも対応するイベント(コールバック)をブロードキャストし、RegisterDirtyLayoutCallbackなどの方法でイベントリスニングを追加することができる.
    public virtual void SetAllDirty()  
    {  
       SetLayoutDirty();  
       SetVerticesDirty();  
       SetMaterialDirty();  
    }    
    public virtual void SetLayoutDirty()  
    {  
       if (!IsActive())  
           return;  
    
       LayoutRebuilder.MarkLayoutForRebuild(rectTransform);  
    
       if (m_OnDirtyLayoutCallback != null)  
           m_OnDirtyLayoutCallback();  
    }  
    
    public virtual void SetVerticesDirty()  
    {  
       if (!IsActive())  
           return;  
    
       m_VertsDirty = true;  
       CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);  
    
       if (m_OnDirtyVertsCallback != null)  
           m_OnDirtyVertsCallback();  
    }  
    
    public virtual void SetMaterialDirty()  
    {  
       if (!IsActive())  
           return;  
    
       m_MaterialDirty = true;  
       CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);  
    
       if (m_OnDirtyMaterialCallback != null)  
           m_OnDirtyMaterialCallback();  
    }  

    レンダリングイベントの処理ロジック

  • Rebuild:Canvasがレンダリングされる前に呼び出され、この方法ではUpdateMaterialUpdateGeometryが呼び出され、マテリアルと頂点が更新されます.

  • UpdateMaterial:canvasRendererのマテリアルとテクスチャをリセットする
    protected virtual void UpdateMaterial()  
    {  
        if (!IsActive())  
            return;  
        canvasRenderer.materialCount = 1;  
        canvasRenderer.SetMaterial(materialForRendering, 0);  
        canvasRenderer.SetTexture(mainTexture);  
    }  

    materialForndering:Mask(マスク)処理後のマテリアルなど、修正されたマテリアルを取得します.
    public virtual Material materialForRendering  
    {  
       get  
       {  
           var components = ListPool.Get();  
           GetComponents(typeof(IMaterialModifier), components);  
           var currentMat = material;  
           for (var i = 0; i < components.Count; i++)  
               currentMat = (components[i] as IMaterialModifier).GetModifiedMaterial(currentMat);  
           ListPool.Release(components);  
           return currentMat;  
       }  
    }  

    UpdateGeometry:useLegacyMeshGenerationというboolの値に従って、DoLegacyMeshGenerationまたはDoMeshGenerationがそれぞれ呼び出されます.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.Get();  
       GetComponents(typeof(IMeshModifier), components);  
       for (var i = 0; i < components.Count; i++)  
           ((IMeshModifier)components[i]).ModifyMesh(s_VertexHelper);  
       ListPool.Release(components);  
       s_VertexHelper.FillMesh(workerMesh);  
       canvasRenderer.SetMesh(workerMesh);  
    }  
    OnPopulateMesh長方形Meshを描いたふりをして、実際には頂点と三角形の情報をs_VertexHelperに保存しただけです.次に、IMeshModifierのタイプのコンポーネントを取得し(IMeshModifierはインタフェースであり、頂点情報のコンポーネントに基づいてそれを継承する必要があり、例えばShadowは間接的にそれを継承する必要がある)、ModifyMeshのメソッドを呼び出し、Meshの情報を変更する.最後に、s_VertexHelperで修正された情報をworkerMeshに割り当て、workerMeshcanvasRendererに設定する.

    他のコンポーネントとの関係


    CrossFadeColor

  • UGUI学習手記-selectable&ButtonにはSelectable状態が変化するとGraphicを呼び出すCrossFadeColorメソッドがある.

  • CrossFadeColor:ColorTweenは緩和効果を実現するクラスであり、m_ColorTweenRunnerはコンストラクション関数で作成され、TweenRunnerの例であり、ColorTweenのキャリアであり、コモンパスによって動作する.
    private void CrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha, bool useRGB)  
    {  
        if (canvasRenderer == null || (!useRGB && !useAlpha))  
            return;  
    
        Color currentColor = canvasRenderer.GetColor();  
        if (currentColor.Equals(targetColor))  
            return;  
    
        ColorTween.ColorTweenMode mode = (useRGB && useAlpha ?  
                                          ColorTween.ColorTweenMode.All :  
                                          (useRGB ? ColorTween.ColorTweenMode.RGB : ColorTween.ColorTweenMode.Alpha));  
    
        var colorTween = new ColorTween {duration = duration, startColor = canvasRenderer.GetColor(), targetColor = targetColor};  
        colorTween.AddOnChangedCallback(canvasRenderer.SetColor);  
        colorTween.ignoreTimeScale = ignoreTimeScale;  
        colorTween.tweenMode = mode;  
        m_ColorTweenRunner.StartTween(colorTween);  
    }  

    Image

    ICanvasRaycastFilterが継承され、Raycastによって放射線がこのアセンブリで有効であるか否かが判断される.この方法はGraphicRaycasterRaycast法で用いられ(前述のGraphicRegistryGetGraphicsForCanvas法も呼び出された)、放射線に照射されたGraphicをスクリーニングするために用いられる.GraphicRaycasterはBaseRaycasterから継承され、入力モジュールはRaycastによって影響を受けるオブジェクトを取得する.
    詳細はUGUI学習手記-EventSystemを参照