unityで外部テキストをC#コードとして読み込む

こんにちは。mo-takusanです。

今まではほとんど記事を書いてこなかったのですが、さすがにそろそろ投稿していこうと思います。

unityで外部コードを読み込むには…

最近とある事情でコンパイル後に外部ソースコードを読み込みたい、という場面がありました。

「あああ、Python書くかぁ」

となっていたのですが、念のため調べると、C#はコンパイル言語ですが、ランタイムでコンパイルができるようです。C#神!!やっぱり.NET最強!!!

ただし、untiyとの相性が悪いものが多く、四苦八苦してしたので、紆余曲折の様子を記事にしていきます。

なお、本記事で使用したunityのバージョンは2017.1.1f1です。

まずはできた方法を、、

まあ、とにかく知りたいのは実際にうまくいったやり方でしょう(需要があれば)から、その方法から話していきます。

なんだかんだとググっていくうちに以下のGitHubにたどり着きました。

https://github.com/aeroson/mcs-ICodeCompiler

このサイトを見たとき、ついに来た!最終コミットもそれなりに新しいしこれはいけるやろ!と思ったのですが、ここからが長かった…(unityのバージョンを合わせればよかったとかそういうツッコミはなしでお願いします、、、)

2018-02-07_23h38_41

早速クローンしてサンプルプロジェクトを開いてみると…

2018-02-07_23h42_07

地獄絵図…。unityはICodeCompilerやCompilerResultsが存在していないと主張してくるのですが、

https://msdn.microsoft.com/ja-jp/library/system.codedom.compiler.icodecompiler(v=vs.110).aspx

https://msdn.microsoft.com/ja-jp/library/system.codedom.compiler.compilerresults(v=vs.110).aspx

のように、System.CodeDom.Compiler名前空間には確かに存在しています。実際コードの方でもusingされており問題はなさそうです。やけくそで丁寧に書き直してみても全然ダメ…

2018-02-07_23h45_47

うーーーん。

これについては解決方法が全く分かりませんでした。ので、ダメもとで一緒にクローンしてきた「non Unity3D usage」のコードを新規プロジェクトに入れてみました。dllはPluginsに入れることを忘れずに…

2018-02-08_00h03_29

おや?エラーが出ない!
やった…やったよ、、おれ、ついにやってのけたよ…
そうするとデモが動かなかった理由がいよいよ謎ですね。

それはともかくとして、あとは適切にファイルを読み込むコードを書いて、、、

 private static Assembly Compile(IEnumerable&lt;FileInfo&gt; files)<br />
 {<br />
     var domain = AppDomain.CurrentDomain;<br />
     var references = domain.GetAssemblies().Select(a =&gt; a.Location).ToArray();<br />
     var options = new CompilerParameters<br />
     {<br />
         GenerateExecutable = false,<br />
         GenerateInMemory = true,<br />
     };<br />
     options.ReferencedAssemblies.AddRange(references);<br />
     var compiler = new CodeCompiler();<br />
     var result = compiler.CompileAssemblyFromFileBatch(options, files.Select(f =&gt; f.FullName).ToArray());<br />
     return result.Errors.Count &gt; 0 ? null : result.CompiledAssembly;<br />
 }

完成しました!!!
なお、こちらのプロジェクトは諸事情で公開していないのであしからず。

ここからはできなかったことを書くぞ!

と言いましたが、疲れたので失敗の様子はダイジェストでどうぞ

System.CodeDom.Compilerを素で使う

なぜかコンパイルすると動かない(unityではよくある泣)

AssetStoreからダウンロード

https://assetstore.unity.com/packages/tools/cs-script-for-unity-23510

このページにいい感じのアセットがあったのでダウンロード。が、だめ。(古かった)

Roslynを使う

unityが.NET4.6に対応したことを利用して、次のサイトを参考にして組んでみよう!

https://www.gaprot.jp/pickup/tips/roslyn

unityが反応してくれない!おい!!nugetからdll落としてPluginsに入れてもダメでした。(むしろそれ以外を知りませんが)

Posted on