Unityを拡張しよう!#1: .Blendファイルを使いこなそう!
どうも、チョコです。
Unityで「これやりたい!」って思ったとき、機能不足でできないこと多いよね。拡張(エディタースクリプト)を書けばいいんだけど、そもそもアセットで使えるデータが限られているからできない。。。なんて思ったことあるかな。
今回はBlenderファイルをUnityで開いて、普通じゃ手に入れられない情報を抽出してみよう!
**この文書を読むにはUnity、C#、Pythonと英語(?)の前提知識が必要です。
Blenderを背景で開く
Blendファイルを読み取るためには、ユーザーが(当然ながら)Blenderを持っていないとできないので、まずBlenderの居場所を確認する。Windowsの場合は、RegistryEditorのSOFTWAREMicrosoftWindowsCurrentVersionUninstallキーにあります。
**注意:RegistryEditorをいじる時に注意してください。変なものいじったりしまうとOSが動かなくなる場合があります。
このキーの中にはすべてインストールされたプログラムが入っているので、Blenderのキーの存在を確認します。
あった。ではここからBlender.exeの場所を出そう。
1 2 3 4 5 6 7 8 9 10 | <br /> using (RegistryKey key = Registry.LocalMachine.OpenSubKey (registry_key)) {<br /> foreach ( string s in key.GetSubKeyNames()) {<br /> using (RegistryKey key2 = key.OpenSubKey(s)) {<br /> if (( string )key2.GetValue("DisplayName", "") == "Blender")<br /> location = ( string )key2.GetValue("InstallLocation", "") + "Blender.exe";<br /> //なんかする<br /> }<br /> }<br /> }<br /> |
**細かい説明は省略させていただきます。(レポートまだ書いてないorz
BlenderでPythonスクリプトを実行
Blenderは、アッドオンやTextEditorでPythonスクリプトを実行し、シーン内のデータを編集したりできます。これを活かしてみよう。具体的には、Pythonを実行し、Unityのアセットフォルダになんか書き込もう。
まず、「System.Diagnostics.ProcessでBlenderを起動し、Pythonを実行して、自動で閉じる」のを背景でやってもらおう。Blender APIに書いてある通り–backgroundコマンドを送ります。
fileはアセットの中の.Blendのパス(例えば、F:/MyProject/Assets/Hoge.blend)。
**以下のコードはエディタースクリプトに入れます。やり方省略
1 2 | <br /> Process.Start (location, file + " –background");<br /> |
これでBlenderは背景起動された。コマンドみたいなものが起動されますね。
では、Pythonスクリプトを実行しよう。まずはこのスクリプトを実行してみよう。
1 2 | <br /> Process.Start (location, file + " –background –python " + Application.dataPath + "/Editor/hoge.py");<br /> |
そして、エディターフォルダに以下のhoge.pyを入れよう。
1 2 3 4 5 6 7 8 | <br / > import bpy<br / > import sys<br / > class Hoge():<br / > def execute( self ):<br / > print ("hi")< / p> <p> if __name__ = = "__main__":<br / > Hoge().execute()<br / > |
コマンドにhiが表示されたら勝ち。
次に、pythonスクリプトにパラメータを送ろう。 — のつぎに来るものがコマンドとしてパースされないので、pythonに使えばいいね。例えば、今のアセットフォルダの位置を渡してみよう。
1 2 | <br /> Process.Start (location, file + " –background –python " + Application.dataPath + "/Editor/ExportSS.py" + " — " + new DirectoryInfo(file).Parent.FullName);<br /> |
**Python側では、sys.argv[sys.argv.index(“–“) + 1:]でパラメータ行列を取れます。
さて意味のあるものができるようになった。できることはさまざまあるが、例としてシーン内の「メッシュではないオブジェクト」の名前を出力してみよう。自明のコードは省略。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <br / > args = sys.argv[sys.argv.index("& #8211;") + 1:] #パラメータを取る<br /> scene = bpy.context.scene<br / > obj = bpy.context.active_object<br / > dir = args[ 0 ]<br / > name = args[ 1 ]< / p> <p> def execute( self ):<br / > if os.access( self .path, os.W_OK) is False :<br / > print ("permission denied : " + self . dir )<br / > return False <br / > self .path = os.path.join( self . dir , self .name + ".txt")<br / > print ("writing to: " + self .path)< / p> <p> with open ( self .path, "wb") as file :<br / > for obj in self .scene.objects:<br / > if obj. type ! = & #8216;MESH’:<br /> self .write( file , obj.name + "rn")<br / > sys.exit() #自殺</p> <p> def write ( self , file , _str):<br / > file .write(_str.encode())<br / > |
すると、.Blendファイルと同じ名前の.txtファイルができます。
以上、拡張機能でした。なんかやりたいときに使えるとうれしい。
では。