これまでに Blenderスクリプトを書いたことがあるなら、正しく機能させるのは戦いの半分にすぎず、もう半分は「誰かにそれを使ってもらうこと」だと気づいたはずです。Blenderアドオンを共有し、販売するには、クリーンなユーザーインターフェースが必須です。
このガイドでは、内蔵のレイアウトシステムを使ってBlenderアドオンのユーザーインターフェースを作る方法を学びます。よく使うUIコンポーネントの種類、パネルが表示され得る場所、そして最小限の動作例を順を追って解説します。最後には、アドオンにBlenderネイティブなグラフィカルインターフェースを与える方法が分かるようになります。
このガイドで紹介している例の統合についての完全なソースコードは、私たちのGitHubで確認できます:
🔗 https://github.com/cgwire/blender-ui-addon-script
1. よくあるUIコンポーネント
Blenderでは、ユーザーインターフェースのあらゆる要素に、Pythonライブラリ上の対応物があります。UIは、次のいずれかの型を継承するクラスを作成することで構築します:
bpy.types.Panel- カスタムパネル(最も一般的)bpy.types.Menu- メニューおよびサブメニューbpy.types.Operator- ボタンから実行できるアクションやツール

これらのクラスは、それぞれ draw(self, context) メソッドを実装できます。レイアウトコマンドを使って、どのようなインターフェースにするべきかを説明します。Blenderのレイアウトシステムは、スペース、整列、位置などを自動的に処理します。これは宣言的なUIシステムで、何が表示され、どの順番にすべきかを説明するだけです。
ここでは、よく使うレイアウト要素を紹介します:
基本的な表示要素
- Label - 対話なしのテキストをそのまま表示します。形式:
layout.label(text="こんにちは!") - Separator - 読みやすくするために、項目の間に縦方向のスペースを追加します。形式:
layout.separator()
ボタン、入力、Props(プロパティ)、Operators(オペレーター)
- Operatorボタン - オペレーター(Blenderコマンドとして登録された関数)を呼び出すクリック可能なボタンを作成します。書き出し、複製、カスタムスクリプトの実行のようなアクションに使えます。構文:
layout.operator("myaddon.some_action", text="アクションを実行")
layout.prop() メソッドは、編集可能なBlenderプロパティを表示するために使います。プロパティには、内蔵データ(例: context.object)のほか、自分で定義したカスタムプロパティも含まれます。たとえば layout.prop(context.object, "name") は、オブジェクトの名前の編集用テキストフィールドを表示します。Blenderは、プロパティの型に応じて適切なウィジェット(テキストボックス、スライダー、チェックボックスなど)を自動で選びます:
- チェックボックス(Booleanプロパティ) - トグル式のチェックボックスを表示します。例:
layout.prop(context.object, "hide_viewport") - 数値フィールド/スライダー(FloatまたはInt) - 数値入力を表示し、しばしばスライダー付きです。例:
layout.prop(context.object, "location", index=0, text="X位置") - ドロップダウンメニュー(Enumプロパティ) - EnumPropertyのときにドロップダウンリストを表示します。例:
layout.prop(context.object, "type") - テキスト入力 - 文字列プロパティのためのテキストボックスを表示します。例:
layout.prop(my_settings, "username")
レイアウトを整理する
UIを構造化して理解しやすく保つために、Blenderは行、列、ボックスのようなレイアウトコンテナを提供しています。
パネルには行と列があります。行と列には、プロパティ、オペレーター、ラベルが含まれます。Blenderは、テーマやレイアウトルールに合わせて、パディング、整列、スケーリングを自動的に処理します。
- 行(水平グループ)は、要素を横方向に並べます:
row = layout.row()
row.prop(obj, "location")
row.prop(obj, "rotation_euler")- 列(垂直グループ)は、要素を縦方向に積み重ねます:
col = layout.column()
col.prop(obj, "scale")
col.prop(obj, "dimensions")- ボックス(視覚的グループ)は、セクションのような関連するコントロールを視覚的にまとめるための、枠付きのボックスを描画します:
box = layout.box()
box.label(text="変換設定")
box.prop(obj, "location")
box.prop(obj, "rotation_euler")UIコンポーネントの完全な一覧は、公式Blenderドキュメントの「ユーザーインターフェース」ページを参照してください。
2. UIパネルを配置できる場所
Blenderでカスタムパネルを作成する際、インターフェースのどこに表示され、どの領域を占有するかを、2つの重要なクラス属性で決められます:
bl_space_type- パネルが属するエディター/ワークスペース(例:3Dビュー、プロパティエディター、ノードエディター)。bl_region_type- そのエディターのどの部分にパネルが表示されるか(例:サイドバー、ツールバー、メインウィンドウ)。
カスタムパネルを置く可能性が高い代表的な場所の一覧です:

- 3Dビューのサイドバーは、3Dビューポートの右側にあるNパネルサイドバーに表示されます。モデリング、リギング、シーンツールのための最も一般的な配置場所です:
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'- プロパティエディター内に、オブジェクト、マテリアル、シーンの各タブの間にパネルを追加できます。アドオンがマテリアル、オブジェクト、レンダー設定、シーンプロパティを扱う場合に使います:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'- UV/Imageエディターのサイドバー(テクスチャツールや画像ユーティリティに便利):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'- ノードを扱うツールのための、シェーダー、ジオメトリノード、コンポジターエディターのサイドバー:
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'最適なパネルの配置場所は、ツールの目的によって変わります:
- モデリング/オブジェクトツール → 3Dビューサイドバー(
VIEW_3D+UI) - マテリアルまたはレンダー設定 → プロパティエディター(
PROPERTIES+WINDOW) - テクスチャユーティリティ → 画像エディターサイドバー(
IMAGE_EDITOR+UI) - シェーダー/ジオメトリツール → ノードエディターサイドバー(
NODE_EDITOR+UI)
適切な「スペース」を選ぶと、ユーザーが自然に期待する場所にアドオンが見つかり、UIをBlenderに合わせて一貫させられます。
3. 最小の例:3Dビューサイドバーにカスタムパネル
簡単なプラグインを試してみましょう。ボタンをクリックすると「Hello world」のテキストアラートを表示する、3Dビューサイドバーのカスタムパネルです。
1) bl_info - アドオンメタデータ
まず、Blenderに対して、アドオンをどのように潜在ユーザーへ提示するかを伝えるためのアドオンメタデータを指定します:
bl_info = {
"name": "Simple Addon Example",
"author": "Your Name",
"version": (1, 0),
"blender": (4, 0, 0),
"location": "View3D > Sidebar > Simple Tab",
"description": "A simple example addon that prints a message",
"category": "3D View",
}bl_infoは、Preferences → Add-ons でアドオン情報を表示するためにBlenderが使う、モジュールレベルの辞書です。name:リストに表示される、読みやすい名前author:著者文字列version:アドオンのバージョンを表すタプルblender:このアドオンが対象とする最小のBlenderバージョン(タプル)location:アドオンUIが表示される場所(ユーザーにとって役立つ)description:UIで使われる短い説明category:Add-onsリスト内でのカテゴリのグルーピング
インストール済みアドオンをスキャンするときにBlenderがbl_infoを読み取るので、bl_infoは正確に保つことが重要です。
2) オペレータークラスを定義する
次に、Operatorのサブクラスを定義します。オペレーターは、Blenderでアクションを行うための公式な方法です。UI、ショートカット、検索メニューなどから呼び出せます。
class SIMPLEADDON_OT_hello(bpy.types.Operator): bl_idname = "simple_addon.say_hello" bl_label = "Say Hello" bl_description = "Prints a message to the console"
def execute(self, context): self.report({'INFO'}, "Hello from Blender Addon!") print("Hello from Blender Addon!") return {'FINISHED'}
bl_idname-"module_name.operator_name"という形式の一意な識別子文字列です。すべて小文字で、ドットで区切ります。コードやUIからオペレーターを呼び出す方法です(bpy.ops.simple_addon.say_hello())。bl_label- ボタン/メニューに表示されるユーザー向けラベル。bl_description- UIに表示されるツールチップ/説明。execute(self, context)- オペレーターが実行されるときに呼び出される中核メソッド(同期実行)。contextは、Blenderの現在の状態(アクティブオブジェクト、シーン、エリアなど)にアクセスできるようにします。self.report({'INFO'}, "…")は、Blenderの情報バー/ステータスに小さなメッセージを表示します(ユーザーへのフィードバックに適しています)。print("…")は、システム/Blenderコンソールへ出力します(デバッグに便利です)。{'FINISHED'}や{'CANCELLED'}のような set を返します。Blenderは、この結果を使ってオペレーターが正常に完了したかどうかを判断します。
3) パネルクラス - UIの配置
次に、BlenderにUIを追加するためのPanelのサブクラスに進みます:
class SIMPLEADDON_PT_panel(bpy.types.Panel): bl_label = "Simple Addon Panel" bl_idname = "SIMPLEADDON_PT_panel" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Simple'
def draw(self, context): layout = self.layout layout.operator("simple_addon.say_hello")
bl_label- UIに表示されるパネルのタイトル。bl_idname- 一意なパネル識別子。bl_space_type = 'VIEW_3D'- このパネルが3Dビューポート領域に属することをBlenderに伝えます。bl_region_type = 'UI'- 右側の領域(Nパネル)に配置します。他にも領域があります(例:'TOOLS', 'WINDOW')。bl_category = 'Simple'- サイドバーのタブ名。このパネルは「Simple」というラベルのタブの下に表示されます。draw(self, context)- UIレイアウトを描画するために呼び出されます。self.layoutは、UILayoutオブジェクトで、ボタン、ラベル、プロパティなどを配置するために使います。layout.operator("simple_addon.say_hello")は、クリックするとbl_idname"simple_addon.say_hello"のオペレーターを呼び出すボタンを作成します。ボタンのテキストは、オペレーターのbl_labelから取得されます。
4) 登録/登録解除(register / unregister)関数
Blenderは、UI、オペレーター、パネル、プロパティなどを定義するクラスを登録して、Blenderがそれらについて認識できるようにする必要があります:
def register(): bpy.utils.register_class(SIMPLEADDON_OT_hello) bpy.utils.register_class(SIMPLEADDON_PT_panel)
def unregister(): bpy.utils.unregister_class(SIMPLEADDON_PT_panel) bpy.utils.unregister_class(SIMPLEADDON_OT_hello)
bpy.utils.register_class(Class)はクラスを登録します。unregister_classは削除します。- 特にクラス同士が参照し合う場合は、登録解除は登録の逆順で行うことが重要です。そのため、パネルをオペレーターより先に登録解除します。
- アドオンがPreferencesで有効化されると、Blenderが
register()を呼び出します。無効化されると、unregister()を呼び出します。
完全なコードは Pythonファイル addon.py に配置します:
bl_info = { "name": "Simple Addon Example", "author": "Your Name", "version": (1, 0), "blender": (4, 0, 0), "location": "View3D > Sidebar > Simple Tab", "description": "A simple example addon that prints a message", "category": "3D View", }import bpy
class SIMPLEADDON_OT_hello(bpy.types.Operator): bl_idname = "simple_addon.say_hello" bl_label = "Say Hello" bl_description = "Prints a message to the console"
def execute(self, context): self.report({'INFO'}, "Hello from Blender Addon!") print("Hello from Blender Addon!") return {'FINISHED'}
class SIMPLEADDON_PT_panel(bpy.types.Panel): bl_label = "Simple Addon Panel" bl_idname = "SIMPLEADDON_PT_panel" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Simple'
def draw(self, context): layout = self.layout layout.operator("simple_addon.say_hello")
def register(): bpy.utils.register_class(SIMPLEADDON_OT_hello) bpy.utils.register_class(SIMPLEADDON_PT_panel)
def unregister(): bpy.utils.unregister_class(SIMPLEADDON_PT_panel) bpy.utils.unregister_class(SIMPLEADDON_OT_hello)
4. アドオンの実行とパッケージ化
アドオンのスクリプトを書いたら、それをBlenderに読み込んで、すぐにテストできます。特別なツールは不要です。
- スクリプトを保存する -
my_addon.pyのように分かりやすい名前でPythonファイルを保存します。 - BlenderのAdd-ons Preferencesを開く - Edit → Preferences → Add-onsへ移動します。ここでBlenderは、インストールされた拡張機能をすべて管理します。
- アドオンをインストールする - Preferencesウィンドウ上部の「Install…」ボタンをクリックします。
Select your my_addon.pyファイルを選択して、「Install Add-on」をクリックします。 - 有効化する - インストール後、アドオンはリストに表示されます。「My Add-on」を探し、まだ有効になっていない場合はチェックを入れて有効化します。

- インターフェースで確認する - 3Dビューポートを開き、サイドバーを開いて「Simple」という名前のタブを探します。カスタムパネルがそこにあり、すぐに使えます!

アドオンを他の人と共有したいときは、配布用にGitHub、Blender Artists、Gumroadへアップロードできます。アドオンが何をするのか、どうやってインストールするのかを説明する短いREADME.mdを用意しましょう。
複数ファイルのアドオン(例:別々のモジュール、アイコン、リソースなど)がある場合は、フォルダーを作成して、そのフォルダー全体をZIPにして(my_addon.zip)共有します。Blenderは同じ「Install…」ボタンから直接.zipアーカイブをインストールできるため、事前に展開する必要はありません。メインのエントリポイントはinit.pyという名前である必要があります。BlenderがそれをPythonパッケージとして扱うためです。
結論
BlenderアドオンのためのUIを作るのは、最初は気後れするかもしれません。しかし、自分で作ったツールを共有するための最も簡単な方法の1つです。パネルとレイアウトの仕組みを理解すれば、ユーザーが直感的に使えるボタン、プロパティ、整理されたセクションを素早く追加できます。
GitHub上のコードリポジトリを見て、ぜひこの例を試してみてください。
まずは小さく、シンプルなパネル、ラベル、ボタンを追加してアクションを作り、そこから広げていきましょう!


