UGUI学習手記-graphic
ソースコードについて
ソースコードについては、このブログを参照してダウンロードまたはデバッグできます.
Graphic
概要
UIBehaviour
(UI
またはUnityEngine
からのイベントの受信を担当するUnityEditor
コンポーネントのすべてのベースクラス)ICanvasElement
(Canvas
で再レンダリングされたイベントを受信)UGUI
のコアコンポーネントは、画像MaskableGraphic
はこのクラスから継承され、MaskableGraphic
はマスク可能な画像(RawImage
、Image
、Text
のベースクラス)のベースクラスである.MaskableGraphic
およびそのサブクラスに共通の継承可能な方法とくせい
[DisallowMultipleComponent]
[RequireComponent(typeof(CanvasRenderer))]
[RequireComponent(typeof(RectTransform))]
[ExecuteInEditMode]
DisallowMultipleComponent
:1つのオブジェクトに同じコンポーネントが2つあることは許されません.すなわち、マスク可能な画像が2つあることはできません.(eg.Image
またはRawImage
およびText
).RequireComponent
:CanvasRenderer
(キャンバスレンダラー)とRectTransform
(長方形変換)の2つのコンポーネントに依存します.ExecuteInEditMode
:編集モードで実行します.UIBehaviourのトリガポイントを利用したロジック
CacheCanvas
コンポーネントをCanvas
メソッドで取得します.GraphicRegistry
に登録されている(Canvas
のレンダリング管理センターと見なすことができ、指定されたCanvas
に含まれるGraphic
などの情報を取得することができる).s_WhiteTexture
を変更します(対応するプロパティMainTexture
).最後のSetAllDirty
(Layout
、Vertices
、Material
がDirty
に設定されている).GraphicRegistry
とCanvasUpdateRegistry
の2つの管理センターからログアウトし、CanvasRenderer
をクリーンアップし、完了したらLayoutRebuilder
にレイアウトの再構築を通知します.RectTransform
次元が変更された場合、Layout
、Vertices
をDirty
に設定します.GraphicRegistry
からログアウトし、LayoutRebuilder
にレイアウトの再構築を通知します.Canvas
が再取得され、GraphicRegistry
に再登録され、SetAllDirty
が再登録されます.SetAllDirty
が呼び出されます.Canvas
が変更された場合、GraphicRegistry
に再登録されます.SetAllDirty詳細コード
SetLayoutDirty
には、LayoutRebuilder
レイアウトの再構築が必要であることが通知されます.SetVerticesDirty
とSetMaterialDirty
には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();
}
レンダリングイベントの処理ロジック
Canvas
がレンダリングされる前に呼び出され、この方法ではUpdateMaterial
、UpdateGeometry
が呼び出され、マテリアルと頂点が更新されます.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
に割り当て、workerMesh
をcanvasRenderer
に設定する.他のコンポーネントとの関係
CrossFadeColor
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
によって放射線がこのアセンブリで有効であるか否かが判断される.この方法はGraphicRaycaster
のRaycast
法で用いられ(前述のGraphicRegistry
のGetGraphicsForCanvas
法も呼び出された)、放射線に照射されたGraphic
をスクリーニングするために用いられる.GraphicRaycasterはBaseRaycaster
から継承され、入力モジュールはRaycast
によって影響を受けるオブジェクトを取得する.詳細はUGUI学習手記-EventSystemを参照