ゲーム作りが大好きな人のブログ

ゲームを作るのが大好きな人のブログ。UE4とBlender、MAYA(LT)、3DCoatを使用しています!

【Blender】【Python】bpy.ops.object.mode_set が context is incorrect で失敗する

※2023/07/30 一番最後に補足を追記

BlenderPythonのお話です。
タイトル名が分かりづらいですがハマりやすい問題でしたので残しておきます。

まず bpy.ops.object.mode_set ですがオブジェクトモードや編集モードに移行する際に使用するコマンドです。これが特定条件を満たした際に context is incorrect で必ず失敗します。その条件というのが・・・

bpy.context.view_layer.objects.active == None

という状態。アクティブオブジェクトが空になった状態ですね。
 
 

アクティブオブジェクトってなんですか?

モード変更の際の指標となるオブジェクト・・・と言えばいいのでしょうか。例えばメッシュを持つオブジェクトがアクティブオブジェクトの場合は「編集モード」が選べるのですが、ライトがアクティブオブジェクトの場合は「編集モード」が選べません。他にも機能はありそうですが、とりあえずモード変更の基準となるオブジェクトなのは間違いないです。

そしてアクティブオブジェクトはアウトライナーから確認する事が可能です。名前横のマークがハイライトされてる物がアクティブオブジェクトです。

 
 

アクティブオブジェクトがNoneになるなんて、そんなことあるぅ?

アクティブオブジェクトを何らかの方法で削除すれば、その状態になります。アウトライナーから右クリック → 削除でも簡単にできます。この時、Blenderのモード選択画面は下のようになります。


 
 

ハマりやすいパターン

自分は下のパターンで失敗しておりました。

# オブジェクトモードにする
bpy.ops.object.mode_set(mode = "OBJECT")

# アクティブオブジェクトを設定する
bpy.context.view_layer.objects.active = obj

モード変更前にアクティブオブジェクトがNoneになっている可能性があります。なので

# アクティブオブジェクトを設定する
bpy.context.view_layer.objects.active = obj

# オブジェクトモードにする
bpy.ops.object.mode_set(mode = "OBJECT")

こうしなければいけません。こうすることで安全にモード変更が可能となります。

Blenderの構造が分かっていれば、このようなミスは起きないのですがあまり詳しく解説しているサイトもないので今回はハマりました。
 
 

まとめ

・アクティブオブジェクトの中身によってモード変更の内容が決まる
・アクティブオブジェクトがNoneであれば、どのモードにも移行できない

何かを編集する際はアクティブオブジェクトにさっさと入れ込む事で不具合が減りそうですね。それでは、良きBlenderライフを!


* 2023/07/30補足

  • オブジェクトが非表示状態でもモードは変えられない
  • bpy.context.view_layer.objects.get(obj.name) == Noneもモード変更不可能
    • オブジェクトは存在するけどビューレイヤーには存在しない為