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ファイルができます。
以上、拡張機能でした。なんかやりたいときに使えるとうれしい。
では。

