Unityを拡張しよう!#1: .Blendファイルを使いこなそう!
どうも、チョコです。
Unityで「これやりたい!」って思ったとき、機能不足でできないこと多いよね。拡張(エディタースクリプト)を書けばいいんだけど、そもそもアセットで使えるデータが限られているからできない。。。なんて思ったことあるかな。
今回はBlenderファイルをUnityで開いて、普通じゃ手に入れられない情報を抽出してみよう!
**この文書を読むにはUnity、C#、Pythonと英語(?)の前提知識が必要です。
Blenderを背景で開く
Blendファイルを読み取るためには、ユーザーが(当然ながら)Blenderを持っていないとできないので、まずBlenderの居場所を確認する。Windowsの場合は、RegistryEditorのSOFTWAREMicrosoftWindowsCurrentVersionUninstallキーにあります。
**注意:RegistryEditorをいじる時に注意してください。変なものいじったりしまうとOSが動かなくなる場合があります。
このキーの中にはすべてインストールされたプログラムが入っているので、Blenderのキーの存在を確認します。
あった。ではここからBlender.exeの場所を出そう。
<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)。
**以下のコードはエディタースクリプトに入れます。やり方省略
<br /> Process.Start (location, file + " –background");<br />
これでBlenderは背景起動された。コマンドみたいなものが起動されますね。
では、Pythonスクリプトを実行しよう。まずはこのスクリプトを実行してみよう。
<br /> Process.Start (location, file + " –background –python " + Application.dataPath + "/Editor/hoge.py");<br />
そして、エディターフォルダに以下のhoge.pyを入れよう。
<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に使えばいいね。例えば、今のアセットフォルダの位置を渡してみよう。
<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:]でパラメータ行列を取れます。
さて意味のあるものができるようになった。できることはさまざまあるが、例としてシーン内の「メッシュではないオブジェクト」の名前を出力してみよう。自明のコードは省略。
<br /> args = sys.argv[sys.argv.index("–") + 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 != ‘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ファイルができます。
以上、拡張機能でした。なんかやりたいときに使えるとうれしい。
では。