はじめに
uGUIの操作を制限するため手前に透明なImageを重ねることがあると思いますが、そのままでは1枚分の描画負荷がかかってしまいます。その負荷を軽減する方法を紹介します。
方法
Imageと同じGameObjectについているCanvasRendererのCull Transparent Mesh
をオンにしてください。
SceneビューのOverdrawモードで確認すると、設定したImage部分の描画がされていないことが確認できます。
StatsでもBatchesが増えていないことが確認できます。
ちなみにCanvasRendererのCull Transparent Mesh
で全ての描画がなくなるのは全ての画像領域が完全に透明な場合のみです。アルファ値が0.1でも残っていると描画されてしまう点に注意してください。
おまけ: 最初から描画しないスクリプトを自作する
上記の方法とほぼほぼ同じことができるスクリプトです。途中から意味ないと気がついたのですが、折角なので紹介します。raycastも当たるやつです。
_^先ほどと同様にいくつ置いても描画されない_スクリプト
Gist: NoRenderImage.cs
using UnityEditor;
namespace UnityEngine.UI
{
/// <summary>
/// 描画しない透明Imageコンポーネント
/// </summary>
[AddComponentMenu("UI/NonRenderImage", 2004)]
public class NoRenderImage : Graphic
{
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); }
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(NoRenderImage))]
class NonRenderImageEditor : UnityEditor.Editor
{
public override void OnInspectorGUI() { }
private static Vector2 s_ImageElementSize = new Vector2(100f, 100f);
[MenuItem("GameObject/UI/NoRender Image", false, 2004)]
public static void CreateNoRenderImage()
{
var parent = Selection.activeGameObject?.transform;
if (parent == null || parent.GetComponentInParent<Canvas>() == null)
{
var canvas = new GameObject("Canvas");
canvas.transform.SetParent(parent);
canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
canvas.AddComponent<CanvasScaler>();
canvas.AddComponent<GraphicRaycaster>();
parent = canvas.transform;
}
var go = new GameObject("NoRenderImage");
var rectTransform = go.AddComponent<RectTransform>();
rectTransform.SetParent(parent);
rectTransform.sizeDelta = s_ImageElementSize;
rectTransform.anchoredPosition = Vector2.zero;
Selection.activeGameObject = go;
go.AddComponent<NoRenderImage>();
}
}
#endif
}
}
メインはこの部分だけです。メッシュ描画のコールバック関数であるOnPopulateMesh
をoverrideして、頂点をクリアしています。これで描画だけがされないGraphicコンポーネントが実現できました。
参考: ボタンの当たり判定(タッチ範囲)だけ広げる【Unity】【uGUI】 - (:3[kanのメモ帳]
public class NoRenderImage : Graphic
{
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); }
}
他の部分は便利に使うための記述です。
_^[Add Component]メニューのUIカテゴリから追加できる_ _^Createメニューからも生成できる_ _^Canvas以下でない階層で生成すると、自動的にCanvasを作ってくれる_この辺りは別の記事でまとめておこうと思います。
余談
Text
コンポーネントも描画するテキストがない場合に描画がされないので、それで良い説もありますね。