はじめてのBlenderアドオン開発

Last Update: 2023.3.1

Blender 2.8~3.0

はじめてのBlenderアドオン開発

Blender 2.8~3.0

Last Update: 2023.3.1

2-5. ショートカットキーを割り当てる

Blender本体の機能には、ショートカットキーを使って特定の操作を素早く実行できるものがあります。 例えば、[3Dビューポート] スペースのメニュー [オブジェクト] > [トランスフォーム] > [移動] で実行される機能には [G] キーが割り当てられてます。

Blenderの機能と同様、個人で作成したアドオンの機能にもショートカットキーを割り当てることができます。 本節では、2-3節 で紹介したサンプルアドオンを改良し、アドオンの機能にショートカットキーを割り当てる方法を紹介します。

作成するアドオンの仕様

アドオンを作成する

1-5節 を参考にして次のソースコードを入力し、ファイル名を sample_2-5.py として保存してください。

import bpy
from bpy.props import FloatProperty, EnumProperty


bl_info = {
    "name": "サンプル 2-5: オブジェクトを並進移動するアドオン④",
    "author": "ぬっち(Nutti)",
    "version": (3, 0),
    "blender": (2, 80, 0),
    "location": "3Dビューポート > オブジェクト, Ctrl + Alt + R",
    "description": "アクティブなオブジェクトを並進移動するサンプルアドオン(ショートカットあり)",
    "warning": "",
    "support": "TESTING",
    "doc_url": "",
    "tracker_url": "",
    "category": "Object"
}

addon_keymaps = []          # 登録したショートカットキー一覧


# オブジェクトを並進移動するオペレータ
class SAMPLE25_OT_TranslateObject(bpy.types.Operator):

    bl_idname = "object.sample25_translate_object"
    bl_label = "並進移動"
    bl_description = "アクティブなオブジェクトを並進移動します"
    bl_options = {'REGISTER', 'UNDO'}

    axis: EnumProperty(
        name="移動軸",
        description="移動軸を設定します",
        default='X',
        items=[
            ('X', "X軸", "X軸に沿って並進移動します"),
            ('Y', "Y軸", "Y軸に沿って並進移動します"),
            ('Z', "Z軸", "Z軸に沿って並進移動します"),
        ]
    )
    amount: FloatProperty(
        name="移動量",
        description="移動量を設定します",
        default=1.0,
    )

    def execute(self, context):
        active_obj = context.active_object
        if self.axis == 'X':
            active_obj.location[0] += self.amount
        elif self.axis == 'Y':
            active_obj.location[1] += self.amount
        elif self.axis == 'Z':
            active_obj.location[2] += self.amount
        self.report({'INFO'}, "サンプル 2-5: 『{}』を{}軸方向へ {} 並進移動しました。"
                              .format(active_obj.name, self.axis, self.amount))
        print("サンプル 2-5: オペレータ『{}』が実行されました。".format(self.bl_idname))

        return {'FINISHED'}


def menu_fn(self, context):
    self.layout.separator()
    self.layout.operator(SAMPLE25_OT_TranslateObject.bl_idname)


classes = [
    SAMPLE25_OT_TranslateObject,
]


def register_shortcut():
    wm = bpy.context.window_manager
    kc = wm.keyconfigs.addon
    if kc:
        # [3Dビューポート] スペースのショートカットキーとして登録
        km = kc.keymaps.new(name="3D View", space_type='VIEW_3D')
        # ショートカットキーの登録
        kmi = km.keymap_items.new(
            idname=SAMPLE25_OT_TranslateObject.bl_idname,
            type='T',
            value='PRESS',
            shift=False,
            ctrl=True,
            alt=True
        )
        # ショートカットキー一覧に登録
        addon_keymaps.append((km, kmi))


def unregister_shortcut():
    for km, kmi in addon_keymaps:
        # ショートカットキーの登録解除
        km.keymap_items.remove(kmi)
    # ショートカットキー一覧をクリア
    addon_keymaps.clear()


def register():
    for c in classes:
        bpy.utils.register_class(c)
    bpy.types.VIEW3D_MT_object.append(menu_fn)
    register_shortcut()
    print("サンプル 2-5: アドオン『サンプル 2-5』が有効化されました。")


def unregister():
    unregister_shortcut()
    bpy.types.VIEW3D_MT_object.remove(menu_fn)
    for c in classes:
        bpy.utils.unregister_class(c)
    print("サンプル 2-5: アドオン『サンプル 2-5』が無効化されました。")


if __name__ == "__main__":
    register()

アドオンを使用する

アドオンを有効化する

1-5節 を参考に作成したアドオンを有効化すると、コンソールウィンドウに次の文字列が出力されます。

サンプル 2-5: アドオン『サンプル 2-5』が有効化されました。

アドオンの機能を使用する

[3Dビューポート] スペース上でオブジェクトを選択し、[Ctrl] + [Alt] + [T] キーを押すと、[3Dビューポート] スペースのメニュー [オブジェクト] > [並進移動] を実行したときと同じく、アクティブなオブジェクトが並進移動します。

アドオンを無効化する

1-5節 を参考にアドオンを無効化すると、コンソールウィンドウに次の文字列が出力されます。

サンプル 2-5: アドオン『サンプル 2-5』が無効化されました。

ソースコードの解説

ショートカットキーの割り当て

ショートカットキーの割り当ては、register_shortcut 関数で行っています。

def register_shortcut():
    wm = bpy.context.window_manager
    kc = wm.keyconfigs.addon
    if kc:
        # [3Dビューポート] スペースのショートカットキーとして登録
        km = kc.keymaps.new(name="3D View", space_type='VIEW_3D')
        # ショートカットキーの登録
        kmi = km.keymap_items.new(
            idname=SAMPLE25_OT_TranslateObject.bl_idname,
            type='T',
            value='PRESS',
            shift=False,
            ctrl=True,
            alt=True
        )
        # ショートカットキー一覧に登録
        addon_keymaps.append((km, kmi))

bpy.context.window_manager.keyconfigs.addon.keymaps は、アドオンに割り当てられているキーマップです。

keymaps.new メソッドを実行することで、新たにキーマップを割り当てることができます。 本節のサンプルアドオンでは、次に示す引数を keymaps.new メソッドに指定して呼び出し、キーマップを割り当てています。

引数 値の意味
name str キーマップ名
space_type str キーマップを割り当てるスペース名

次に、km.keymap_items.new メソッドを使い、新しく割り当てたキーマップにショートカットキーを登録します。 km.keymap_items.new メソッドに指定する引数を、次に示します。

引数 値の意味
idname str イベント発生時に実行するオペレータの処理を記述した、オペレータクラスの bl_idname
type str イベントを発生させるキーボードのキー
value str イベントを発生させるための条件値
shift bool イベントを発生させるために、[Shift] キーが押されている必要がある場合は True
ctrl bool イベントを発生させるために、[Ctrl] キーが押されている必要がある場合は True
alt bool イベントを発生させるために、[Alt] キーが押されている必要がある場合は True

本節のサンプルアドオンは、[Shift] + [Ctrl] + [T] キーが押されたときにイベントを発生させ、オブジェクトを並進移動するオペレータを実行するように、引数を指定しています。 イベント発生時に、引数 idname に指定した処理を実行しますが、引数 value には、例えば次のようなイベント発生の条件値を指定できます。

イベント値 値の意味
'PRESS' ボタンを押したときに、イベントを発生させる
'RELEASE' ボタンを離したときに、イベントを発生させる
'ANY' ボタンの状態に何かしら変更があったときに、イベントを発生させる
'NOTHING' イベントを発生させない

最後に、割り当てたキーマップとショートカットキーのペアを、グローバル変数 addon_keymaps に保存します。 この変数は、アドオン無効化時に、割り当てたショートカットキーの割り当てを解除するために必要になります。

ショートカットキーの割り当て解除

登録したショートカットキーは、アドオン無効化時に割り当てを解除する必要があります。

ショートカットキーの割り当てを解除する処理は、unregister_shortcut 関数に定義されています。

def unregister_shortcut():
    for km, kmi in addon_keymaps:
        # ショートカットキーの登録解除
        km.keymap_items.remove(kmi)
    # ショートカットキー一覧をクリア
    addon_keymaps.clear()

アドオン有効化時に、グローバル変数 addon_keymaps に保存したキーマップを、keymap_items.remove メソッドの引数に指定して実行することで、ショートカットキーの割り当てを解除できます。

最後に、キーマップとショートカットキーのペアを保存したグローバル変数 addon_keymaps をクリアします。

割り当てるショートカットキー

Blenderでは、すでに多くの機能にショートカットキーが割り当てられているため、ショートカットキーとして何も割り当てられていないキーを、単一のキーの中から探すのは意外と大変です。 このため、[Ctrl] キーや [Shift] キー、[Alt] キーと組み合わせたショートカットキーを割り当てることも検討しましょう。 これらのキーと組み合わせることで、すでに割り当てられているキーと被る可能性を低くでき、より簡単に空いているキーを見つけることができると思います。 本節のサンプルアドオンでも、[Ctrl] キーや [Alt] キーを組み合わせたショートカットキーを登録しています。

割り当てるショートカットキーは、ショートカットキーに割り当てた機能を簡単に推測できるようなものにしましょう。 ショートカットキーを割り当てる機能であるオブジェクトの並進移動は、英訳するとTranslate Objectになるため、本節のサンプルアドオンでは英訳の頭文字を取って [T] キーを割り当てています。

まとめ

2-3節 を改造し、[3Dビューポート] スペースのメニュー [オブジェクト] > [並進移動] にショートカットキーを割り当て、ショートカットキーからオペレータを実行できるようにしました。

ショートカットキーをオペレータに割り当てることで、ユーザがオペレータをより素早く実行できるようになります。 頻繁に使う機能に対してショートカットキーを割り当てることは、アドオンの利便性の改善につながる可能性があります。 一方、ショートカットキーに設定できるキーの組み合わせには限りがあるため、ショートカットキーを乱用してユーザが利用可能なショートカットキーを減らしてしまうのは、よいとは言えません。

アドオンをさまざまな人に使ってもらうことを考えている場合は、ショートカットキーによってユーザの利便性が本当に向上するのかを検討してから設定すべきです。 個人的に利用するアドオンではない限り、試しにショートカットキーを割り当ててみたとか、とりあえず割り当てとけばよいという程度の判断で、ショートカットキーを設定すべきではありません。

ポイント