はじめに
以前書いた『描画負荷がかからない透明なuGUI Imageを作る【Unity】』の中で紹介しているNoRenderImage
というコンポーネントをHierarchyのCreate/UI
以下から追加できるようにしたり、AddComponentのUI
以下から追加できるようにしました。
新しく追加するだけなら簡単ですが既存のカテゴリに追加する方法が少しだけややこしかったので、簡単に解説します。
AddComponentの既存カテゴリ階層に追加する
こっちの方が簡単なので先に紹介します。
クラスの先頭に[AddComponentMenu()]
をつけるだけです。既存カテゴリ以下にしたければ/
で区切って指定してください。第二引数は表示順ですが、コンポーネントについているAddComponentメニューの方では反映されなくて、メニューバーのComponentの方のみに適用されます。
[AddComponentMenu("UI/NonRenderImage", 14)]
public class NoRenderImage : Graphic
{
}
例えばRectMask2D
の下に追加したい場合はRectMask2D
の定義を調べます(コードエディタから辿れます)。
namespace UnityEngine.UI
{
[AddComponentMenu("UI/Rect Mask 2D", 13)]
[DisallowMultipleComponent]
[ExecuteAlways]
[RequireComponent(typeof(RectTransform))]
public class RectMask2D : UIBehaviour, IClipper, ICanvasRaycastFilter
{
}
}
13
が指定されていることが確認できるため、14
を指定してその直後に表示させることができました。

ちなみに表示順指定はint
型なので、連番の中に挟む際の細かい表示順は指定できなさそうです。(RawImage
が12
、Mask
とRectMask2D
が13
なので、その間は多分辞書順とかでしか制御できない)
Createの既存カテゴリ階層に追加する
HierarchyのCreate/UI
以下などに追加する方法です。Canvasの扱いについても簡単に紹介します。
こちらはコンポーネント自体の指定ではなく、生成するメソッドが登録されているメニューになります。以下のようなstatic
メソッドを用意し、[MenuItem()]
アトリビュートを追加します。
[MenuItem("GameObject/UI/NoRender Image", false, 2003)]
public static void CreateNoRenderImage()
{
var go = new GameObject("NoRenderImage");
go.AddComponent<NoRenderImage>();
}
^実行するとNoRenderImage
がアタッチされたGameObjectが生成されるメソッド
こちらは第三引数で表示順の指定をします。既存のCreateメソッドはUnityEditor.UI
のinternal
クラス内にありコードエディタからでは辿れないため、Bitbucket上で公開されているリポジトリから確認します。
Unity-Technologies / ui / UnityEditor.UI / UI / MenuOptions.cs — Bitbucket
[MenuItem("GameObject/UI/Raw Image", false, 2002)]
static public void AddRawImage(MenuCommand menuCommand)
{
}
例えばRawImage
は2002
が指定されているため、直後に表示したい場合は2003
などを指定すれば良いです。
また、生成時に他のコンポーネントと同様に選択中のGameObject以下に生成するようにしてみましょう。Canvas以下でなかった場合は生成する処理も書きました。
[MenuItem("GameObject/UI/NoRender Image", false, 2003)]
public static void CreateNoRenderImage()
{
// 選択状態のGameObjectを取得する
var parent = Selection.activeGameObject?.transform;
// 親や祖先にCanvasが存在しない場合
if (parent == null || parent.GetComponentInParent<Canvas>() == null)
{
// 新規Canvasの生成
var canvas = new GameObject("Canvas");
canvas.transform.SetParent(parent);
// Canvasの初期化
canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
canvas.AddComponent<CanvasScaler>();
canvas.AddComponent<GraphicRaycaster>();
// 親の付け替え
parent = canvas.transform;
}
var go = new GameObject("NoRenderImage");
// RectTransformの初期化
var rectTransform = go.AddComponent<RectTransform>();
// 親コンポーネントの指定 (nullの場合はルートになるので問題ない)
rectTransform.SetParent(parent);
rectTransform.sizeDelta = s_ImageElementSize;
rectTransform.anchoredPosition = Vector2.zero;
// 生成したGameObjectを選択状態にする
Selection.activeGameObject = go;
// コンポーネントの追加
go.AddComponent<NoRenderImage>();
}
簡易的ですが、これで他のUIコンポーネントと同様の振る舞いをするようになったと思います。
^生成後のGameObjectが選択状態になる / Canvas下でない場合は生成する
スクリプト全文
Gist: NoRenderImage.cs
using UnityEditor;
namespace UnityEngine.UI
{
/// <summary>
/// 描画しない透明Imageコンポーネント
/// </summary>
[AddComponentMenu("UI/NonRenderImage", 14)]
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, 2003)]
public static void CreateNoRenderImage()
{
// 選択状態のGameObjectを取得する
var parent = Selection.activeGameObject?.transform;
// 親や祖先にCanvasが存在しない場合
if (parent == null || parent.GetComponentInParent<Canvas>() == null)
{
// 新規Canvasの生成
var canvas = new GameObject("Canvas");
canvas.transform.SetParent(parent);
// Canvasの初期化
canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
canvas.AddComponent<CanvasScaler>();
canvas.AddComponent<GraphicRaycaster>();
// 親の付け替え
parent = canvas.transform;
}
var go = new GameObject("NoRenderImage");
// RectTransformの初期化
var rectTransform = go.AddComponent<RectTransform>();
// 親コンポーネントの指定 (nullの場合はルートになるので問題ない)
rectTransform.SetParent(parent);
rectTransform.sizeDelta = s_ImageElementSize;
rectTransform.anchoredPosition = Vector2.zero;
// 生成したGameObjectを選択状態にする
Selection.activeGameObject = go;
// コンポーネントの追加
go.AddComponent<NoRenderImage>();
}
}
# endif
}
}
最後に
CreateやAddComponentに追加する記事はいくつかありましたが、既存のカテゴリ階層に追加する方法は見当たらなかったので簡単にまとめてみました。
もし参考になったら「いいね」やTwitterのフォローよろしくお願いします!
Twitter: @nkjzm
参考
【Unity】AddComponentMenuでスクリプトを整理して表示 │ エクスプラボ
https://ekulabo.com/add-component-menu